Pitch detection and dsp

I want to work with the pitch detection program that’s in Fmod’s example folder. However, the example is with the spectrum command which is obsolete in Fmod5. In the manual it is written that one should use dsp instead, but it seems to be more complicated, and I find it difficult to understand how to convert the pitch detection example program using dsp. Also, I am programming in C, and one of the commands needed is only for C++. I therefore wonder what the advantages actually are for using the dsp instead of the spectrum command, or if I just as well should run the example program with Fmodex.

Thanks in advance.

None of the commands in FMOD are C++ only, they all have C equivalents. Compare fmod.h vs fmod.hpp

The FMOD5 DSP method is probably easier, as all you have to do is

  1. create the FFT dsp
  2. use addDSP to add it to a channel or bus (channelgroup).
  3. use DSP::getParameter with FMOD_DSP_FFT_DOMINANT_FREQ …

… and it just tells you which is the dominant frequency with a single floating point value, you dont need to calculate it yourself.

1 Like

Thank you for your answer. I have tried to make the dsp solution work, but I must have misunderstood something, as it crashes on the GetParameterFloat command. It would be great if you could take a look at it. Here is what I did:

FMOD_DSP *mydsp;
FMOD_CHANNELGROUP *channelgroup;
int index = 0;
int *numparams = 0;
char *valuestring = “0”;
int valuelength=0;
int going = 1;
float *frq = 0;

result = FMOD_System_RecordStart(system, recorddriver, sound, TRUE);
ERRCHECK(result);
Sleep(200);
result = FMOD_System_PlaySound(system, sound, NULL, 0, &channel);
ERRCHECK(result);
result = FMOD_Channel_SetVolume(channel, 0);
ERRCHECK(result);
result = FMOD_System_GetMasterChannelGroup(system, &channelgroup);
result = FMOD_System_CreateDSPByType(system, FMOD_DSP_TYPE_FFT, &mydsp);
result = FMOD_ChannelGroup_AddDSP(channelgroup, FMOD_CHANNELCONTROL_DSP_TAIL, mydsp);
ERRCHECK(result);

while(going){
if (_kbhit()) going = 0;

result = FMOD_DSP_GetParameterFloat(mydsp, *numparams, frq, valuestring, valuelength);

ERRCHECK(result);

printf(“Detected frequency : %f”, frq );

Sleep(200);

FMOD_System_Update(system);

}

Thanks in advance.

int *numparams = 0; followed by *numparams.
You are dereferencing a null pointer, so it is crashing on your own code not FMOD.
You seem to not have grasped what a pointer is yet, I would stop where you are and learn about this first. You can’t just use null pointers an pass memory to fmod that consists of 1 or bytes (ie the “0”) when it should be much more than that.

You also don’t reference the thing that you’re wanting to query, which I said you should use, which is FMOD_DSP_FFT_DOMINANT_FREQ, so it should be FMOD_DSP_GetParameterFloat(mydsp, FMOD_DSP_FFT_DOMINANT_FREQ, &frq, 0, 0); but you still have to realize that you should be using real values not pointers.

Thank you very much. Now it seems to work. However, I don’t understand what exactly is being measured. Is it the pitch of the moment of the measuring, or is it an average pitch for a certain time span, and how can I possibly measure the average pitch for different time spans?

Sincerely

the frequency returned is the frequency at the time of calling, you could keep a history yourself from calling it regularly if you wanted to build up an average over time.

Ok. I understand. Thank you for your support.

Sincerely