- Home /
Question by
Digital-Dreams · Nov 27, 2013 at 06:41 PM ·
microphonepitchfrequency
Microphone pitch/dB analysis
I'm looking into analyzing microphone input. For this I want to see what the dB and (voice's) pitch/frequence is. I think I'm getting the dB info properly using GetOutputData(). I know I'm supposed to use GetSpectrumData() for the pitch, but I can't find any examples online on this subject (other than a seemingly broken one http://answers.unity3d.com/questions/275378/simple-lipsync-with-microphone-input.html, why the FreqN index is used, is beyond me).
The question would be: How do I manipulate the float[] data into meaningful Hz information?
This code is work in progress, so it's rambling on several sides, but it's mostly that weird linked thing, which does yield some believable values sometimes.. but why, I don't know:
private void AnalyzeSound()
{
// Get all of our samples from the mic.
audio.GetOutputData(samples, 0);
// Sums squared samples
float sum = 0;
for (int i = 0; i < SAMPLECOUNT; i++)
{
sum += samples[i] * samples[i];
}
// RMS is the square root of the average value of the samples.
if (sum == 0 )
{
rmsValue = 0f;
dbValuePrev = dbValue;
dbValue = 0f;
pitchValuePrev = pitchValue;
pitchValue = 0f;
return;
}
rmsValue = Mathf.Sqrt(sum / SAMPLECOUNT);
dbValue = 20 * Mathf.Log10(rmsValue / REFVALUE);
// Clamp it to {clamp} min
if (dbValue < -clamp)
{
dbValue = -clamp;
}
// Gets the sound spectrum.
audio.GetSpectrumData(spectrum, 0, fftWindow);
float maxV = 0;
int maxN = 0;
// Find the highest sample.
for (int i = 0; i < SAMPLECOUNT; i++)
{
if (spectrum[i] > maxV && spectrum[i] > THRESHOLD)
{
maxV = spectrum[i];
maxN = i; // maxN is the index of maxV
}
}
// Pass the index to a float variable
float freqN = maxN;
// Interpolate index using neighbours
if (maxN > 0 && maxN < SAMPLECOUNT - 1)
{
float dL = spectrum[maxN-1] / spectrum[maxN];
float dR = spectrum[maxN+1] / spectrum[maxN];
freqN += 0.5f * (dR * dR - dL * dL);
}
// Convert index to frequency
pitchValue = freqN * 24000f / (float)SAMPLECOUNT ;
// Internal pitch/dB value stuff
dbValuePrev = dbValue;
pitchValuePrev = pitchValue;
}
Comment
Your answer
