From 7390136a42915bed6ef085a1339da70aefe1f1cc Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Mon, 23 Dec 2019 14:01:02 +0300 Subject: [PATCH] add Mix_GetVolume() call to retrieve the volume of a music The 'Stream' suffix is there to prepare for multi-music functionality which includes a set of new functions equal to old Music functions but unlike them, requiring a music pointer. multi-music: it's an api that should allow to play multiple parallel streams (for example, various environment SFX that is hard to play via existing chunks api due the fact they are loading an entire song into memory). Also the multi-music api should allow a cross-fade of songs and should allow making a dynamical songs - i.e. playing separated tracks of the same song as different streams, and controlling a volume of every stream to mute/unmute certain stream. All multi-music related functions will have 'Stream' suffix. multi-music isn't ready yet on Mixer-X side. --- include/SDL_mixer.h | 4 +++- src/codecs/music_cmd.c | 1 + src/codecs/music_flac.c | 12 ++++++++++-- src/codecs/music_fluidsynth.c | 10 ++++++++++ src/codecs/music_mad.c | 7 +++++++ src/codecs/music_mikmod.c | 8 ++++++++ src/codecs/music_modplug.c | 12 ++++++++++++ src/codecs/music_mpg123.c | 7 +++++++ src/codecs/music_nativemidi.c | 1 + src/codecs/music_ogg.c | 10 +++++++++- src/codecs/music_opus.c | 8 ++++++++ src/codecs/music_timidity.c | 13 ++++++++++++- src/codecs/music_wav.c | 7 +++++++ src/music.c | 15 +++++++++++++++ src/music.h | 3 +++ 15 files changed, 113 insertions(+), 5 deletions(-) diff --git a/include/SDL_mixer.h b/include/SDL_mixer.h index 894160b1..bc3caca2 100644 --- a/include/SDL_mixer.h +++ b/include/SDL_mixer.h @@ -566,6 +566,8 @@ extern DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume); extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume); extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume); +/* Get the current volume value in the range of 0-128 of a music stream */ +extern DECLSPEC int SDLCALL Mix_GetVolumeMusicStream(Mix_Music *music); /* Halt playing of a particular channel */ extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel); @@ -604,7 +606,7 @@ extern DECLSPEC int SDLCALL Mix_PausedMusic(void); /* Set the current position in the music stream. This returns 0 if successful, or -1 if it failed or isn't implemented. This function is only implemented for MOD music formats (set pattern - order number) and for OGG, FLAC, MP3_MAD, MP3_MPG and MODPLUG music + order number) and for WAV, OGG, FLAC, MP3_MAD, MP3_MPG, and MODPLUG music (set position in seconds), at the moment. */ extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position); diff --git a/src/codecs/music_cmd.c b/src/codecs/music_cmd.c index e7eb734e..2b72dda7 100644 --- a/src/codecs/music_cmd.c +++ b/src/codecs/music_cmd.c @@ -275,6 +275,7 @@ Mix_MusicInterface Mix_MusicInterface_CMD = NULL, /* CreateFromRW */ MusicCMD_CreateFromFile, NULL, /* SetVolume */ + NULL, /* GetVolume */ MusicCMD_Play, MusicCMD_IsPlaying, NULL, /* GetAudio */ diff --git a/src/codecs/music_flac.c b/src/codecs/music_flac.c index ccc82a05..763e43c9 100644 --- a/src/codecs/music_flac.c +++ b/src/codecs/music_flac.c @@ -354,7 +354,7 @@ static FLAC__StreamDecoderWriteStatus flac_write_music_cb( music->pcm_pos += (FLAC__int64) frame->header.blocksize; if (music->loop && (music->play_count != 1) && (music->pcm_pos >= music->loop_end)) { - amount -= (music->pcm_pos - music->loop_end) * channels * sizeof(*data); + amount -= (music->pcm_pos - music->loop_end) * channels * (int)sizeof(*data); music->loop_flag = SDL_TRUE; } @@ -589,6 +589,13 @@ static void FLAC_SetVolume(void *context, int volume) music->volume = volume; } +/* Get the volume for an FLAC stream */ +static int FLAC_GetVolume(void *context) +{ + FLAC_Music *music = (FLAC_Music *)context; + return music->volume; +} + /* Start playback of a given FLAC stream */ static int FLAC_Play(void *context, int play_count) { @@ -621,7 +628,7 @@ static int FLAC_GetSome(void *context, void *data, int bytes, SDL_bool *done) if (music->loop_flag) { music->pcm_pos = music->loop_start; - if (flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, music->loop_start) == + if (flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, (FLAC__uint64)music->loop_start) == FLAC__STREAM_DECODER_SEEK_ERROR) { SDL_SetError("FLAC__stream_decoder_seek_absolute() failed"); flac.FLAC__stream_decoder_flush(music->flac_decoder); @@ -718,6 +725,7 @@ Mix_MusicInterface Mix_MusicInterface_FLAC = FLAC_CreateFromRW, NULL, /* CreateFromFile */ FLAC_SetVolume, + FLAC_GetVolume, FLAC_Play, NULL, /* IsPlaying */ FLAC_GetAudio, diff --git a/src/codecs/music_fluidsynth.c b/src/codecs/music_fluidsynth.c index ad4463f4..b6369dba 100644 --- a/src/codecs/music_fluidsynth.c +++ b/src/codecs/music_fluidsynth.c @@ -121,6 +121,7 @@ typedef struct { SDL_AudioStream *stream; void *buffer; int buffer_size; + int volume; } FLUIDSYNTH_Music; @@ -162,6 +163,7 @@ static FLUIDSYNTH_Music *FLUIDSYNTH_LoadMusic(void *data) if ((music = SDL_calloc(1, sizeof(FLUIDSYNTH_Music)))) { Uint8 channels = 2; + music->volume = MIX_MAX_VOLUME; if ((music->stream = SDL_NewAudioStream(AUDIO_S16SYS, channels, music_spec.freq, music_spec.format, music_spec.channels, music_spec.freq))) { music->buffer_size = music_spec.samples * sizeof(Sint16) * channels; if ((music->buffer = SDL_malloc((size_t)music->buffer_size))) { @@ -225,9 +227,16 @@ static void FLUIDSYNTH_SetVolume(void *context, int volume) { FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context; /* FluidSynth's default is 0.2. Make 1.2 the maximum. */ + music->volume = volume; fluidsynth.fluid_synth_set_gain(music->synth, (float) (volume * 1.2 / MIX_MAX_VOLUME)); } +static int FLUIDSYNTH_GetVolume(void *context) +{ + FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context; + return music->volume; +} + static int FLUIDSYNTH_Play(void *context, int play_count) { FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context; @@ -296,6 +305,7 @@ Mix_MusicInterface Mix_MusicInterface_FLUIDSYNTH = FLUIDSYNTH_CreateFromRW, NULL, /* CreateFromFile */ FLUIDSYNTH_SetVolume, + FLUIDSYNTH_GetVolume, FLUIDSYNTH_Play, FLUIDSYNTH_IsPlaying, FLUIDSYNTH_GetAudio, diff --git a/src/codecs/music_mad.c b/src/codecs/music_mad.c index 08a1f173..3da7d30b 100644 --- a/src/codecs/music_mad.c +++ b/src/codecs/music_mad.c @@ -190,6 +190,12 @@ static void MAD_SetVolume(void *context, int volume) music->volume = volume; } +static int MAD_GetVolume(void *context) +{ + MAD_Music *music = (MAD_Music *)context; + return music->volume; +} + /* Starts the playback. */ static int MAD_Play(void *context, int play_count) { @@ -461,6 +467,7 @@ Mix_MusicInterface Mix_MusicInterface_MAD = MAD_CreateFromRW, NULL, /* CreateFromFile */ MAD_SetVolume, + MAD_GetVolume, MAD_Play, NULL, /* IsPlaying */ MAD_GetAudio, diff --git a/src/codecs/music_mikmod.c b/src/codecs/music_mikmod.c index d267dceb..3ac0abf8 100644 --- a/src/codecs/music_mikmod.c +++ b/src/codecs/music_mikmod.c @@ -369,6 +369,13 @@ static void MIKMOD_SetVolume(void *context, int volume) mikmod.Player_SetVolume((SWORD)volume); } +/* Set the volume for a MOD stream */ +static int MIKMOD_GetVolume(void *context) +{ + MIKMOD_Music *music = (MIKMOD_Music *)context; + return music->volume; +} + /* Start playback of a given MOD stream */ static int MIKMOD_Play(void *context, int play_count) { @@ -478,6 +485,7 @@ Mix_MusicInterface Mix_MusicInterface_MIKMOD = MIKMOD_CreateFromRW, NULL, /* CreateFromFile */ MIKMOD_SetVolume, + MIKMOD_GetVolume, MIKMOD_Play, MIKMOD_IsPlaying, MIKMOD_GetAudio, diff --git a/src/codecs/music_modplug.c b/src/codecs/music_modplug.c index 7e1aefe1..fb2d2569 100644 --- a/src/codecs/music_modplug.c +++ b/src/codecs/music_modplug.c @@ -108,6 +108,7 @@ static void MODPLUG_Unload(void) typedef struct { + int volume; int play_count; ModPlugFile *file; SDL_AudioStream *stream; @@ -166,6 +167,8 @@ void *MODPLUG_CreateFromRW(SDL_RWops *src, int freesrc) return NULL; } + music->volume = MIX_MAX_VOLUME; + music->stream = SDL_NewAudioStream((settings.mBits == 8) ? AUDIO_U8 : AUDIO_S16SYS, (Uint8)settings.mChannels, settings.mFrequency, music_spec.format, music_spec.channels, music_spec.freq); if (!music->stream) { @@ -204,9 +207,17 @@ void *MODPLUG_CreateFromRW(SDL_RWops *src, int freesrc) static void MODPLUG_SetVolume(void *context, int volume) { MODPLUG_Music *music = (MODPLUG_Music *)context; + music->volume = volume; modplug.ModPlug_SetMasterVolume(music->file, (unsigned int)volume * 2); /* 0-512, reduced to 0-256 to prevent clipping */ } +/* Get the volume for a modplug stream */ +static int MODPLUG_GetVolume(void *context) +{ + MODPLUG_Music *music = (MODPLUG_Music *)context; + return music->volume; +} + /* Start playback of a given modplug stream */ static int MODPLUG_Play(void *context, int play_count) { @@ -302,6 +313,7 @@ Mix_MusicInterface Mix_MusicInterface_MODPLUG = MODPLUG_CreateFromRW, NULL, /* CreateFromFile */ MODPLUG_SetVolume, + MODPLUG_GetVolume, MODPLUG_Play, NULL, /* IsPlaying */ MODPLUG_GetAudio, diff --git a/src/codecs/music_mpg123.c b/src/codecs/music_mpg123.c index af2bace3..1a0d738b 100644 --- a/src/codecs/music_mpg123.c +++ b/src/codecs/music_mpg123.c @@ -324,6 +324,12 @@ static void MPG123_SetVolume(void *context, int volume) music->volume = volume; } +static int MPG123_GetVolume(void *context) +{ + MPG123_Music *music = (MPG123_Music *)context; + return music->volume; +} + static int MPG123_Play(void *context, int play_count) { MPG123_Music *music = (MPG123_Music *)context; @@ -471,6 +477,7 @@ Mix_MusicInterface Mix_MusicInterface_MPG123 = MPG123_CreateFromRW, NULL, /* CreateFromFile */ MPG123_SetVolume, + MPG123_GetVolume, MPG123_Play, NULL, /* IsPlaying */ MPG123_GetAudio, diff --git a/src/codecs/music_nativemidi.c b/src/codecs/music_nativemidi.c index bdf0da62..562d2db4 100644 --- a/src/codecs/music_nativemidi.c +++ b/src/codecs/music_nativemidi.c @@ -96,6 +96,7 @@ Mix_MusicInterface Mix_MusicInterface_NATIVEMIDI = NATIVEMIDI_CreateFromRW, NULL, /* CreateFromFile */ NATIVEMIDI_SetVolume, + NULL, /* GetVolume */ NATIVEMIDI_Play, NATIVEMIDI_IsPlaying, NULL, /* GetAudio */ diff --git a/src/codecs/music_ogg.c b/src/codecs/music_ogg.c index 58d6eb02..8b11bd13 100644 --- a/src/codecs/music_ogg.c +++ b/src/codecs/music_ogg.c @@ -356,6 +356,13 @@ static void OGG_SetVolume(void *context, int volume) music->volume = volume; } +/* Get the volume for an OGG stream */ +static int OGG_GetVolume(void *context) +{ + OGG_music *music = (OGG_music *)context; + return music->volume; +} + /* Start playback of a given OGG stream */ static int OGG_Play(void *context, int play_count) { @@ -386,7 +393,7 @@ static int OGG_GetSome(void *context, void *data, int bytes, SDL_bool *done) section = music->section; #ifdef OGG_USE_TREMOR - amount = vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, §ion); + amount = (int)vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, §ion); #else amount = (int)vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, 0, 2, 1, §ion); #endif @@ -502,6 +509,7 @@ Mix_MusicInterface Mix_MusicInterface_OGG = OGG_CreateFromRW, NULL, /* CreateFromFile */ OGG_SetVolume, + OGG_GetVolume, OGG_Play, NULL, /* IsPlaying */ OGG_GetAudio, diff --git a/src/codecs/music_opus.c b/src/codecs/music_opus.c index ba379cdc..cd7e8286 100644 --- a/src/codecs/music_opus.c +++ b/src/codecs/music_opus.c @@ -355,6 +355,13 @@ static void OPUS_SetVolume(void *context, int volume) music->volume = volume; } +/* Get the volume for an Opus stream */ +static int OPUS_GetVolume(void *context) +{ + OPUS_music *music = (OPUS_music *)context; + return music->volume; +} + /* Start playback of a given Opus stream */ static int OPUS_Play(void *context, int play_count) { @@ -490,6 +497,7 @@ Mix_MusicInterface Mix_MusicInterface_Opus = OPUS_CreateFromRW, NULL, /* CreateFromFile */ OPUS_SetVolume, + OPUS_GetVolume, OPUS_Play, NULL, /* IsPlaying */ OPUS_GetAudio, diff --git a/src/codecs/music_timidity.c b/src/codecs/music_timidity.c index 8ca5aa62..a3207cd8 100644 --- a/src/codecs/music_timidity.c +++ b/src/codecs/music_timidity.c @@ -35,6 +35,7 @@ typedef struct SDL_AudioStream *stream; void *buffer; Sint32 buffer_size; + int volume; } TIMIDITY_Music; @@ -94,6 +95,8 @@ void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc) return NULL; } + music->volume = MIX_MAX_VOLUME; + SDL_memcpy(&spec, &music_spec, sizeof(spec)); if (spec.channels > 2) { need_stream = SDL_TRUE; @@ -114,7 +117,7 @@ void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc) } music->buffer_size = spec.samples * (SDL_AUDIO_BITSIZE(spec.format) / 8) * spec.channels; - music->buffer = SDL_malloc(music->buffer_size); + music->buffer = SDL_malloc((size_t)music->buffer_size); if (!music->buffer) { SDL_OutOfMemory(); TIMIDITY_Delete(music); @@ -131,9 +134,16 @@ void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc) static void TIMIDITY_SetVolume(void *context, int volume) { TIMIDITY_Music *music = (TIMIDITY_Music *)context; + music->volume = volume; Timidity_SetVolume(music->song, volume); } +static int TIMIDITY_GetVolume(void *context) +{ + TIMIDITY_Music *music = (TIMIDITY_Music *)context; + return music->volume; +} + static int TIMIDITY_Play(void *context, int play_count) { TIMIDITY_Music *music = (TIMIDITY_Music *)context; @@ -241,6 +251,7 @@ Mix_MusicInterface Mix_MusicInterface_TIMIDITY = TIMIDITY_CreateFromRW, NULL, /* CreateFromFile */ TIMIDITY_SetVolume, + TIMIDITY_GetVolume, TIMIDITY_Play, NULL, /* IsPlaying */ TIMIDITY_GetAudio, diff --git a/src/codecs/music_wav.c b/src/codecs/music_wav.c index 79cf3048..c0bc186d 100644 --- a/src/codecs/music_wav.c +++ b/src/codecs/music_wav.c @@ -221,6 +221,12 @@ static void WAV_SetVolume(void *context, int volume) music->volume = volume; } +static int WAV_GetVolume(void *context) +{ + WAV_Music *music = (WAV_Music *)context; + return music->volume; +} + /* Start playback of a given WAV stream */ static int WAV_Play(void *context, int play_count) { @@ -1092,6 +1098,7 @@ Mix_MusicInterface Mix_MusicInterface_WAV = WAV_CreateFromRW, NULL, /* CreateFromFile */ WAV_SetVolume, + WAV_GetVolume, WAV_Play, NULL, /* IsPlaying */ WAV_GetAudio, diff --git a/src/music.c b/src/music.c index cb1a5db9..a795881a 100644 --- a/src/music.c +++ b/src/music.c @@ -860,6 +860,21 @@ int Mix_VolumeMusic(int volume) return(prev_volume); } +int Mix_GetVolumeMusicStream(Mix_Music *music) +{ + int prev_volume; + + if (music && music->interface->GetVolume) + prev_volume = music->interface->GetVolume(music->context); + else if (music_playing && music_playing->interface->GetVolume) { + prev_volume = music_playing->interface->GetVolume(music_playing->context); + } else { + prev_volume = music_volume; + } + + return prev_volume; +} + /* Halt playing of music */ static void music_internal_halt(void) { diff --git a/src/music.h b/src/music.h index 962ca121..21166d09 100644 --- a/src/music.h +++ b/src/music.h @@ -70,6 +70,9 @@ typedef struct /* Set the volume */ void (*SetVolume)(void *music, int volume); + /* Get the volume */ + int (*GetVolume)(void *music); + /* Start playing music from the beginning with an optional loop count */ int (*Play)(void *music, int play_count);