add Mix_GetVolume() call to retrieve the volume of a music
authorVitaly Novichkov
Mon, 23 Dec 2019 14:01:02 +0300
changeset 11169835d67a27f9
parent 1115 760a8cb05f97
child 1117 70412138c859
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
src/codecs/music_cmd.c
src/codecs/music_flac.c
src/codecs/music_fluidsynth.c
src/codecs/music_mad.c
src/codecs/music_mikmod.c
src/codecs/music_modplug.c
src/codecs/music_mpg123.c
src/codecs/music_nativemidi.c
src/codecs/music_ogg.c
src/codecs/music_opus.c
src/codecs/music_timidity.c
src/codecs/music_wav.c
src/music.c
src/music.h
     1.1 --- a/include/SDL_mixer.h	Sun Dec 22 17:20:50 2019 +0300
     1.2 +++ b/include/SDL_mixer.h	Mon Dec 23 14:01:02 2019 +0300
     1.3 @@ -566,6 +566,8 @@
     1.4  extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
     1.5  extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
     1.6  extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume);
     1.7 +/* Get the current volume value in the range of 0-128 of a music stream */
     1.8 +extern DECLSPEC int SDLCALL Mix_GetVolumeMusicStream(Mix_Music *music);
     1.9  
    1.10  /* Halt playing of a particular channel */
    1.11  extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel);
    1.12 @@ -604,7 +606,7 @@
    1.13  /* Set the current position in the music stream.
    1.14     This returns 0 if successful, or -1 if it failed or isn't implemented.
    1.15     This function is only implemented for MOD music formats (set pattern
    1.16 -   order number) and for OGG, FLAC, MP3_MAD, MP3_MPG and MODPLUG music
    1.17 +   order number) and for WAV, OGG, FLAC, MP3_MAD, MP3_MPG, and MODPLUG music
    1.18     (set position in seconds), at the moment.
    1.19  */
    1.20  extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
     2.1 --- a/src/codecs/music_cmd.c	Sun Dec 22 17:20:50 2019 +0300
     2.2 +++ b/src/codecs/music_cmd.c	Mon Dec 23 14:01:02 2019 +0300
     2.3 @@ -275,6 +275,7 @@
     2.4      NULL,   /* CreateFromRW */
     2.5      MusicCMD_CreateFromFile,
     2.6      NULL,   /* SetVolume */
     2.7 +    NULL,   /* GetVolume */
     2.8      MusicCMD_Play,
     2.9      MusicCMD_IsPlaying,
    2.10      NULL,   /* GetAudio */
     3.1 --- a/src/codecs/music_flac.c	Sun Dec 22 17:20:50 2019 +0300
     3.2 +++ b/src/codecs/music_flac.c	Mon Dec 23 14:01:02 2019 +0300
     3.3 @@ -354,7 +354,7 @@
     3.4      music->pcm_pos += (FLAC__int64) frame->header.blocksize;
     3.5      if (music->loop && (music->play_count != 1) &&
     3.6          (music->pcm_pos >= music->loop_end)) {
     3.7 -        amount -= (music->pcm_pos - music->loop_end) * channels * sizeof(*data);
     3.8 +        amount -= (music->pcm_pos - music->loop_end) * channels * (int)sizeof(*data);
     3.9          music->loop_flag = SDL_TRUE;
    3.10      }
    3.11  
    3.12 @@ -589,6 +589,13 @@
    3.13      music->volume = volume;
    3.14  }
    3.15  
    3.16 +/* Get the volume for an FLAC stream */
    3.17 +static int FLAC_GetVolume(void *context)
    3.18 +{
    3.19 +    FLAC_Music *music = (FLAC_Music *)context;
    3.20 +    return music->volume;
    3.21 +}
    3.22 +
    3.23  /* Start playback of a given FLAC stream */
    3.24  static int FLAC_Play(void *context, int play_count)
    3.25  {
    3.26 @@ -621,7 +628,7 @@
    3.27  
    3.28      if (music->loop_flag) {
    3.29          music->pcm_pos = music->loop_start;
    3.30 -        if (flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, music->loop_start) ==
    3.31 +        if (flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, (FLAC__uint64)music->loop_start) ==
    3.32                  FLAC__STREAM_DECODER_SEEK_ERROR) {
    3.33              SDL_SetError("FLAC__stream_decoder_seek_absolute() failed");
    3.34              flac.FLAC__stream_decoder_flush(music->flac_decoder);
    3.35 @@ -718,6 +725,7 @@
    3.36      FLAC_CreateFromRW,
    3.37      NULL,   /* CreateFromFile */
    3.38      FLAC_SetVolume,
    3.39 +    FLAC_GetVolume,
    3.40      FLAC_Play,
    3.41      NULL,   /* IsPlaying */
    3.42      FLAC_GetAudio,
     4.1 --- a/src/codecs/music_fluidsynth.c	Sun Dec 22 17:20:50 2019 +0300
     4.2 +++ b/src/codecs/music_fluidsynth.c	Mon Dec 23 14:01:02 2019 +0300
     4.3 @@ -121,6 +121,7 @@
     4.4      SDL_AudioStream *stream;
     4.5      void *buffer;
     4.6      int buffer_size;
     4.7 +    int volume;
     4.8  } FLUIDSYNTH_Music;
     4.9  
    4.10  
    4.11 @@ -162,6 +163,7 @@
    4.12  
    4.13      if ((music = SDL_calloc(1, sizeof(FLUIDSYNTH_Music)))) {
    4.14          Uint8 channels = 2;
    4.15 +        music->volume = MIX_MAX_VOLUME;
    4.16          if ((music->stream = SDL_NewAudioStream(AUDIO_S16SYS, channels, music_spec.freq, music_spec.format, music_spec.channels, music_spec.freq))) {
    4.17              music->buffer_size = music_spec.samples * sizeof(Sint16) * channels;
    4.18              if ((music->buffer = SDL_malloc((size_t)music->buffer_size))) {
    4.19 @@ -225,9 +227,16 @@
    4.20  {
    4.21      FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
    4.22      /* FluidSynth's default is 0.2. Make 1.2 the maximum. */
    4.23 +    music->volume = volume;
    4.24      fluidsynth.fluid_synth_set_gain(music->synth, (float) (volume * 1.2 / MIX_MAX_VOLUME));
    4.25  }
    4.26  
    4.27 +static int FLUIDSYNTH_GetVolume(void *context)
    4.28 +{
    4.29 +    FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
    4.30 +    return music->volume;
    4.31 +}
    4.32 +
    4.33  static int FLUIDSYNTH_Play(void *context, int play_count)
    4.34  {
    4.35      FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
    4.36 @@ -296,6 +305,7 @@
    4.37      FLUIDSYNTH_CreateFromRW,
    4.38      NULL,   /* CreateFromFile */
    4.39      FLUIDSYNTH_SetVolume,
    4.40 +    FLUIDSYNTH_GetVolume,
    4.41      FLUIDSYNTH_Play,
    4.42      FLUIDSYNTH_IsPlaying,
    4.43      FLUIDSYNTH_GetAudio,
     5.1 --- a/src/codecs/music_mad.c	Sun Dec 22 17:20:50 2019 +0300
     5.2 +++ b/src/codecs/music_mad.c	Mon Dec 23 14:01:02 2019 +0300
     5.3 @@ -190,6 +190,12 @@
     5.4      music->volume = volume;
     5.5  }
     5.6  
     5.7 +static int MAD_GetVolume(void *context)
     5.8 +{
     5.9 +    MAD_Music *music = (MAD_Music *)context;
    5.10 +    return music->volume;
    5.11 +}
    5.12 +
    5.13  /* Starts the playback. */
    5.14  static int MAD_Play(void *context, int play_count)
    5.15  {
    5.16 @@ -461,6 +467,7 @@
    5.17      MAD_CreateFromRW,
    5.18      NULL,   /* CreateFromFile */
    5.19      MAD_SetVolume,
    5.20 +    MAD_GetVolume,
    5.21      MAD_Play,
    5.22      NULL,   /* IsPlaying */
    5.23      MAD_GetAudio,
     6.1 --- a/src/codecs/music_mikmod.c	Sun Dec 22 17:20:50 2019 +0300
     6.2 +++ b/src/codecs/music_mikmod.c	Mon Dec 23 14:01:02 2019 +0300
     6.3 @@ -369,6 +369,13 @@
     6.4      mikmod.Player_SetVolume((SWORD)volume);
     6.5  }
     6.6  
     6.7 +/* Set the volume for a MOD stream */
     6.8 +static int MIKMOD_GetVolume(void *context)
     6.9 +{
    6.10 +    MIKMOD_Music *music = (MIKMOD_Music *)context;
    6.11 +    return music->volume;
    6.12 +}
    6.13 +
    6.14  /* Start playback of a given MOD stream */
    6.15  static int MIKMOD_Play(void *context, int play_count)
    6.16  {
    6.17 @@ -478,6 +485,7 @@
    6.18      MIKMOD_CreateFromRW,
    6.19      NULL,   /* CreateFromFile */
    6.20      MIKMOD_SetVolume,
    6.21 +    MIKMOD_GetVolume,
    6.22      MIKMOD_Play,
    6.23      MIKMOD_IsPlaying,
    6.24      MIKMOD_GetAudio,
     7.1 --- a/src/codecs/music_modplug.c	Sun Dec 22 17:20:50 2019 +0300
     7.2 +++ b/src/codecs/music_modplug.c	Mon Dec 23 14:01:02 2019 +0300
     7.3 @@ -108,6 +108,7 @@
     7.4  
     7.5  typedef struct
     7.6  {
     7.7 +    int volume;
     7.8      int play_count;
     7.9      ModPlugFile *file;
    7.10      SDL_AudioStream *stream;
    7.11 @@ -166,6 +167,8 @@
    7.12          return NULL;
    7.13      }
    7.14  
    7.15 +    music->volume = MIX_MAX_VOLUME;
    7.16 +
    7.17      music->stream = SDL_NewAudioStream((settings.mBits == 8) ? AUDIO_U8 : AUDIO_S16SYS, (Uint8)settings.mChannels, settings.mFrequency,
    7.18                                         music_spec.format, music_spec.channels, music_spec.freq);
    7.19      if (!music->stream) {
    7.20 @@ -204,9 +207,17 @@
    7.21  static void MODPLUG_SetVolume(void *context, int volume)
    7.22  {
    7.23      MODPLUG_Music *music = (MODPLUG_Music *)context;
    7.24 +    music->volume = volume;
    7.25      modplug.ModPlug_SetMasterVolume(music->file, (unsigned int)volume * 2); /* 0-512, reduced to 0-256 to prevent clipping */
    7.26  }
    7.27  
    7.28 +/* Get the volume for a modplug stream */
    7.29 +static int MODPLUG_GetVolume(void *context)
    7.30 +{
    7.31 +    MODPLUG_Music *music = (MODPLUG_Music *)context;
    7.32 +    return music->volume;
    7.33 +}
    7.34 +
    7.35  /* Start playback of a given modplug stream */
    7.36  static int MODPLUG_Play(void *context, int play_count)
    7.37  {
    7.38 @@ -302,6 +313,7 @@
    7.39      MODPLUG_CreateFromRW,
    7.40      NULL,   /* CreateFromFile */
    7.41      MODPLUG_SetVolume,
    7.42 +    MODPLUG_GetVolume,
    7.43      MODPLUG_Play,
    7.44      NULL,   /* IsPlaying */
    7.45      MODPLUG_GetAudio,
     8.1 --- a/src/codecs/music_mpg123.c	Sun Dec 22 17:20:50 2019 +0300
     8.2 +++ b/src/codecs/music_mpg123.c	Mon Dec 23 14:01:02 2019 +0300
     8.3 @@ -324,6 +324,12 @@
     8.4      music->volume = volume;
     8.5  }
     8.6  
     8.7 +static int MPG123_GetVolume(void *context)
     8.8 +{
     8.9 +    MPG123_Music *music = (MPG123_Music *)context;
    8.10 +    return music->volume;
    8.11 +}
    8.12 +
    8.13  static int MPG123_Play(void *context, int play_count)
    8.14  {
    8.15      MPG123_Music *music = (MPG123_Music *)context;
    8.16 @@ -471,6 +477,7 @@
    8.17      MPG123_CreateFromRW,
    8.18      NULL,   /* CreateFromFile */
    8.19      MPG123_SetVolume,
    8.20 +    MPG123_GetVolume,
    8.21      MPG123_Play,
    8.22      NULL,   /* IsPlaying */
    8.23      MPG123_GetAudio,
     9.1 --- a/src/codecs/music_nativemidi.c	Sun Dec 22 17:20:50 2019 +0300
     9.2 +++ b/src/codecs/music_nativemidi.c	Mon Dec 23 14:01:02 2019 +0300
     9.3 @@ -96,6 +96,7 @@
     9.4      NATIVEMIDI_CreateFromRW,
     9.5      NULL,   /* CreateFromFile */
     9.6      NATIVEMIDI_SetVolume,
     9.7 +    NULL,   /* GetVolume */
     9.8      NATIVEMIDI_Play,
     9.9      NATIVEMIDI_IsPlaying,
    9.10      NULL,   /* GetAudio */
    10.1 --- a/src/codecs/music_ogg.c	Sun Dec 22 17:20:50 2019 +0300
    10.2 +++ b/src/codecs/music_ogg.c	Mon Dec 23 14:01:02 2019 +0300
    10.3 @@ -356,6 +356,13 @@
    10.4      music->volume = volume;
    10.5  }
    10.6  
    10.7 +/* Get the volume for an OGG stream */
    10.8 +static int OGG_GetVolume(void *context)
    10.9 +{
   10.10 +    OGG_music *music = (OGG_music *)context;
   10.11 +    return music->volume;
   10.12 +}
   10.13 +
   10.14  /* Start playback of a given OGG stream */
   10.15  static int OGG_Play(void *context, int play_count)
   10.16  {
   10.17 @@ -386,7 +393,7 @@
   10.18  
   10.19      section = music->section;
   10.20  #ifdef OGG_USE_TREMOR
   10.21 -    amount = vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, &section);
   10.22 +    amount = (int)vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, &section);
   10.23  #else
   10.24      amount = (int)vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, 0, 2, 1, &section);
   10.25  #endif
   10.26 @@ -502,6 +509,7 @@
   10.27      OGG_CreateFromRW,
   10.28      NULL,   /* CreateFromFile */
   10.29      OGG_SetVolume,
   10.30 +    OGG_GetVolume,
   10.31      OGG_Play,
   10.32      NULL,   /* IsPlaying */
   10.33      OGG_GetAudio,
    11.1 --- a/src/codecs/music_opus.c	Sun Dec 22 17:20:50 2019 +0300
    11.2 +++ b/src/codecs/music_opus.c	Mon Dec 23 14:01:02 2019 +0300
    11.3 @@ -355,6 +355,13 @@
    11.4      music->volume = volume;
    11.5  }
    11.6  
    11.7 +/* Get the volume for an Opus stream */
    11.8 +static int OPUS_GetVolume(void *context)
    11.9 +{
   11.10 +    OPUS_music *music = (OPUS_music *)context;
   11.11 +    return music->volume;
   11.12 +}
   11.13 +
   11.14  /* Start playback of a given Opus stream */
   11.15  static int OPUS_Play(void *context, int play_count)
   11.16  {
   11.17 @@ -490,6 +497,7 @@
   11.18      OPUS_CreateFromRW,
   11.19      NULL,   /* CreateFromFile */
   11.20      OPUS_SetVolume,
   11.21 +    OPUS_GetVolume,
   11.22      OPUS_Play,
   11.23      NULL,   /* IsPlaying */
   11.24      OPUS_GetAudio,
    12.1 --- a/src/codecs/music_timidity.c	Sun Dec 22 17:20:50 2019 +0300
    12.2 +++ b/src/codecs/music_timidity.c	Mon Dec 23 14:01:02 2019 +0300
    12.3 @@ -35,6 +35,7 @@
    12.4      SDL_AudioStream *stream;
    12.5      void *buffer;
    12.6      Sint32 buffer_size;
    12.7 +    int volume;
    12.8  } TIMIDITY_Music;
    12.9  
   12.10  
   12.11 @@ -94,6 +95,8 @@
   12.12          return NULL;
   12.13      }
   12.14  
   12.15 +    music->volume = MIX_MAX_VOLUME;
   12.16 +
   12.17      SDL_memcpy(&spec, &music_spec, sizeof(spec));
   12.18      if (spec.channels > 2) {
   12.19          need_stream = SDL_TRUE;
   12.20 @@ -114,7 +117,7 @@
   12.21          }
   12.22  
   12.23          music->buffer_size = spec.samples * (SDL_AUDIO_BITSIZE(spec.format) / 8) * spec.channels;
   12.24 -        music->buffer = SDL_malloc(music->buffer_size);
   12.25 +        music->buffer = SDL_malloc((size_t)music->buffer_size);
   12.26          if (!music->buffer) {
   12.27              SDL_OutOfMemory();
   12.28              TIMIDITY_Delete(music);
   12.29 @@ -131,9 +134,16 @@
   12.30  static void TIMIDITY_SetVolume(void *context, int volume)
   12.31  {
   12.32      TIMIDITY_Music *music = (TIMIDITY_Music *)context;
   12.33 +    music->volume = volume;
   12.34      Timidity_SetVolume(music->song, volume);
   12.35  }
   12.36  
   12.37 +static int TIMIDITY_GetVolume(void *context)
   12.38 +{
   12.39 +    TIMIDITY_Music *music = (TIMIDITY_Music *)context;
   12.40 +    return music->volume;
   12.41 +}
   12.42 +
   12.43  static int TIMIDITY_Play(void *context, int play_count)
   12.44  {
   12.45      TIMIDITY_Music *music = (TIMIDITY_Music *)context;
   12.46 @@ -241,6 +251,7 @@
   12.47      TIMIDITY_CreateFromRW,
   12.48      NULL,   /* CreateFromFile */
   12.49      TIMIDITY_SetVolume,
   12.50 +    TIMIDITY_GetVolume,
   12.51      TIMIDITY_Play,
   12.52      NULL,   /* IsPlaying */
   12.53      TIMIDITY_GetAudio,
    13.1 --- a/src/codecs/music_wav.c	Sun Dec 22 17:20:50 2019 +0300
    13.2 +++ b/src/codecs/music_wav.c	Mon Dec 23 14:01:02 2019 +0300
    13.3 @@ -221,6 +221,12 @@
    13.4      music->volume = volume;
    13.5  }
    13.6  
    13.7 +static int WAV_GetVolume(void *context)
    13.8 +{
    13.9 +    WAV_Music *music = (WAV_Music *)context;
   13.10 +    return music->volume;
   13.11 +}
   13.12 +
   13.13  /* Start playback of a given WAV stream */
   13.14  static int WAV_Play(void *context, int play_count)
   13.15  {
   13.16 @@ -1092,6 +1098,7 @@
   13.17      WAV_CreateFromRW,
   13.18      NULL,   /* CreateFromFile */
   13.19      WAV_SetVolume,
   13.20 +    WAV_GetVolume,
   13.21      WAV_Play,
   13.22      NULL,   /* IsPlaying */
   13.23      WAV_GetAudio,
    14.1 --- a/src/music.c	Sun Dec 22 17:20:50 2019 +0300
    14.2 +++ b/src/music.c	Mon Dec 23 14:01:02 2019 +0300
    14.3 @@ -860,6 +860,21 @@
    14.4      return(prev_volume);
    14.5  }
    14.6  
    14.7 +int Mix_GetVolumeMusicStream(Mix_Music *music)
    14.8 +{
    14.9 +    int prev_volume;
   14.10 +
   14.11 +    if (music && music->interface->GetVolume)
   14.12 +        prev_volume = music->interface->GetVolume(music->context);
   14.13 +    else if (music_playing && music_playing->interface->GetVolume) {
   14.14 +        prev_volume = music_playing->interface->GetVolume(music_playing->context);
   14.15 +    } else {
   14.16 +        prev_volume = music_volume;
   14.17 +    }
   14.18 +
   14.19 +    return prev_volume;
   14.20 +}
   14.21 +
   14.22  /* Halt playing of music */
   14.23  static void music_internal_halt(void)
   14.24  {
    15.1 --- a/src/music.h	Sun Dec 22 17:20:50 2019 +0300
    15.2 +++ b/src/music.h	Mon Dec 23 14:01:02 2019 +0300
    15.3 @@ -70,6 +70,9 @@
    15.4      /* Set the volume */
    15.5      void (*SetVolume)(void *music, int volume);
    15.6  
    15.7 +    /* Get the volume */
    15.8 +    int (*GetVolume)(void *music);
    15.9 +
   15.10      /* Start playing music from the beginning with an optional loop count */
   15.11      int (*Play)(void *music, int play_count);
   15.12