// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// sound.c
// ============================================================================
#define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
#define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
-#define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
-#define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
+#define SAME_SOUND_NR(x, y) ((x).nr == (y).nr)
+#define SAME_SOUND_DATA(x, y) ((x).data_ptr == (y).data_ptr)
-#define SOUND_VOLUME_FROM_PERCENT(v,p) ((p) < 0 ? SOUND_MIN_VOLUME : \
+#define SOUND_VOLUME_FROM_PERCENT(v, p) ((p) < 0 ? SOUND_MIN_VOLUME : \
(p) > 100 ? (v) : \
(p) * (v) / 100)
#define SOUND_VOLUME_LOOPS(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_loops)
#define SOUND_VOLUME_MUSIC(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_music)
-#define SETUP_SOUND_VOLUME(v,s) ((s) & SND_CTRL_MUSIC ? \
+#define SETUP_SOUND_VOLUME(v, s) ((s) & SND_CTRL_MUSIC ? \
SOUND_VOLUME_MUSIC(v) : \
(s) & SND_CTRL_LOOP ? \
SOUND_VOLUME_LOOPS(v) : \
static void FreeSound(void *);
static void FreeMusic(void *);
static void FreeAllMusic_NoConf(void);
+static void Mixer_StopMusicChannel(void);
static SoundInfo *getSoundInfoEntryFromSoundID(int);
static MusicInfo *getMusicInfoEntryFromMusicID(int);
if (expire_loop_sounds &&
IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
- DelayReached(&mixer[channel].playing_starttime,
- SOUND_LOOP_EXPIRATION_TIME))
+ DelayReachedExt2(&mixer[channel].playing_starttime,
+ SOUND_LOOP_EXPIRATION_TIME, Counter()))
return TRUE;
if (!Mix_Playing(channel))
{
int loops = (IS_LOOP(mixer[audio.music_channel]) ? -1 : 1);
+ // stopping music channel before playing next track seems to be needed to
+ // prevent audio problems that may occur when playing MP3 files on Windows
+ Mixer_StopMusicChannel();
+
// use short fade-in to prevent "plop" sound for certain music files
// (this may happen when switching on music while playing the game)
Mix_VolumeMusic(mixer[audio.music_channel].volume);
Mix_FadeInMusic(mixer[audio.music_channel].data_ptr, loops, 100);
-#if defined(PLATFORM_WIN32)
+#if defined(PLATFORM_WINDOWS)
// playing MIDI music is broken since Windows Vista, as it sets the volume
// for MIDI music also for all other sounds and music, which cannot be set
// back to normal unless playing MIDI music again with that desired volume
Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
-#if defined(PLATFORM_WIN32)
+#if defined(PLATFORM_WINDOWS)
// playing MIDI music is broken since Windows Vista, as it sets the volume
// for MIDI music also for all other sounds and music, which cannot be set
// back to normal unless playing MIDI music again with that desired volume
{
if (!mixer[i].active)
{
- Error(ERR_INFO, "Mixer_InsertSound: Channel %d inactive", i);
- Error(ERR_INFO, "Mixer_InsertSound: This should never happen!");
+ Debug("audio", "Mixer_InsertSound: Channel %d inactive", i);
+ Debug("audio", "Mixer_InsertSound: This should never happen!");
mixer_active_channels--;
}
if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
{
- Error(ERR_WARN, "cannot read sound file '%s': %s", filename, Mix_GetError());
+ Warn("cannot read sound file '%s': %s", filename, Mix_GetError());
+
free(snd_info);
+
return NULL;
}
if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
{
- Error(ERR_WARN, "cannot read music file '%s': %s", filename, Mix_GetError());
+ Warn("cannot read music file '%s': %s", filename, Mix_GetError());
+
free(mod_info);
+
return NULL;
}
return NULL;
}
+static int compareMusicInfo(const void *object1, const void *object2)
+{
+ const MusicInfo *mi1 = *((MusicInfo **)object1);
+ const MusicInfo *mi2 = *((MusicInfo **)object2);
+
+ return strcmp(mi1->source_filename, mi2->source_filename);
+}
+
static void LoadCustomMusic_NoConf(void)
{
static boolean draw_init_text = TRUE; // only draw at startup
static char *last_music_directory = NULL;
- char *music_directory = getCustomMusicDirectory();
+ char *music_directory = getCustomMusicDirectory_NoConf();
Directory *dir;
DirectoryEntry *dir_entry;
int num_music = getMusicListSize();
FreeAllMusic_NoConf();
- if ((dir = openDirectory(music_directory)) == NULL)
+ if (music_directory == NULL)
{
- Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+ Warn("cannot find music directory with unconfigured music");
- audio.music_available = FALSE;
+ return;
+ }
+ else if ((dir = openDirectory(music_directory)) == NULL)
+ {
+ Warn("cannot read music directory '%s'", music_directory);
return;
}
if (draw_init_text)
- DrawInitText("Loading music", 120, FC_GREEN);
+ DrawInitTextHead("Loading music");
while ((dir_entry = readDirectory(dir)) != NULL) // loop all entries
{
continue;
if (draw_init_text)
- DrawInitText(basename, 150, FC_YELLOW);
+ DrawInitTextItem(basename);
if (FileIsMusic(dir_entry->filename))
mus_info = Load_WAV_or_MOD(dir_entry->filename);
closeDirectory(dir);
+ // sort music files by filename
+ qsort(Music_NoConf, num_music_noconf, sizeof(MusicInfo *), compareMusicInfo);
+
draw_init_text = FALSE;
}
music_info->num_dynamic_file_list_entries);
}
+int getMusicListSize_NoConf(void)
+{
+ return num_music_noconf;
+}
+
struct FileInfo *getSoundListEntry(int pos)
{
int num_sounds = getSoundListSize();
return mus_info[list_pos];
}
+char *getSoundInfoEntryFilename(int pos)
+{
+ SoundInfo *snd_info = getSoundInfoEntryFromSoundID(pos);
+
+ if (snd_info == NULL)
+ return NULL;
+
+ return getBaseNamePtr(snd_info->source_filename);
+}
+
char *getMusicInfoEntryFilename(int pos)
{
MusicInfo *mus_info = getMusicInfoEntryFromMusicID(pos);
LoadCustomMusic_NoConf();
}
-void InitReloadCustomSounds(char *set_identifier)
+void InitReloadCustomSounds(void)
{
if (!audio.sound_available)
return;
ReloadCustomSounds();
}
-void InitReloadCustomMusic(char *set_identifier)
+void InitReloadCustomMusic(void)
{
if (!audio.music_available)
return;