2015-03-08 19 views
0

我试图在IOS 8中实现一个吉他调谐器,并从s.o中获得了一些代码。谁已经意识到这一点:它处理Goertzel算法,短期内比较固定频率的大小 - 定义为srings E-A-D-G-B-E。 - 在这里,其被放置在CoreAudio的回调方法的程序:IOS中的吉他调谐器:Goertzel算法不适用于6个字符串中的2个

int currentString(SInt16 *samples, int N) { 

int note0 = 82; 
int note1 = 110; 
int note2 = 147; 
int note3 = 196; 
int note4 = 247; 
int note5 = 330; 

int offset = 0.5; 


double results[6]; 
// filter for the six strings 
results[0] = (goertzelFilter(samples, note0+offset, N) +goertzelFilter(samples, note0, N) + goertzelFilter(samples, note0-offset, N))/3.0; 

results[1] = (goertzelFilter(samples, note1+offset, N) +goertzelFilter(samples, note1, N) + goertzelFilter(samples, note1-offset, N))/3.0; 

results[2] = (goertzelFilter(samples, note2+offset, N) +goertzelFilter(samples, note2, N) + goertzelFilter(samples, note2-offset, N))/3.0; 

results[3] = (goertzelFilter(samples, note3+offset, N) +goertzelFilter(samples, note3, N) + goertzelFilter(samples, note3-offset, N))/3.0; 

results[4] = (goertzelFilter(samples, note4+offset, N) +goertzelFilter(samples, note4, N) + goertzelFilter(samples, note4-offset, N))/3.0; 

results[5] = (goertzelFilter(samples, note5+offset, N) +goertzelFilter(samples, note5, NN) + goertzelFilter(samples, note5-offset, N))/3.0; 


int maxInd = -1; 
double maxVal = 0.0; 

for (int i=0; i<6; i++) { 
    if (results[i] > maxVal) { 

     if (i==0) 
      NSLog(@"String %d - value: %f", i+1, results[i]); 

     maxVal = results[i]; 
     maxInd = i; 
    } 
} 

// if all levels are quite low, return -1 
if (maxVal < 1) { 
    maxInd = -1; 
} 
return maxInd; 
} 

然而,这样的日常工作仅用于下字符串“d-G-B-E”。 对于电子字符串和D字符串,我得到了错误的结果,我认为这种行为与泛音有关,因为它们似乎比搜索字符更强 - 也许低字母“E”有“A”或“D “作为泛音,幅度更大。

我的问题:有s.o.遇到类似的问题?并解决它? Goertzel是正确的算法,还是FFT或卷积更好的解决方案?

去年这里的Goertzel算法使用:

double goertzelFilter(SInt16* samples, double freq, int N) { 
double s_prev = 0.0; 
double s_prev2 = 0.0; 
double coeff,normalizedfreq,power,s; 
int i; 
normalizedfreq = freq/44100; 
coeff = 2*cos(2*M_PI*normalizedfreq); 
for (i=0; i<N; i++) { 
    s = samples[i] + coeff * s_prev - s_prev2; 
    s_prev2 = s_prev; 
    s_prev = s; 
} 
power = s_prev2*s_prev2+s_prev*s_prev-coeff*s_prev*s_prev2; 
return power; 
} 

回答

0

戈泽尔算法在特定的频率,而不是音高(这是一个不同的心理声学现象)测量能量。许多弦乐器和声音产生的最强频谱频率很可能是泛音或泛音,而不是音高频率,而频谱频率是Goertzel滤波器看到的而不是音高。

对于低频字符串声音,尝试使用基音检测/估计算法(如自相关,ASDF,AMDF,RAPT,YAAPT等)代替使用Goertzel滤波器(或简单的DFT量值)的球场。

+0

非常感谢你,hotpaw2 - 我试过AMDF,它完美的工作! – 2015-03-14 18:11:51

相关问题