Pitch detection and frequencies found

Hi,

I have made a pitch detection program with dsp and the GetParameterFloat command, detecting the frequency every 100th millisecond. I am however puzzled by the frequencies I get as output. I made a sound file playing a plain, single C note from a keyboard, which I belive should have the frequency of 2093.0096 hz. However, I don’t understand why the frequencies from my program varies so much. The frequenciy of the note below C, B, is 1975.53, and the one above, C#, is 2217.46, and as I can see from the ouput, some of the frequencies are more than half a note higher or lower than the C note. I therefore hope someone could give a comment why this is so.

Here’s the output:

2020.356567
1990.973511
2074.719971
2372.341553
1989.259766
2520.695068
2055.541748
2041.533203
2183.365967
1936.559082
2266.481934
2026.778931
1995.836182
1942.678589
1983.223755
2100.231689
2025.617798
1929.928833
1941.497437
2019.644043
2097.964600
1977.790894
1972.209961
1905.834839
2028.224243

Thanks in advance.

Sincerely

Try changing your window to a triangle window if you are using a pure tone. You use different windows for different types of sounds.

Also try reducing or enlarging the FFT window size.
It wont just give 1 solid value the whole time, but it should be pretty close, but from the numbers you give above they probably average out to about 2093. You should keep a running average to smooth the values out.

Try changing your window to a triangle window if you are using a pure tone. You use different windows for different types of sounds.

Also try reducing or enlarging the FFT window size.
It wont just give 1 solid value the whole time, but it should be pretty close, but from the numbers you give above they probably average out to about 2093. You should keep a running average to smooth the values out.

Ok, thank you, but you have to explain how I change the window to a triangle and change the FFT window size. I only understand that I have to place “FMOD_DSP_FFT_WINDOW_TRIANGLE” somehwere.

Hi, you should use the documentation. http://www.fmod.org/documentation/#content/generated/FMOD_DSP_FFT_WINDOW.html has a link to http://www.fmod.org/documentation/#content/generated/FMOD_DSP_FFT.html which shows DSP::setParameterInt can be used to set FMOD_DSP_FFT_WINDOWTYPE and FMOD_DSP_FFT_WINDOWSIZE

Ok, so I did like this:

result =  FMOD_DSP_SetParameterInt(mydsp, FMOD_DSP_FFT_WINDOW_TRIANGLE, 0);

result =  FMOD_DSP_SetParameterInt(mydsp, FMOD_DSP_FFT_WINDOWSIZE, 4096);

Hope that’s correct. 4096 seems to be what gives the most stable results. However, I am still puzzled about the output. In my program I print the average of 200 measurements made with 10 milliseconds intervals. Like this:

while(going){

     if (_kbhit()) going = 0;
 
     result = FMOD_System_Update(system);

 result = FMOD_DSP_GetParameterFloat(mydsp, FMOD_DSP_FFT_DOMINANT_FREQ, &frq, 0, 0);	 
 
    ++counter;
 totalfrq += frq;

 if(counter==200){
	 frq = totalfrq / 200;
	 printf("Detected frequency : %f\n", frq );
	 fwprintf(output, L"%f\n", frq);  
	 totalfrq = 0;
	 counter = 0;
 }

 Sleep(10);

 FMOD_System_Update(system);

 }

When I play the C note on a keyboard I get the following results:

2325.231934
2327.076660
2367.127441
2270.046631
2366.404785
2244.767090
2289.176025
2223.448242
2175.976318
2196.502686
2197.390625
2081.131348
2138.204590
2078.389404
2172.810059
2355.056641
2375.444580
2331.669189
2342.987549
2340.032715
2299.864258
2326.206299
2169.465820
2227.807617
2145.235107
2152.538818
2052.996338
2091.300781
1967.640747
2352.203857
2387.549805

Not only do the measurements vary a lot, but neither do I find that they correspond to any frequency of the equal temperament C, whatever octave.

I also run the same program with another sound file that is a harmonica playing the C in the same octave as the previous fil. Then I get this result:

3605.675537
3513.960693
3250.236572
3313.126221
3546.079346
3470.497559
3336.862305
3249.795898
3380.970703
3562.777100
3384.564697
3287.515625
3304.250977
3580.893799
3417.386475
3285.365723
3314.378662
3418.399658
3504.573975
3322.640381
3226.164063
3310.930908
3575.778320
3412.447266
3246.031494
3311.082520
3484.239258
3454.739746
3316.436279

This output also varies a lot, while it also doesn’t correspond with the previous sound file. And in addition I have difficulty with finding how it correspond with the frequency of equal temperament C.

Sincerely

It should be FMOD_DSP_SetParameterInt(mydsp, FMOD_DSP_FFT_WINDOW_TYPE, FMOD_DSP_FFT_WINDOW_TRIANGLE);

I tried this, but it gave syntax error.

Please look at the documentation or the header, you could have solved that one yourself in seconds. The code above that Nick gave has an extra underscore, it should be WINDOWTYPE

Ok, so I changed the code to this:

result = FMOD_System_CreateDSPByType(system, FMOD_DSP_TYPE_FFT, &mydsp);

result = FMOD_ChannelGroup_AddDSP(channelgroup, FMOD_CHANNELCONTROL_DSP_TAIL, mydsp);
ERRCHECK(result);

result = FMOD_DSP_SetParameterInt(mydsp, FMOD_DSP_FFT_WINDOWTYPE,  FMOD_DSP_FFT_WINDOW_TRIANGLE);
ERRCHECK(result);

result =  FMOD_DSP_SetParameterInt(mydsp, FMOD_DSP_FFT_WINDOWSIZE, 8192);
ERRCHECK(result);

Then I also changed the code to print the average of 800 measurements made with 10 milliseconds intervals. But I still can’t make any sense of the result. First of all, the measurments also now varies a lot, while I also can’t find the relationship to the actual frequency of equal temperament C - and it doesn’t help using other window sizes. The note of C has the frequency of 523.2524, but however I divide or multiply this number to lower or higher octaves, I don’t make it fit with the output from the program.

1891.583252
1830.896118
1762.204834
1737.798096
1886.142700
1806.150024
1749.045044
1786.455200
1870.773438
1793.697388
1726.604492
1831.142944
1850.975098
1783.625732
1691.478394
1896.159180
1830.121216
1760.763184
1740.061523
1884.362183
1806.524658
1746.637939
1788.418945
1869.995117
1793.126465
1725.528442
1832.563110

Sincerely

is it a looping sound that doesnt loop properly and has high frequency clicks in it because of that?

I added this code very quickly using a 440hz sine wav that loops properly.

first

result = gSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &dspfft);
result = channelGroupMaster->addDSP(0, dspfft);

then in my loop

if (dspfft)
{
    float val;
    dspfft->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_TRIANGLE);
    dspfft->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 4096);
    dspfft->getParameterFloat(FMOD_DSP_FFT_DOMINANT_FREQ, &val, 0, 0);
    printf("dom freq = %d\n", (int)(val + 0.5f));   // round to nearest
}

Here is the output

dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440
dom freq = 440

1 Like

I understand that there are certain factors that will influence the result, like the clicking sound when the looop transition is not smooth, or the quality of the sound. The last sound I used was from a harmonica lasting about 25 seconds before it is looped with a fade out and a fade in. The outputs is the average of 400 measurements with 10 milliseconds invertals:

2563.455078
2419.706055
2428.343994
2497.666992
2371.210205
2398.550049
2604.717773
2406.706787
2441.078369
2492.871826
2380.274414
2378.002686
2618.081299
2401.799561
2449.688965
2483.237061
2401.814697
2339.447754
2630.663086
2399.175049
2471.438477
2469.524658
2413.720947
2318.586426
2622.350342

The outputs that are above 2600 is after the loop transition has occured, and can therefore be taken out. The list seems to be more even than the previous ones, but still some variance, while I still find it somewhat difficult to make it correspond to equal temperament C, which I guess in this case should be 2616.262. However, there might be a possibility that a harmonica gets slightly out of tune over time.

I also tried a very pure electronic C sound file, which I believe is in the same octave as the sound from the harmonica above. The output was as follow:

261.628571
261.531738
261.522705
261.527924
261.523285
261.533844
261.521820
261.535950
261.520844
261.536224

It is fairly even, while the frequency measures have about one tenth of the value of the harmonica sound file, which I also find puzzling.

Sincerely

if the sound is not pure, you use different window types, and it is just an RMS value, you have to use the raw spectrum data in the array if you want to scan for harmonics and the like yourself. The value is generally fine but you’re talking about noisy signals that have all sorts of different harmonics in them.