进一步了解portaudio信号的fftw处理

问题描述 投票:2回答:2

我想用portaudiofftwpp分析我从麦克风端口得到的信号。为此,我按照here提供的解释。我现在的问题是: 据说我应该从传入的数据中抽出一个窗口。在我只录制了很短的时间之后,我的数据已经被分块了,然后处理它。因此,我假设矩形窗口已应用于我的数据。那是对的吗? 现在我得到200k数据点,我应该直接将它们放入数组中:

    Array::array1<Complex> F(np,align);
    Array::array1<double> f(n,align);               // For out-of-place transforms
    //  array1<double> f(2*np,(double *) F()); // For in-place transforms

    fftwpp::rcfft1d Forward(n,f,F);
    fftwpp::crfft1d Backward(n,F,f);
    qDebug() << "Putting " << numSamples << " into an array!";
    for(int i = 0; i < numSamples; i++)
        f[i] = this->data.recordedSamples[i];

或者我应该拆分它们?如果我把它们都放在一个数组中,我会得到哪个分辨率?我的采样率设置为44.1 kHz。

c++ audio fft fftw portaudio
2个回答
4
投票

假设您的数据不是静止的(换句话说,频谱内容是时变的,例如语音或音乐的情况),那么您通常需要选择一个窗口大小,在此期间数据可以被认为是固定。对于语音和音乐,典型的窗口大小可以是20ms的量级。对于44.1 kHz的采样率,这对应于882个采样,因此1024的FFT大小可能是一个很好的起点。

重叠连续窗口也很常见,以便为信号的时变分量获得更好的时间分辨率。通常使用50%的重叠,因此您的第一个样本块将是0..1023,第二个块将是512..1535等。

正如在@ Stefan的回答中已经提出的那样,在FFT之前,应该对每个样本块应用合适的窗口函数。常用的窗户是汉明和冯汉恩(又名汉宁)。显然,窗口函数需要与FFT的大小相同(例如,N = 1024)。

对于数据末尾大小<N的任何剩余样本块,您只需填充零。

上述操作的常用术语是生成spectrogram。它本质上是时间v频率v幅度/相位的3D数据结构,其可以以各种不同方式显示或用于进一步的频域处理。

另请参阅这些密切相关的StackOverflow问题和答案:


1
投票

因此,我假设矩形窗口已应用于我的数据。那是对的吗?

在某种程度上,窗口通常用于滤除由于信号的突然开/关状态引起的高频失真,或者减少或重新排序频谱泄漏(https://en.wikipedia.org/wiki/Spectral_leakage

如果要显示fft,建议应用窗口,尤其是(非矩形)窗口。有关选项,请参阅https://en.wikipedia.org/wiki/Window_function#Hann_.28Hanning.29_window

请注意,您应在fft之前应用窗口。

或者我应该拆分它们?

那么,这取决于您的要求。但总的来说,最好不要因为窗口化,样本越长,那段时间内FFT的准确度就越高,尽管这种技术对于加快速度并不鲜见。

那我的分辨率是多少?

分辨率是采样率除以样本计数。

© www.soinside.com 2019 - 2024. All rights reserved.