2012-10-09 23 views
2

維基百科說,我們可以用方程近似Bark標:獲取有關近似樹皮規模等距間隔

b(f) = 13*atan(0.00076*f)+3.5*atan(power(f/7500,2))

我怎麼可以把頻譜分成上巴克尺度相同的長度n區間(區間分割點在樹皮尺度上是等距的)?

最好的方法是分析反函數(通過函數y表示x)。我試圖在紙上做,但失敗了。 WolframAlpha搜索欄也無法做到這一點。我嘗試了Octave finverse函數,但是出現錯誤。

八度說(爲簡單的例子):

octave:2> x = sym('x'); 
octave:3> finverse(2*x) 
error: `finverse' undefined near line 3 column 1 

這是從MATLAB finverse描述:http://www.mathworks.com/help/symbolic/finverse.html

有可能是還數值的方式來做到這一點。我可以想象,您只需從平分軸y開始,並通過二分搜索來尋找理想的分割。但也許有一些現有的工具可以做到這一點?

回答

1

此功能不能分析倒置。你將不得不使用一些數字程序。二進制搜索會很好,但有更有效的方法來做這些事情:看看root-finding algorithms。對於每個頻率間隔端點f_n,您可以將選擇的算法應用於方程b(f) = f_n

1

我最終決定不使用Bark值近似值,而是用於臨界帶中心的理想值(定義爲n=1..24)。我用gnuplot對它們進行了標繪,並在同一圖表上繪製了任意選擇的更高密度點(對於所需的n>24)。我調整了Hz中的點值,直到兩條曲線大致相同。

當然rpsmi大衛Zaslavsky答案都比較一般和可擴展性。

1

只要你知道,在(比方說)倍頻來實現rpsmi的或大衛Zaslavsky的答案,你會做這樣的事情:

global x0 = 0. 

function res = b(f) 
    global x0 
    res = 13*atan(0.00076*f)+3.5*atan(power(f/7500,2)) - x0 
end 

function [intervals, barks] = barkintervals(left, right, n) 
    global x0 
    intervals = linspace(left, right, n); 
    barks  = intervals; 
    for i = 1:n 
     x0 = intervals(i); 
     # 125*x0 is just a crude guess starting point given the values 
     [barks(i), fval, info] = fsolve('b', 125*x0); 
    endfor 
end 

,並像這樣運行:

octave:1> barks 
octave:2> [i,bx] = barkintervals(0, 10, 10) 
[... lots of output from fsolve deleted...] 
i = 

Columns 1 through 8: 

    0.00000 1.11111 2.22222 3.33333 4.44444 5.55556 6.66667 7.77778 

Columns 9 and 10: 

    8.88889 10.00000 

bx = 

Columns 1 through 6: 

    0.0000e+00 1.1266e+02 2.2681e+02 3.4418e+02 4.6668e+02 5.9653e+02 

Columns 7 through 10: 

    7.3639e+02 8.8960e+02 1.0605e+03 1.2549e+03