首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >IOS和FFT (vDSP_fft_zrip):频率低于appr。100赫兹被切断-为什么?

IOS和FFT (vDSP_fft_zrip):频率低于appr。100赫兹被切断-为什么?
EN

Stack Overflow用户
提问于 2015-06-19 09:45:40
回答 2查看 1.6K关注 0票数 0

我正在使用诺沃卡因框架来执行音高检测。所有的操作都很好,只有用图形FFT表示,才会有一些问题.

当我使用音频文件作为输入时,FFT的工作频率在100 Hz以下是完美的。

相反,当我使用麦克风作为输入,频率低于100赫兹是根本没有显示-我不知道为什么!见下面的截图:

更高的频率(例如1000赫兹)被正确地显示!

以下是FFT过程的源代码:

代码语言:javascript
运行
复制
- (NSMutableArray*)performFFT: (float*) data  withFrames: (int) numSamples {
    // 1. init
    float bufferSize = numSamples;
    uint32_t maxFrames = numSamples;
    displayData = (float*)malloc(maxFrames*sizeof(float));
    bzero(displayData, maxFrames*sizeof(float));
    int log2n = log2f(maxFrames);
    int n = 1 << log2n;
    assert(n == maxFrames);
    float nOver2 = maxFrames/2;
    
    
    A.realp = (float*)malloc(nOver2 * sizeof(float));
    A.imagp = (float*)malloc(nOver2 * sizeof(float));
    fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
    
    // 2. calcuate
    bufferSize = numSamples;
    float ln = log2f(numSamples);
    vDSP_ctoz((COMPLEX*)data, 2, &A, 1, numSamples/2);
    
    //fft
    vDSP_fft_zrip(fftSetup, &A, 1, ln, FFT_FORWARD);
    
    // Absolute square (equivalent to mag^2)
    vDSP_zvmags(&A, 1, A.realp, 1, numSamples/2);
    // make imaginary part to zero in order to filter them out in the following loop
    bzero(A.imagp, (numSamples/2) * sizeof(float));
    
    //convert complex split to real
    vDSP_ztoc(&A, 1, (COMPLEX*)displayData, 2, numSamples/2);
    
    // Normalize
    float scale = 1.f/displayData[0];
    vDSP_vsmul(displayData, 1, &scale, displayData, 1, numSamples);
    
    
    //scale fft
    Float32 mFFTNormFactor = 1.0/(2*numSamples);
    vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, numSamples/2);
    vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, numSamples/2);

...
}

对于进一步的图形问题,我使用displayData

由于我对较低的频率感兴趣(有一个单独的基音检测算法工作很好),我已经将采样率降低到11.025 (而不是44100)。

在诺沃卡因,我打以下电话:

1)输入

代码语言:javascript
运行
复制
[audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
            
            // frequency analysis
            vDSP_rmsqv(data, 1, &magnitude, numFrames*numChannels);
            self->ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels);
...
}

2)产出:

代码语言:javascript
运行
复制
[audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
     { 
   self->ringBuffer->FetchInterleavedData(data, numFrames, numChannels);
   ....
   [fft performFFT:data withFrames:numFrames];
   ...
   }

有人有主意吗?

EN

回答 2

Stack Overflow用户

发布于 2015-06-19 13:46:02

这是因为内置麦克风是一个冷凝器麦克风,并有一个高通滤波器,以消除直流偏置的信号。

可以禁用HPF。直流偏置并不是什么问题,因为它只会出现在FFT的bin #0中。

代码语言:javascript
运行
复制
[[AVAudioSession sharedInstance] setMode: AVAudioSessionModeMeasurement error:NULL];

还请注意,对FFT的加窗也会影响FFT的低频桶的精度。在给定的频率下,窗口中至少需要2*PI的样本。

票数 1
EN

Stack Overflow用户

发布于 2015-06-22 17:49:50

基音与频谱频率不同。低音调的声音通常由谐波和泛音能量组成,在基频上没有多少能量。因此,FFT在那里也找不到什么。自相关在找到这些类型的谐波丰富的声音的音高方面略好一些。

此外,iPhone麦克风对低频能量不像对中高音频敏感(有音频响应图在线)。

还请注意,FFT缓冲器需要按比例更长,以具有等效百分比(相等的回火螺距,美分)分辨率的低频内容。低频率分辨率通常需要远长于由iOS音频单元提供的任何单个缓冲器的快速傅立叶变换。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30934971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档