在iPhone上进行FFT以忽略背景噪音并找到较低的音高 [英] FFT on iPhone to ignore background noise and find lower pitches

查看:491
本文介绍了在iPhone上进行FFT以忽略背景噪音并找到较低的音高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为iPhone实施了Demetri的 Pitch Detector 项目,并遇到了两个问题。 1)任何类型的背景噪声发送频率读取香蕉和2)较低频率的声音没有正确投球。我试着调整我的吉他,而更高的琴弦工作 - 调音器无法正确识别低音。

I have implemented Demetri's Pitch Detector project for the iPhone and hitting up against two problems. 1) any sort of background noise sends the frequency reading bananas and 2) lower frequency sounds aren't being pitched correctly. I tried to tune my guitar and while the higher strings worked - the tuner could not correctly discern the low E.

音高检测代码位于RIOInterface.mm并且去了像这样......

The Pitch Detection code is located in RIOInterface.mm and goes something like this ...

// get the data
AudioUnitRender(...);

// convert int16 to float
Convert(...);

// divide the signal into even-odd configuration
vDSP_ctoz((COMPLEX*)outputBuffer, 2, &A, 1, nOver2);

// apply the fft
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);

// convert split real form to split vector
vDSP_ztoc(&A, 1, (COMPLEX *)outputBuffer, 2, nOver2);

然后Demetri继续确定主导频率如下:

Demetri then goes on to determine the 'dominant' frequency as follows:

float dominantFrequency = 0;
int bin = -1;
for (int i=0; i<n; i+=2) {
    float curFreq = MagnitudeSquared(outputBuffer[i], outputBuffer[i+1]);
    if (curFreq > dominantFrequency) {
        dominantFrequency = curFreq;
        bin = (i+1)/2;
    }
}
memset(outputBuffer, 0, n*sizeof(SInt16));

// Update the UI with our newly acquired frequency value.
[THIS->listener frequencyChangedWithValue:bin*(THIS->sampleRate/bufferCapacity)];

首先,我相信我需要申请低通过率...但我是不是FFT专家,也不确定在何处或如何对vDSP函数返回的数据执行此操作。我也不确定如何在较低频率下提高代码的准确性。似乎还有其他算法来确定主导频率 - 但是,当使用Apple的Accelerate框架返回的数据时,再次寻找正确的方向。

To start with, I believe I need to apply a LOW PASS FILTER ... but I'm not an FFT expert and not sure exactly where or how to do that against the data returned from the vDSP functions. I'm also not sure how to improve the accuracy of the code in the lower frequencies. There seem to be other algorithms to determine the dominant frequency - but again, looking for a kick in the right direction when using the data returned by Apple's Accelerate framework.

更新:

加速框架实际上有一些窗口函数。我设置了一个像这样的基本窗口

The accelerate framework actually has some windowing functions. I setup a basic window like this

windowSize = maxFrames;
transferBuffer = (float*)malloc(sizeof(float)*windowSize);
window = (float*)malloc(sizeof(float)*windowSize);
memset(window, 0, sizeof(float)*windowSize);
vDSP_hann_window(window, windowSize, vDSP_HANN_NORM); 

然后我通过插入来申请

vDSP_vmul(outputBuffer, 1, window, 1, transferBuffer, 1, windowSize); 

。然后我改变其余代码使用'transferBuffer'而不是outputBuffer ...但到目前为止,还没有注意到最终音高猜测的任何戏剧性变化。

before the vDSP_ctoz function. I then change the rest of the code to use 'transferBuffer' instead of outputBuffer ... but so far, haven't noticed any dramatic changes in the final pitch guess.

推荐答案

Pitch与峰值幅度频率bin不同(这是Accelerate框架中的FFT可能直接给你的)。因此任何峰值频率检测器对于音调估计都不可靠。当音符缺少或非常弱的基音(在某些声音,钢琴和吉他声中很常见)和/或其频谱中有很多强大的泛音时,低通滤波器将无法帮助。

Pitch is not the same as peak magnitude frequency bin (which is what the FFT in the Accelerate framework might give you directly). So any peak frequency detector will not be reliable for pitch estimation. A low-pass filter will not help when the note has a missing or very weak fundamental (common in some voice, piano and guitar sounds) and/or lots of powerful overtones in its spectrum.

查看音乐声的宽带频谱或光谱图,你会看到问题。

Look at a wide-band spectrum or spectrograph of your musical sounds and you will see the problem.

通常需要其他方法来获得更可靠的估计音乐节目。其中一些包括自相关方法(AMDF,ASDF),倒谱/倒谱分析,谐波积谱,相位声码器和/或复合算法,例如RAPT(用于音高跟踪的鲁棒算法)和YAAPT。 FFT仅作为上述某些方法的子部分有用。

Other methods are usually needed for a more reliable estimate of musical pitch. Some of these include autocorrelation methods (AMDF, ASDF), Cepstrum/Cepstral analysis, harmonic product spectrum, phase vocoder, and/or composite algorithms such as RAPT (Robust Algorithm for Pitch Tracking) and YAAPT. An FFT is useful as only a sub-part of some of the above methods.

这篇关于在iPhone上进行FFT以忽略背景噪音并找到较低的音高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆