Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert volume API from integers [0-128] to floats [0-1] #653

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
3.0.0:
* Updated for SDL 3.0
* Volume APIs now operate on floats, rather than integers between 0 and 128
6 changes: 3 additions & 3 deletions examples/playmus.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static void Menu(void)
Mix_HaltMusic();
break;
case 'v': case 'V':
Mix_VolumeMusic(SDL_atoi(buf+1));
Mix_VolumeMusic((float)SDL_atof(buf+1));
break;
}
}
Expand All @@ -112,7 +112,7 @@ static void IntHandler(int sig)

int main(int argc, char *argv[])
{
int audio_volume = MIX_MAX_VOLUME;
float audio_volume = 1.0f;
int looping = 0;
bool interactive = false;
bool use_io = false;
Expand Down Expand Up @@ -151,7 +151,7 @@ int main(int argc, char *argv[])
} else
if ((SDL_strcmp(argv[i], "-v") == 0) && argv[i+1]) {
++i;
audio_volume = SDL_atoi(argv[i]);
audio_volume = (float)SDL_atof(argv[i]);
} else
if (SDL_strcmp(argv[i], "-l") == 0) {
looping = -1;
Expand Down
49 changes: 22 additions & 27 deletions include/SDL3_mixer/SDL_mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ extern SDL_DECLSPEC void SDLCALL Mix_Quit(void);
#define MIX_DEFAULT_FREQUENCY 44100
#define MIX_DEFAULT_FORMAT SDL_AUDIO_S16
#define MIX_DEFAULT_CHANNELS 2
#define MIX_MAX_VOLUME 128 /* Volume of a chunk */

/**
* The internal format for an audio chunk
Expand All @@ -197,7 +196,7 @@ typedef struct Mix_Chunk {
int allocated;
Uint8 *abuf;
Uint32 alen;
Uint8 volume; /* Per-sample volume, 0-128 */
float volume; /* Per-sample volume */
} Mix_Chunk;

/**
Expand Down Expand Up @@ -1808,9 +1807,8 @@ extern SDL_DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *c
/**
* Set the volume for a specific channel.
*
* The volume must be between 0 (silence) and MIX_MAX_VOLUME (full volume).
* Note that MIX_MAX_VOLUME is 128. Values greater than MIX_MAX_VOLUME are
* clamped to MIX_MAX_VOLUME.
* The volume must be between 0 (silence) and 1 (full volume).
* Values greater than 1 are clamped to 1.
*
* Specifying a negative volume will not change the current volume; as such,
* this can be used to query the current volume without making changes, as
Expand All @@ -1820,18 +1818,18 @@ extern SDL_DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *c
* channels, and returns _the average_ of all channels' volumes prior to this
* call.
*
* The default volume for a channel is MIX_MAX_VOLUME (no attenuation).
* The default volume for a channel is 1 (no attenuation).
*
* \param channel the channel on set/query the volume on, or -1 for all
* channels.
* \param volume the new volume, between 0 and MIX_MAX_VOLUME, or -1 to query.
* \param volume the new volume, between 0 and 1, or -1 to query.
* \returns the previous volume. If the specified volume is -1, this returns
* the current volume. If `channel` is -1, this returns the average
* of all channels.
*
* \since This function is available since SDL_mixer 3.0.0.
*/
extern SDL_DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
extern SDL_DECLSPEC float SDLCALL Mix_Volume(int channel, float volume);

/**
* Set the volume for a specific chunk.
Expand All @@ -1842,55 +1840,53 @@ extern SDL_DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
* volume for all instances of a sound in addition to specific instances of
* that sound.
*
* The volume must be between 0 (silence) and MIX_MAX_VOLUME (full volume).
* Note that MIX_MAX_VOLUME is 128. Values greater than MIX_MAX_VOLUME are
* clamped to MIX_MAX_VOLUME.
* The volume must be between 0 (silence) and 1 (full volume).
* Values greater than 1 are clamped to 1.
*
* Specifying a negative volume will not change the current volume; as such,
* this can be used to query the current volume without making changes, as
* this function returns the previous (in this case, still-current) value.
*
* The default volume for a chunk is MIX_MAX_VOLUME (no attenuation).
* The default volume for a chunk is 1 (no attenuation).
*
* \param chunk the chunk whose volume to adjust.
* \param volume the new volume, between 0 and MIX_MAX_VOLUME, or -1 to query.
* \param volume the new volume, between 0 and 1, or -1 to query.
* \returns the previous volume. If the specified volume is -1, this returns
* the current volume. If `chunk` is NULL, this returns -1.
*
* \since This function is available since SDL_mixer 3.0.0.
*/
extern SDL_DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
extern SDL_DECLSPEC float SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, float volume);

/**
* Set the volume for the music channel.
*
* The volume must be between 0 (silence) and MIX_MAX_VOLUME (full volume).
* Note that MIX_MAX_VOLUME is 128. Values greater than MIX_MAX_VOLUME are
* clamped to MIX_MAX_VOLUME.
* The volume must be between 0 (silence) and 1 (full volume).
* Values greater than 1 are clamped to 1.
*
* Specifying a negative volume will not change the current volume; as such,
* this can be used to query the current volume without making changes, as
* this function returns the previous (in this case, still-current) value.
*
* The default volume for music is MIX_MAX_VOLUME (no attenuation).
* The default volume for music is 1 (no attenuation).
*
* \param volume the new volume, between 0 and MIX_MAX_VOLUME, or -1 to query.
* \param volume the new volume, between 0 and 1, or -1 to query.
* \returns the previous volume. If the specified volume is -1, this returns
* the current volume.
*
* \since This function is available since SDL_mixer 3.0.0.
*/
extern SDL_DECLSPEC int SDLCALL Mix_VolumeMusic(int volume);
extern SDL_DECLSPEC float SDLCALL Mix_VolumeMusic(float volume);

/**
* Query the current volume value for a music object.
*
* \param music the music object to query.
* \returns the music's current volume, between 0 and MIX_MAX_VOLUME (128).
* \returns the music's current volume, between 0 and 1.
*
* \since This function is available since SDL_mixer 3.0.0.
*/
extern SDL_DECLSPEC int SDLCALL Mix_GetMusicVolume(Mix_Music *music);
extern SDL_DECLSPEC float SDLCALL Mix_GetMusicVolume(Mix_Music *music);

/**
* Set the master volume for all channels.
Expand All @@ -1899,9 +1895,8 @@ extern SDL_DECLSPEC int SDLCALL Mix_GetMusicVolume(Mix_Music *music);
* volume, and considers all three when mixing audio. This function sets the
* master volume, which is applied to all playing channels when mixing.
*
* The volume must be between 0 (silence) and MIX_MAX_VOLUME (full volume).
* Note that MIX_MAX_VOLUME is 128. Values greater than MIX_MAX_VOLUME are
* clamped to MIX_MAX_VOLUME.
* The volume must be between 0 (silence) and 1 (full volume).
* Values greater than 1 are clamped to 1.
*
* Specifying a negative volume will not change the current volume; as such,
* this can be used to query the current volume without making changes, as
Expand All @@ -1910,13 +1905,13 @@ extern SDL_DECLSPEC int SDLCALL Mix_GetMusicVolume(Mix_Music *music);
* Note that the master volume does not affect any playing music; it is only
* applied when mixing chunks. Use Mix_VolumeMusic() for that.\
*
* \param volume the new volume, between 0 and MIX_MAX_VOLUME, or -1 to query.
* \param volume the new volume, between 0 and 1, or -1 to query.
* \returns the previous volume. If the specified volume is -1, this returns
* the current volume.
*
* \since This function is available since SDL_mixer 3.0.0.
*/
extern SDL_DECLSPEC int SDLCALL Mix_MasterVolume(int volume);
extern SDL_DECLSPEC float SDLCALL Mix_MasterVolume(float volume);

/**
* Halt playing of a particular channel.
Expand Down
8 changes: 4 additions & 4 deletions src/codecs/music_drflac.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ typedef struct {
drflac *dec;
int play_count;
bool closeio;
int volume;
float volume;
int status;
int sample_rate;
int channels;
Expand Down Expand Up @@ -167,7 +167,7 @@ static void *DRFLAC_CreateFromIO(SDL_IOStream *src, bool closeio)
if (!music) {
return NULL;
}
music->volume = MIX_MAX_VOLUME;
music->volume = 1.0f;

if (MP3_IOinit(&music->file, src) < 0) {
SDL_free(music);
Expand Down Expand Up @@ -215,13 +215,13 @@ static void *DRFLAC_CreateFromIO(SDL_IOStream *src, bool closeio)
return music;
}

static void DRFLAC_SetVolume(void *context, int volume)
static void DRFLAC_SetVolume(void *context, float volume)
{
DRFLAC_Music *music = (DRFLAC_Music *)context;
music->volume = volume;
}

static int DRFLAC_GetVolume(void *context)
static float DRFLAC_GetVolume(void *context)
{
DRFLAC_Music *music = (DRFLAC_Music *)context;
return music->volume;
Expand Down
8 changes: 4 additions & 4 deletions src/codecs/music_flac.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static void FLAC_Unload(void)


typedef struct {
int volume;
float volume;
int play_count;
FLAC__StreamDecoder *flac_decoder;
unsigned sample_rate;
Expand Down Expand Up @@ -533,7 +533,7 @@ static void *FLAC_CreateFromIO(SDL_IOStream *src, bool closeio)
return NULL;
}
music->src = src;
music->volume = MIX_MAX_VOLUME;
music->volume = 1.0f;

music->flac_decoder = flac.FLAC__stream_decoder_new();
if (music->flac_decoder) {
Expand Down Expand Up @@ -609,14 +609,14 @@ static const char* FLAC_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)


/* Set the volume for an FLAC stream */
static void FLAC_SetVolume(void *context, int volume)
static void FLAC_SetVolume(void *context, float volume)
{
FLAC_Music *music = (FLAC_Music *)context;
music->volume = volume;
}

/* Get the volume for an FLAC stream */
static int FLAC_GetVolume(void *context)
static float FLAC_GetVolume(void *context)
{
FLAC_Music *music = (FLAC_Music *)context;
return music->volume;
Expand Down
12 changes: 6 additions & 6 deletions src/codecs/music_fluidsynth.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ typedef struct {
SDL_AudioStream *stream;
void *buffer;
int buffer_size;
int volume;
float volume;
bool is_paused;
} FLUIDSYNTH_Music;

Expand Down Expand Up @@ -187,7 +187,7 @@ static FLUIDSYNTH_Music *FLUIDSYNTH_LoadMusic(void *data)
return NULL;
}

music->volume = MIX_MAX_VOLUME;
music->volume = 1.0f;
music->buffer_size = 4096/*music_spec.samples*/ * sizeof(Sint16) * channels;
music->synth_write = fluidsynth.fluid_synth_write_s16;
if (music_spec.format & 0x0020) { /* 32 bit. */
Expand Down Expand Up @@ -259,15 +259,15 @@ static void *FLUIDSYNTH_CreateFromIO(SDL_IOStream *src, bool closeio)
return music;
}

static void FLUIDSYNTH_SetVolume(void *context, int volume)
static void FLUIDSYNTH_SetVolume(void *context, float volume)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
/* FluidSynth's default gain is 0.2. Make 1.0 the maximum gain value to avoid sound overload. */
music->volume = volume;
fluidsynth.fluid_synth_set_gain(music->synth, volume * 1.0f / MIX_MAX_VOLUME);
fluidsynth.fluid_synth_set_gain(music->synth, volume);
}

static int FLUIDSYNTH_GetVolume(void *context)
static float FLUIDSYNTH_GetVolume(void *context)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
return music->volume;
Expand Down Expand Up @@ -321,7 +321,7 @@ static int FLUIDSYNTH_GetSome(void *context, void *data, int bytes, bool *done)
}
static int FLUIDSYNTH_GetAudio(void *context, void *data, int bytes)
{
return music_pcm_getaudio(context, data, bytes, MIX_MAX_VOLUME, FLUIDSYNTH_GetSome);
return music_pcm_getaudio(context, data, bytes, 1.0f, FLUIDSYNTH_GetSome);
}

static void FLUIDSYNTH_Stop(void *context)
Expand Down
16 changes: 7 additions & 9 deletions src/codecs/music_gme.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ typedef struct
int track_length;
int intro_length;
int loop_length;
int volume;
float volume;
double tempo;
double gain;
SDL_AudioStream *stream;
Expand All @@ -138,19 +138,17 @@ typedef struct
static void GME_Delete(void *context);

/* Set the volume for a GME stream */
static void GME_SetVolume(void *music_p, int volume)
static void GME_SetVolume(void *music_p, float volume)
{
GME_Music *music = (GME_Music*)music_p;
double v = SDL_floor(((double)volume * music->gain) + 0.5);
music->volume = (int)v;
music->volume = volume;
}

/* Get the volume for a GME stream */
static int GME_GetVolume(void *music_p)
static float GME_GetVolume(void *music_p)
{
GME_Music *music = (GME_Music*)music_p;
double v = SDL_floor(((double)(music->volume) / music->gain) + 0.5);
return (int)v;
return music->volume;
}

static int initialize_from_track_info(GME_Music *music, int track)
Expand Down Expand Up @@ -265,7 +263,7 @@ static void *GME_CreateFromIO(struct SDL_IOStream *src, bool closeio)

gme.gme_set_tempo(music->game_emu, music->tempo);

music->volume = MIX_MAX_VOLUME;
music->volume = 1.0f;

meta_tags_init(&music->tags);
if (initialize_from_track_info(music, 0) < 0) {
Expand Down Expand Up @@ -328,7 +326,7 @@ static int GME_GetSome(void *context, void *data, int bytes, bool *done)
static int GME_PlayAudio(void *music_p, void *data, int bytes)
{
GME_Music *music = (GME_Music*)music_p;
return music_pcm_getaudio(music_p, data, bytes, music->volume, GME_GetSome);
return music_pcm_getaudio(music_p, data, bytes, (float)(music->volume * music->gain), GME_GetSome);
}

/* Close the given Game Music Emulators stream */
Expand Down
8 changes: 4 additions & 4 deletions src/codecs/music_minimp3.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ typedef struct {
int closeio;
mp3dec_ex_t dec;
mp3dec_io_t io;
int volume;
float volume;
int status;
SDL_AudioStream *stream;
mp3d_sample_t *buffer;
Expand Down Expand Up @@ -72,7 +72,7 @@ static void *MINIMP3_CreateFromIO(SDL_IOStream *src, bool closeio)
if (!music) {
return NULL;
}
music->volume = MIX_MAX_VOLUME;
music->volume = 1.0f;

if (MP3_IOinit(&music->file, src) < 0) {
SDL_free(music);
Expand Down Expand Up @@ -125,13 +125,13 @@ static void *MINIMP3_CreateFromIO(SDL_IOStream *src, bool closeio)
return music;
}

static void MINIMP3_SetVolume(void *context, int volume)
static void MINIMP3_SetVolume(void *context, float volume)
{
MiniMP3_Music *music = (MiniMP3_Music *)context;
music->volume = volume;
}

static int MINIMP3_GetVolume(void *context)
static float MINIMP3_GetVolume(void *context)
{
MiniMP3_Music *music = (MiniMP3_Music *)context;
return music->volume;
Expand Down
Loading