Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NAudio FFT返回所有频率的较小且相等的幅值_C#_Fft_Naudio - Fatal编程技术网

C# 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

我正在使用NAudio 1.9进行一个项目,我想计算整首歌曲的fft,即将歌曲分成大小相等的块,然后计算每个块的fft。问题是NAudio FFT函数返回的是频谱中任何频率的非常小且相等的值

我搜索了以前的相关帖子,但似乎没有一篇对我有帮助

使用NAudio计算FFT的代码:

公共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) 我接收到的小幅度值来自这样一个事实,即我测试代码的音频文件没有记录足够的增益