C# NAudio FFT返回所有频率的较小且相等的幅值
我正在使用NAudio 1.9进行一个项目,我想计算整首歌曲的fft,即将歌曲分成大小相等的块,然后计算每个块的fft。问题是NAudio FFT函数返回的是频谱中任何频率的非常小且相等的值 我搜索了以前的相关帖子,但似乎没有一篇对我有帮助 使用NAudio计算FFT的代码:C# NAudio FFT返回所有频率的较小且相等的幅值,c#,fft,naudio,C#,Fft,Naudio,我正在使用NAudio 1.9进行一个项目,我想计算整首歌曲的fft,即将歌曲分成大小相等的块,然后计算每个块的fft。问题是NAudio FFT函数返回的是频谱中任何频率的非常小且相等的值 我搜索了以前的相关帖子,但似乎没有一篇对我有帮助 使用NAudio计算FFT的代码: 公共IList Fft(uint窗口大小){ IList timeDomainChunks=this.SplitInChunks(this.audioContent,WindowsSize); 返回timeDomainCh
公共IList Fft(uint窗口大小){
IList timeDomainChunks=this.SplitInChunks(this.audioContent,WindowsSize);
返回timeDomainChunks.Select(this.tofFrequencySpectrum.ToList();
}
私有IList SplitInChunks(浮点[]音频内容,uint chunkSize){
IList splittedContent=新列表();
对于(uint k=0;k
频谱:
公共结构频谱{
私有只读复数[]频域;
专用只读单元采样频率;
公共频谱(复[]频域,uint采样频率){
if(frequencyDomain.Length==0){
抛出新ArgumentException(“参数值必须大于0”,nameof(frequencyDomain));
}
if(采样频率==0){
抛出新ArgumentException(“参数值必须大于0”,nameof(samplingFrequency));
}
this.frequencyDomain=frequencyDomain;
this.samplingFrequency=采样频率;
}
//返回频率的大小
公共浮动本[uint freq]{
得到{
如果(频率>=此采样频率){
抛出新的IndexOutOfRangeException();
}
//查找相应的垃圾箱
float k=freq/((float)this.samplingFrequency/this.FftWindowSize);
复数c=该频域[选中((uint)k)];
返回(浮点)数学Sqrt(c.X*c.X+c.Y*c.Y);
}
}
}
对于包含440Hz正弦波的文件
预期输出:freq=440的值为0.5,其他值为0
实际输出:频谱中任何频率的值,如0.000168153987f,似乎我犯了4个错误: 1) 这里我测量的采样频率是44100。但这并不是我的代码不起作用的原因
return new FrequencySpectrum(timeDomain, 44100);
2) 始终对输出数据进行可视化表示!我必须吸取这个教训。。。似乎对于一个包含440Hz正弦波的文件,我得到了正确的结果,但是
3) 由于以下原因,频谱与我预期的略有偏移:
int m = (int) Math.Log(timeDomain.Length, 2);
FastFourierTransform.FFT(true, m, timeDomain);
时域是一个大小为44100的数组,因为这是WindowsSize的值(我使用WindowsSize=44100调用该方法),但FFT方法要求窗口大小的值幂为2。我说的是“NAudio,给我计算这个数组的fft,它有44100个元素,但只考虑前32768个”。我没有意识到这会对结果产生严重影响:
float k = freq / ((float) this.samplingFrequency / this.FftWindowSize);
这里,this.FftWindowSize是基于数组大小的属性,而不是基于m。所以,在对结果进行可视化后,我发现440Hz频率的大小实际上与调用对应:
spectrum[371]
而不是
spectrum[440]
因此,我的错误是fft(m)的窗口大小与阵列的实际长度(FrequencySpectrum.FftWindowSize)不对应
4) 我收到的小幅度值来自这样一个事实,即我测试代码的音频文件没有记录足够的增益。似乎我犯了4个错误: 1) 这里我测量的采样频率是44100。但这并不是我的代码不起作用的原因
return new FrequencySpectrum(timeDomain, 44100);
2) 始终对输出数据进行可视化表示!我必须吸取这个教训。。。似乎对于一个包含440Hz正弦波的文件,我得到了正确的结果,但是
3) 由于以下原因,频谱与我预期的略有偏移:
int m = (int) Math.Log(timeDomain.Length, 2);
FastFourierTransform.FFT(true, m, timeDomain);
时域是一个大小为44100的数组,因为这是WindowsSize的值(我使用WindowsSize=44100调用该方法),但FFT方法要求窗口大小的值幂为2。我说的是“NAudio,给我计算这个数组的fft,它有44100个元素,但只考虑前32768个”。我没有意识到这会对结果产生严重影响:
float k = freq / ((float) this.samplingFrequency / this.FftWindowSize);
这里,this.FftWindowSize是基于数组大小的属性,而不是基于m。所以,在对结果进行可视化后,我发现440Hz频率的大小实际上与调用对应:
spectrum[371]
而不是
spectrum[440]
因此,我的错误是fft(m)的窗口大小与阵列的实际长度(FrequencySpectrum.FftWindowSize)不对应
4) 我接收到的小幅度值来自这样一个事实,即我测试代码的音频文件没有记录足够的增益