Hello! For context, I’m using FMOD Core API in my C++ project.
Let’s say I have a .wav file recorded at 60 BPM and depending on the game state, I want the .wav file to play at 75 BPM (1.25x faster) (pitch unaffected). I see a couple of options on how to set the playback speed:
- Channel::setFrequency(float frequency)
- ChannelControl::setPitch(float pitch) (speeds up playback and pitch) + FMOD_DSP_PITCHSHIFT (to pitch the playback back to original)
However, I’m a little confused how the speed scalar I derive (1.25) can map to any of the FMOD parameters. As in, what is the frequency/pitch value when a .wav file is played 1.25x? And of the 2 options listed, which is more performant based on my use case? Any pointers?
Hi,
FMOD has no simple solution for pitch-invariant time stretching, or time-invariant pitch shifting - changing the pitch is the same as playing the playback rate/frequency, and vice versa. As such, Channel::setFrequency
and ChannelControl::setPitch
both essentially do the same thing. The only major difference is that ChannelControl::setPitch
is a higher level control, and when used on a channelgroup will affect all child channels and channelgroups. The only way to work around this is to do as you’ve noted in option 2, and combine a change in frequency with the use of a pitch shift DSP that shifts the pitch inversely proportionate to the change in frequency.
As for mapping your scalar:
-
The pitch
float should be a 1:1 mapping.
-
The frequency
float is proportionate to the default frequency of the sound being played on a given channel. You can get the sound playing on a channel with Channel::getCurrentSound
, and then get the default playback frequency of the sound with Sound::getDefaults
. For example, 1.25x the playback frequency of a 48Khz sound would be 60Khz.