SDL_mixer
SDL_mixer copied to clipboard
Add support for changing channel playback rate.
This bug report was migrated from our old Bugzilla tracker.
Reported in version: unspecified Reported for operating system, platform: All, All
Comments on the original bug report:
On 2017-10-28 20:40:23 +0000, Ivan Epifanov wrote:
Ryan seems to have Mix_PlaybackRate in http://icculus.org/~icculus/tmp/mixer.c Would be nice to have it in official SDL_Mixer too.
Ehh...I wrote that for someone that needed an engine revving up effect in their game, but I don't know if it's really good quality work.
There was a discussion somewhere of having some way to make SDL_AudioStream change it's resampling rate, instead of locking it in at creation time, and that would be useful here, too, though, so let's keep this open for now in any case.
Ehh...I wrote that for someone that needed an engine revving up effect in their game, but I don't know if it's really good quality work.
It's not mathematically correct, but yeah, let's leave this open for future discussion.
Speaking about playback rate switch on the fly, I made a little experiment with the music on my MixerX fork side to see how that thing works: https://github.com/WohlSoft/SDL-Mixer-X/commit/840606fabfd42ba92100f59c8f9f8a02880434ac
It works, but, when I change the rate (flushing and re-creating the stream instance), clicks appear (maybe there is a better way to flush all content of the stream buffer until re-create it?).
Speaking about channels, I highly recommend making the new call with the tempo factor as an argument to ensure it will start with given tempo immediately (especially if you choose the channel by a -1 number).
And, more about channels, there are three new fields that would appear:
- tempo factor;
- computed source rate (the sample rate passed to SDL_AudioStream as a source to trick it);
- and the stream pointer itself.
Maybe I'll try to make some on my side for the experiment to see how the thing works in action...
The demo with music on my MixerX fork side:
https://user-images.githubusercontent.com/6751442/179379309-96072be8-2bd2-4cce-b415-d67c6b601533.mp4
Hi,
I'm porting SDL2 Mixer to our Game engine and seeing the functionality of other ported audio engines, I could provide the following information as a contribution: *** Used in OpenAL/OpenAL Soft *** alSourcef(source_id, AL_PITCH, rate); // rate values = 0.0 to 2.0 (1.0 = default rate)
*** Used in FMOD Ex/FMOD Studio *** FMOD_Sound_SetDefaults(FMOD_SOUND *sound, float frequency, int priority) Sets a sound's default playback attributes.
- frequency Default playback frequency. Units: Hertz Default: 48000
FMOD_RESULT FMOD_Channel_SetFrequency(FMOD_CHANNEL *channel, float frequency) Sets the frequency or playback rate.
- frequency Playback rate. Units: Hertz Default frequency is determined by the audio format of the Sound or DSP.
FMOD_RESULT FMOD_Channel_SetPitch(FMOD_CHANNEL *channel, float pitch) Sets the relative pitch / playback rate.
- pitch Pitch value where 0.5 represents half pitch (one octave down), 1.0 represents unmodified pitch and 2.0 represents double pitch (one octave up).
Changing the rate in both libraries is individual, each sound, music or channel can have its own rate in playing, while maintaining the global one set by default.
Maybe looking at how OpenAL Soft is progressing can help.
So in the time since this originally came up, SDL3's SDL_AudioStream came along and is super powerful for this; it can change both input and output sample rate on the fly, even managing data that is still queued at a different sample rate than new data that is just entering the queue.
More or less, this does exactly what is needed here.
However, while we have moved SDL_mixer to SDL3, we have not made each SDL_mixer channel use its own audiostream, which we would need to do to make this work.
Figuring out the logistics of that would solve this, and probably other problems, too.