12 #include <fc_config.h>
36 #define MAX_NUM_PLUGINS 2
37 #define SNDSPEC_SUFFIX ".soundspec"
38 #define MUSICSPEC_SUFFIX ".musicspec"
40 #define SOUNDSPEC_CAPSTR "+Freeciv-3.0-soundset"
41 #define MUSICSPEC_CAPSTR "+Freeciv-2.6-musicset"
63 bool repeat,
int exclude,
bool keepstyle);
72 if (plugin_list->isEmpty()) {
88 *sound_list = std::move(*list);
100 *music_list = std::move(*list);
147 qFatal(
_(
"Plugin '%s' isn't available. Available are %s"),
148 qUtf8Printable(
name),
154 qCritical(
"Plugin %s found, but can't be initialized.",
155 qUtf8Printable(
name));
160 qDebug(
"Plugin '%s' is now selected",
193 QString audioset_default =
194 music ? QStringLiteral(
"stdmusic") : QStringLiteral(
"stdsounds");
197 QString fname = QStringLiteral(
"%1%2").arg(audioset_name, suffix);
200 if (!dname.isEmpty()) {
204 if (audioset_name == audioset_default) {
209 qCritical(
"Couldn't find audioset \"%s\", trying \"%s\".",
210 qUtf8Printable(audioset_name), qUtf8Printable(audioset_default));
219 const QString *filename,
220 const QString *our_cap,
221 const QString *opt_path)
223 const char *file_capstr;
226 if (
nullptr == file_capstr) {
227 qFatal(
"Audio spec-file \"%s\" doesn't have capability string.",
228 qUtf8Printable(*filename));
232 qFatal(
"Audio spec-file appears incompatible:");
233 qFatal(
" file: \"%s\"", qUtf8Printable(*filename));
234 qFatal(
" file options: %s", file_capstr);
235 qFatal(
" supported options: %s", qUtf8Printable(*our_cap));
239 qFatal(
"Audio spec-file claims required option(s) "
240 "which we don't support:");
241 qFatal(
" file: \"%s\"", qUtf8Printable(*filename));
242 qFatal(
" file options: %s", file_capstr);
243 qFatal(
" supported options: %s", qUtf8Printable(*our_cap));
254 const QString &musicset_name,
255 const QString &preferred_plugin_name)
262 if (preferred_plugin_name == QLatin1String(
"none")) {
264 qDebug(
"Proceeding with sound support disabled.");
271 qInfo(
_(
"No real audio plugin present."));
272 qInfo(
_(
"Proceeding with sound support disabled."));
273 qInfo(
_(
"For sound support, install SDL2_mixer"));
274 qInfo(
"http://www.libsdl.org/projects/SDL_mixer/index.html");
279 if (soundset_name.isEmpty()) {
280 qFatal(
"No sound spec-file given!");
283 if (musicset_name.isEmpty()) {
284 qFatal(
"No music spec-file given!");
287 qDebug(
"Initializing sound using %s and %s...",
288 qUtf8Printable(soundset_name), qUtf8Printable(musicset_name));
291 if (ss_filename.isEmpty() || ms_filename.isEmpty()) {
292 qCritical(
"Cannot find audio spec-file \"%s\" or \"%s\"",
293 qUtf8Printable(soundset_name), qUtf8Printable(musicset_name));
294 qInfo(
_(
"To get sound you need to download a sound set!"));
295 qInfo(
_(
"Get sound sets from the Modpack Installer "
296 "(freeciv21-modpack-qt) program."));
297 qInfo(
_(
"Proceeding with sound support disabled."));
304 qFatal(
_(
"Could not load sound spec-file '%s':\n%s"),
310 qFatal(
_(
"Could not load music spec-file '%s':\n%s"),
314 QString t0 = QStringLiteral(
"soundspec.options");
317 QString t1 = QStringLiteral(
"musicspec.options");
322 if (!preferred_plugin_name.isEmpty()) {
324 qInfo(
_(
"Proceeding with sound support disabled."));
330 QString audio_str = QStringLiteral(
"sdl");
335 qInfo(
_(
"No real audio subsystem managed to initialize!"));
336 qInfo(
_(
"Perhaps there is some misconfiguration or bad permissions."));
337 qInfo(
_(
"Proceeding with sound support disabled."));
344 const QString &musicset_name)
371 bool usage_enabled =
true;
392 bool repeat,
int exclude,
bool keepstyle)
399 if (tag.isEmpty() || (tag == QLatin1String(
"-"))) {
408 std::vector<QString> files;
409 for (
int i = 0; i < std::numeric_limits<int>::max(); i++) {
413 if (ftmp ==
nullptr) {
418 files.push_back(ftmp);
421 if (files.size() > 1 && exclude >= 0) {
425 ret =
fc_rand(files.size() - 1);
427 if (ret == exclude) {
430 ret = files.size() - 1;
440 soundfile = files.at(ret);
456 if (soundfile.isEmpty()) {
457 qDebug(
"No sound file for tag %s", qUtf8Printable(tag));
460 if (fullpath.isEmpty()) {
461 qCritical(
"Cannot find audio file %s for tag %s",
462 qUtf8Printable(soundfile), qUtf8Printable(tag));
496 const QString pretty_alt_tag =
497 alt_tag.isEmpty() ? QStringLiteral(
"(null)") : alt_tag;
502 log_debug(
"audio_play_sound('%s', '%s')", qUtf8Printable(tag),
503 qUtf8Printable(pretty_alt_tag));
508 qDebug(
"Neither of tags %s or %s found", qUtf8Printable(tag),
509 qUtf8Printable(pretty_alt_tag));
521 QString pretty_alt_tag = alt_tag.isEmpty() ? (
"(null)") : alt_tag;
525 log_debug(
"audio_play_music('%s', '%s')", qUtf8Printable(tag),
526 qUtf8Printable(pretty_alt_tag));
535 qDebug(
"Neither of tags %s or %s found", qUtf8Printable(tag),
536 qUtf8Printable(pretty_alt_tag));
635 buffer = QStringLiteral(
"[");
640 buffer = buffer +
", ";
643 buffer += QLatin1String(
"]");
static int audio_play_music_tag(const QString &tag, bool repeat, bool keepstyle)
Play tag from music set.
void audio_init()
Initialize base audio system.
void audio_play_sound(const QString &tag, const QString &alt_tag)
Play an audio sample as suggested by sound tags.
static struct audio_plugin plugins[MAX_NUM_PLUGINS]
static void music_finished_callback()
Callback to start new track.
static int audio_play_tag(struct section_file *sfile, const QString &tag, bool repeat, int exclude, bool keepstyle)
INTERNAL.
void audio_play_track(const QString &tag, const QString &alt_tag)
Play single track as suggested by sound tags.
static enum music_usage current_usage
static int selected_plugin
void audio_play_music(const QString &tag, const QString &alt_tag, enum music_usage usage)
Loop music as suggested by sound tags.
const QVector< QString > * get_musicset_list(const struct option *poption)
Returns a static string vector of musicsets available on the system.
static struct section_file * ss_tagfile
static bool check_audiofile_capstr(struct section_file *sfile, const QString *filename, const QString *our_cap, const QString *opt_path)
Check capabilities of the audio specfile.
void audio_stop_usage()
Stop looping sound.
static void real_audio_play_music(const QString &tag, const QString &alt_tag, bool keepstyle)
Play music, either in loop or just one track in the middle of the style music.
void audio_set_volume(double volume)
Set sound volume to use.
void audio_stop()
Stop sound.
void audio_real_init(const QString &soundset_name, const QString &musicset_name, const QString &preferred_plugin_name)
Initialize audio system and autoselect a plugin.
void audio_restart(const QString &soundset_name, const QString &musicset_name)
Switch soundset.
void audio_add_plugin(struct audio_plugin *p)
Add a plugin.
const QVector< QString > * get_soundset_list(const struct option *poption)
Returns a static string vector of soundsets available on the system.
static bool let_single_track_play
static bool audio_play_sound_tag(const QString &tag, bool repeat)
Play tag from sound set.
const QVector< QString > * get_soundplugin_list(const struct option *poption)
Returns a static string vector of all sound plugins available on the system.
double audio_get_volume()
Get sound volume currently in use.
static struct section_file * ms_tagfile
static struct mfcb_data mfcb
const QString audio_get_all_plugin_names()
Returns a string which list all available plugins.
bool audio_select_plugin(const QString &name)
Choose plugin.
static int num_plugins_used
static const QString audiospec_fullname(const QString &audioset_name, bool music)
Returns the filename for the given audio set.
static bool switching_usage
void audio_shutdown()
Call this at end of program only.
void(* audio_finished_callback)()
void audio_none_init()
Initialize.
void audio_sdl_init()
Initialize.
bool has_capabilities(const char *us, const char *them)
This routine returns true if all the mandatory capabilities in us appear in them.
QString sound_plugin_name
#define fc_assert_ret(condition)
#define log_debug(message,...)
client_options * gui_options
struct section_file * secfile_load(const QString &filename, bool allow_duplicates)
Create a section file from a file.
const char * secfile_error()
Returns the last error which occurred in a string.
void secfile_destroy(struct section_file *secfile)
Free a section file.
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Lookup a string value in the secfile.
Q_GLOBAL_STATIC(QVector< QString >, future_name_translation)
const QStringList & get_data_dirs()
Returns a list of data directory paths, in the order in which they should be searched.
QString fileinfoname(const QStringList &dirs, const QString &filename)
Returns a filename to access the specified file from a directory by searching all specified directori...
QVector< QString > * fileinfolist(const QStringList &dirs, const char *suffix)
Returns a string vector storing the filenames in the data directories matching the given suffix.
bool(* play)(const QString &tag, const QString &path, bool repeat, audio_finished_callback cb)
void(* set_volume)(double volume)
bool sound_enable_menu_music
bool sound_enable_effects
bool sound_enable_game_music
struct section_file * sfile
The base class for options.