我想看看在一段音频中,某些频率,特别是20 - 60Hz的低音。我有音频作为一个字节数组,我将它转换为短阵列,然后通过(short [i] /(double)short.MaxValue,0)转换为一个复数。然后我把它传给Aforge的FFT。FFT哪些频率在哪些分箱?
音频是单声道的,采样率为44100.据我所知,我只能在^ 2处通过FFT加载卡盘。例如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;
编辑:改到FFT来回DFT
那么你似乎在做一个DFT(它比FFT更精确),但是返回的数据是如何构造的,我不知道。应该在您正在使用的库的文档中。从根本上说,如果数据的结构是线性的,那么它就是对的,但它也可以用对数结构。 – MrPaulch 2014-11-20 18:30:47
感谢您指出了这一点,我的意思是运行fft,当我正在玩DFT时只是复制了代码。 – 2014-11-20 18:47:14
你基本上是在正确的轨道上 - 你的箱子在你计算的时候宽度大约为10赫兹 - 见[这个答案](http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft -result/4371627#4371627)以获得更全面的解释。 – 2014-11-20 20:07:25