X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsound.c;h=8371b9b5cd879d02b56fabe8ab4487faa2da3fe3;hb=ae22060f6dbc84e9fe7f4ea6a8d2e29cc9c311dd;hp=5ace5922af201154ff5f96f9f0385a868365072a;hpb=4fb7d637c3bcc3381918636fdd22733ff7bae3ac;p=rocksndiamonds.git diff --git a/src/libgame/sound.c b/src/libgame/sound.c index 5ace5922..8371b9b5 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -116,12 +116,15 @@ static MusicInfo **Music_NoConf = NULL; static int num_music_noconf = 0; static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1]; +static char *currently_playing_music_filename = NULL; + /* ========================================================================= */ /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */ static struct SoundControl mixer[NUM_MIXER_CHANNELS]; static int mixer_active_channels = 0; +static boolean expire_loop_sounds = FALSE; static void ReloadCustomSounds(); static void ReloadCustomMusic(); @@ -150,7 +153,8 @@ static void Mixer_ResetChannelExpiration(int channel) { mixer[channel].playing_starttime = Counter(); - if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel])) + if (expire_loop_sounds && + IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel])) Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME); } @@ -159,7 +163,8 @@ static boolean Mixer_ChannelExpired(int channel) if (!mixer[channel].active) return TRUE; - if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) && + if (expire_loop_sounds && + IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) && DelayReached(&mixer[channel].playing_starttime, SOUND_LOOP_EXPIRATION_TIME)) return TRUE; @@ -216,10 +221,20 @@ static void Mixer_PlayMusicChannel() if (mixer[audio.music_channel].type != MUS_TYPE_WAV) { - /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() -- - this looks like a bug in the SDL_mixer library */ - Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1); + // 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, -1, 100); + +#if defined(PLATFORM_WIN32) + // 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 + // (more details: https://www.artsoft.org/forum/viewtopic.php?f=7&t=2253) + // => workaround: always play MIDI music with maximum volume + if (Mix_GetMusicType(NULL) == MUS_MID) + Mix_VolumeMusic(SOUND_MAX_VOLUME); +#endif } } @@ -239,6 +254,8 @@ static void Mixer_StopMusicChannel() Mixer_StopChannel(audio.music_channel); Mix_HaltMusic(); + + setString(¤tly_playing_music_filename, NULL); } static void Mixer_FadeChannel(int channel) @@ -256,6 +273,18 @@ static void Mixer_FadeMusicChannel() Mixer_FadeChannel(audio.music_channel); Mix_FadeOutMusic(SOUND_FADING_INTERVAL); + +#if defined(PLATFORM_WIN32) + // 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 + // (more details: https://www.artsoft.org/forum/viewtopic.php?f=7&t=2253) + // => workaround: never fade MIDI music to lower volume, but just stop it + if (Mix_GetMusicType(NULL) == MUS_MID) + Mixer_StopMusicChannel(); +#endif + + setString(¤tly_playing_music_filename, NULL); } static void Mixer_UnFadeChannel(int channel) @@ -319,6 +348,9 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) mixer[audio.music_channel] = snd_ctrl; Mixer_PlayMusicChannel(); + setString(¤tly_playing_music_filename, + getBaseNamePtr(snd_info->source_filename)); + return; } @@ -478,6 +510,10 @@ static void HandleSoundRequest(SoundControl snd_ctrl) if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl)) Mixer_StopChannel(i); } + else if (SET_EXPIRE_LOOPS(snd_ctrl)) /* set loop expiration on or off */ + { + expire_loop_sounds = snd_ctrl.active; + } else if (snd_ctrl.active) /* add new sound to mixer */ { Mixer_InsertSound(snd_ctrl); @@ -516,7 +552,7 @@ static void *Load_WAV(char *filename) if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL) { - Error(ERR_WARN, "cannot read sound file '%s'", filename); + Error(ERR_WARN, "cannot read sound file '%s': %s", filename, Mix_GetError()); free(snd_info); return NULL; } @@ -540,7 +576,7 @@ static void *Load_MOD(char *filename) if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL) { - Error(ERR_WARN, "cannot read music file '%s'", filename); + Error(ERR_WARN, "cannot read music file '%s': %s", filename, Mix_GetError()); free(mod_info); return NULL; } @@ -689,6 +725,11 @@ static MusicInfo *getMusicInfoEntryFromMusicID(int pos) return mus_info[list_pos]; } +char *getCurrentlyPlayingMusicFilename() +{ + return currently_playing_music_filename; +} + int getSoundListPropertyMappingSize() { return sound_info->num_property_mapping_entries; @@ -990,6 +1031,21 @@ void StopSoundExt(int nr, int state) HandleSoundRequest(snd_ctrl); } +void ExpireSoundLoops(boolean active) +{ + SoundControl snd_ctrl; + + if (!audio.sound_available) + return; + + clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ + + snd_ctrl.active = active; + snd_ctrl.state = SND_CTRL_EXPIRE_LOOPS; + + HandleSoundRequest(snd_ctrl); +} + static void ReloadCustomSounds() { LoadArtworkConfig(sound_info);