How to set playback speed given a tempo scalar?

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:

  1. Channel::setFrequency(float frequency)
  2. 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.