Tempo control of wav files with pitch correction in FMOD and C++
There aren’t a lot of references for tempo control with pitch correction online for FMOD although it does have the ability to do so. This process is based on 2 functions in FMOD. setFrequency(), which is the tempo control and DSP_PITCHSHIFT, which by varying the pitch parameter, can correct the unintentional pitch change when changing the frequency.
The code gets the deafult frequency for the wav stream, (in most cases 44100Hz), takes a user input for a new tempo, and sets the pitch parameter as a fraction of the default frequency over the user input.
#include "stdafx.h" void errchk(FMOD_RESULT r) { if(r != FMOD_OK) { printf("FMOD_ERROR! (%d) %s\n", r, FMOD_ErrorString(r)); } } int _tmain(int argc, _TCHAR* argv[]) { FMOD::System *system; FMOD::Channel *channel=0; FMOD::Sound *stream1; FMOD::DSP *pitch; unsigned int version; float defreq, spfreq, pit; bool done = false, active = true; FMOD_RESULT result; result = FMOD::System_Create(&system); errchk(result); result = system->getVersion(&version); errchk(result); if(version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. Required: %08x.", version, FMOD_VERSION); return 0; } result = system->init(1, FMOD_INIT_NORMAL, 0); errchk(result); result = system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &pitch); errchk(result); result = system->createStream("C:/trackStreams/Balcony.wav", FMOD_HARDWARE | FMOD_LOOP_NORMAL| FMOD_2D, 0, &stream1); errchk(result); result = system->playSound(FMOD_CHANNEL_FREE, stream1, false, &channel); errchk(result); result = channel->getFrequency(&defreq); errchk(result); printf("\n Default freq is: %.2f\n\n", defreq); result = pitch->setParameter(FMOD_DSP_PITCHSHIFT_FFTSIZE, 4096); errchk(result); result = system->addDSP(pitch,0); errchk(result); result = pitch->setActive(active); errchk(result); while(!done) { printf("\rEnter frequency: "); scanf(" %f", &spfreq); if(spfreq > 0) { result = pitch->remove(); errchk(result); result = channel->setFrequency(spfreq); errchk(result); result = pitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, (defreq/spfreq)); errchk(result); result = system->addDSP(pitch, 0); errchk(result); result = pitch->getParameter(FMOD_DSP_PITCHSHIFT_PITCH, &pit, 0, 0); errchk(result); printf("\nCurrent Pitch: %f\n", pit); } else done = true; } result = stream1->release(); errchk(result); result = system->close(); errchk(result); result = system->release(); errchk(result); return 0; }