FFT哪个频率在哪个频段?

时间:2014-11-20 17:32:40

标签: c# fft naudio audio-processing

我想看看某些音频中某些频率,特别是20 - 60hz的低音低音。我将音频作为字节数组,我将其转换为短数组,然后通过(short [i] /(double)short.MaxValue,0)转换为复数。然后我将其传递给Aforge的FFT。

音频是单声道,采样率为44100.我知道我只能在^ 2处通过FFT进行chuck。以4096为例。我不明白输出箱中的频率是多少。

如果我从44100采样率的音频中采集4096个样本。这是否意味着我需要毫秒的音频?或只获得一些将出现的频率?

我将FFT的输出添加到数组中,我的理解是,当我占用4096时,bin 0将包含0 * 44100/4096 = 0hz,bin 1将保持1 * 44100/4096 = 10.7666015625hz等等上。它是否正确?或者我在这里做了一些根本错误的事情?

我的目标是平均20到60赫兹之间的频率,所以对于一首低音重低音的歌曲来说,这个数字会高于低音非常低的软钢琴曲。

这是我的代码。

OpenFileDialog file = new OpenFileDialog();
file.ShowDialog();
WaveFileReader reader = new WaveFileReader(file.FileName);

byte[] data = new byte[reader.Length];
reader.Read(data, 0, data.Length);

samepleRate = reader.WaveFormat.SampleRate;
bitDepth = reader.WaveFormat.BitsPerSample;
channels = reader.WaveFormat.Channels;

Console.WriteLine("audio has " + channels + " channels, a sample rate of " + samepleRate + " and bitdepth of " + bitDepth + ".");


short[] shorts = data.Select(b => (short)b).ToArray();

int size = 4096;
int window = 44100 * 10;
int y = 0;
Complex[] complexData = new Complex[size];
for (int i = window; i < window + size; i++) 
{
    Complex tmp = new Complex(shorts[i]/(double)short.MaxValue, 0);

    complexData[y] = tmp;
    y++;

}




FourierTransform.FFT(complexData, FourierTransform.Direction.Forward);


double[] arr = new double[complexData.Length];
//print out sample of conversion
for (int i = 0; i < complexData.Length; i++)
{
    arr[i] = complexData[i].Magnitude;

}

Console.Write("complete, ");


return arr; 

编辑:更改为DFT的FFT

1 个答案:

答案 0 :(得分:1)

这是您的代码的修改版本。请注意以&#34; ***&#34;。

开头的评论
OpenFileDialog file = new OpenFileDialog();
file.ShowDialog();
WaveFileReader reader = new WaveFileReader(file.FileName);

byte[] data = new byte[reader.Length];
reader.Read(data, 0, data.Length);

samepleRate = reader.WaveFormat.SampleRate;
bitDepth = reader.WaveFormat.BitsPerSample;
channels = reader.WaveFormat.Channels;

Console.WriteLine("audio has " + channels + " channels, a sample rate of " + samepleRate + " and bitdepth of " + bitDepth + ".");

// *** NAudio "thinks" in floats
float[] floats = new float[data.Length / sizeof(float)]
Buffer.BlockCopy(data, 0, floats, 0, data.Length);

int size = 4096;
// *** You don't have to fill the FFT buffer to get valid results.  More noisy & smaller "magnitudes", but better freq. res.
int inputSamples = samepleRate / 100; // 10ms... adjust as needed
int offset = samepleRate * 10 * channels;
int y = 0;
Complex[] complexData = new Complex[size];
// *** get a "scaling" curve to make both ends of sample region 0 but still allow full amplitude in the middle of the region.
float[] window = CalcWindowFunction(inputSamples);
for (int i = 0; i < inputSamples; i++)
{
    // *** "floats" is stored as LRLRLR interleaved data for stereo audio
    complexData[y] = new Complex(floats[i * channels + offset] * window[i], 0);
    y++;
}
// make sure the back portion of the buffer is set to all 0's
while (y < size)
{
    complexData[y] = new Complex(0, 0);
    y++;
}


// *** Consider using a DCT here instead...  It returns less "noisy" results
FourierTransform.FFT(complexData, FourierTransform.Direction.Forward);


double[] arr = new double[complexData.Length];
//print out sample of conversion
for (int i = 0; i < complexData.Length; i++)
{
    // *** I assume we don't care about phase???
    arr[i] = complexData[i].Magnitude;
}

Console.Write("complete, ");


return arr;

获得结果后,假设44100 Hz采样率和大小= 4096,元素2 - 4应该是您要查找的值。有一种方法可以将它们转换为dB,但我不会随便记住它。

祝你好运!