Get the Hertz outa here

Started by
6 comments, last by johnboy007 12 years, 8 months ago
I want to be able to get the frequency out of some audio do detect gender. I am using C# and the Unity engine.



void Update ()
{

if(listener.enabled)
{
AudioListener.GetSpectrumData(number, 0,FFTWindow.BlackmanHarris);

for(int i=0; i < numSamples; i++)
{
int newHertz = Mathf.RoundToInt (Mathf.Clamp (number * 2, 0, AudioSettings.outputSampleRate) / (AudioSettings.outputSampleRate / numSamples));

if(newHertz >=100 && newHertz <= 150)
bMan = true;
else if(newHertz >= 170 && newHertz <= 220)
bWoman = true;
else
bGender = false;

if(newHertz > peakData.Hertz)
peakData.Hertz = newHertz;
}
}
}



I thought this would work but it does not, can anyone point me i0n the right direction?
Advertisement


void Update ()
{

if(listener.enabled)

{

AudioListener.GetOutputData(number, 0);

for(int i=0; i < numSamples; i++)

{

int newHertz = Mathf.RoundToInt (Mathf.Clamp (number * 2, 0, AudioSettings.outputSampleRate) / (AudioSettings.outputSampleRate / numSamples));

if(newhertz >=100 && newHertz <= 150)

bMan = true;

else if(newHertz >= 170 && newHertz <= 220)

bWoman = true;

else

bGender = false;

}

}

}




I don't know if it would work and if it did it is not doing what you think it is. It will only store the last time newHertz was checked. I would try it like this:


int newHertz = 0;

for (numsamples with i)
{
//NOTE THE += and not =
newHertz += do calculation
}
newHertz /= numsamples;
if (newHerz ....)
male
else if (newHerz ....
female
else
none

Hi jp,

Extracting frequency info from the raw amplitudes is, I'm afraid, not a trivial problem. You need to do a Fourier analysis (FFT) on the data.

For you though it IS trivial, because you're using Unity -- happy day!

You just need to check out AudioListener.GetSpectrumData(), which gives you an array of amplitudes of different frequency bands.

Ideas for procedurally-generated-from music race games....

HTH.
[size="2"]www.coldcity.com code, art, life

I want to be able to get the frequency out of some audio do detect gender. I am using C# and the Unity engine.


There is no unique frequency you can get out of a audio file/stream. You can try to Fourier transform the input and then analyze the "spectrum".

I don't get at all what you are trying to do in your code? You are trying to calculate the gender inside the loop for every audio sample? The audio samples are an amplitude so to speak. So you can't get a frequency from a single sample. Also the whole upper bound of the clamp "AudioSettings.outputSampleRate) / (AudioSettings.outputSampleRate / numSamples)" is just a fancy way to write "numSamples" + some integer rounding error?

Edit: after the ninja edit it makes more sense. I still don't get why you are clamping the result. Basically what you want to do is search for the max amplitude.


void Update ()
{

if(listener.enabled)
{
AudioListener.GetSpectrumData(number, 0,FFTWindow.BlackmanHarris);

double max = 0;
int maxpos = 0;
for(int i=0; i < numSamples; i++)
{
if(Mathf.Abs(number)>max)
{
max = Mathf.Abs(number);
maxpos = i;
}
}
double frequency = maxpos*AudioSettings.outputSampleRate/numSamples;
//...

}
}

Ah, gotcha now after the edit!

OK, the numbers[] array you're getting back IS the frequency data. Each cell in that array corresponds to the amplitude of the frequencies in that particular bin. A bin in this case is a little sub-band of audio frequencies.

So, assuming each bin is 1Hz wide (is that the case? Not sure..), you could check the value of numbers[170] to get the amplitude of the 170Hz component, and compare that to other components.

For your example use case, you could check all array cells between 100 and 150 and find an average amplitude; then do the same for cells 170 to 220, and compare the two averages amplitudes.

Whether this will actually WORK to discriminate male and female voices is a different matter :cool:
[size="2"]www.coldcity.com code, art, life

[quote name='johnboy007' timestamp='1313423805' post='4849432']
I want to be able to get the frequency out of some audio do detect gender. I am using C# and the Unity engine.


There is no unique frequency you can get out of a audio file/stream. You can try to Fourier transform the input and then analyze the "spectrum".

I don't get at all what you are trying to do in your code? You are trying to calculate the gender inside the loop for every audio sample? The audio samples are an amplitude so to speak. So you can't get a frequency from a single sample. Also the whole upper bound of the clamp "AudioSettings.outputSampleRate) / (AudioSettings.outputSampleRate / numSamples)" is just a fancy way to write "numSamples" + some integer rounding error?

Edit: after the ninja edit it makes more sense. I still don't get why you are clamping the result. Basically what you want to do is search for the max amplitude.


void Update ()
{

if(listener.enabled)
{
AudioListener.GetSpectrumData(number, 0,FFTWindow.BlackmanHarris);

double max = 0;
int maxpos = 0;
for(int i=0; i < numSamples; i++)
{
if(Mathf.Abs(number)>max)
{
max = Mathf.Abs(number);
maxpos = i;
}
}
double frequency = maxpos*AudioSettings.outputSampleRate/numSamples;
//...

}
}


[/quote]
Thank you for your reply:
I have now added this to get my frequency, and i have 2 test wav files, man and woman and the womans is higher but both output value are alot higher than i expected, i like 22500 hertz, going to see if i can find a wav file that outputs just 500 hertz and see if it is calibrated right?
Well, I don't have experience with unity and just assumed the spectrum data would return a fourier transform that's why I put that scaling factor there. What happens when you just write "frequency = maxpos"?

Well, I don't have experience with unity and just assumed the spectrum data would return a fourier transform that's why I put that scaling factor there. What happens when you just write "frequency = maxpos"?



I have downloaded and tested it with a wav file that outputs 500hz

If i do fequency = maxpos with numsample that = 256 the frequency is showing as 5

Then i thought well i really need to up the numsamples to test so i put that to 512 and my freq is 10 not 500? Has anyone got any ideas why?

This topic is closed to new replies.

Advertisement