2

维基百科说我们可以用以下等式近似 Bark 尺度:

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

如何在 Bark 尺度上将频谱划分n为相同长度的区间(区间划分点在 Bark 尺度上是等距的)?

最好的方法是解析反函数(x用 的函数表示y)。我试图在纸上做,但失败了。WolframAlpha 搜索栏也做不到。我尝试了 Octavefinverse函数,但出现错误。

Octave 说(举个简单的例子):

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

这是finverse来自 Matlab 的描述:http: //www.mathworks.com/help/symbolic/finverse.html

也可以有数字方式来做到这一点。我可以想象你只是从等分y轴开始,通过二分搜索寻找理想的划分。但也许有一些现有的工具可以做到这一点?

4

4 回答 4

1

这个函数不能解析倒置。您将不得不使用一些数字程序。二进制搜索会很好,但是有更有效的方法来做这些事情:研究寻根算法。您可以将您选择的算法b(f) = f_n应用于每个频率间隔端点的方程f_n

于 2012-10-09T19:54:25.820 回答
1

您需要对这个方程进行数值求解(没有解析反函数)。设置b等间距的值并求解方程以找到各种f. 二分法有点慢,但一个很好的替代方法是布伦特的方法。见http://en.wikipedia.org/wiki/Brent%27s_method

于 2012-10-09T20:00:41.957 回答
1

我最终决定不使用 Bark 值近似值,而是使用临界带中心的理想值(定义为n=1..24)。我用gnuplot和 在同一张图上绘制了它们,我为更高密度的点(对于所需的n>24)绘制了任意选择的值。我调整了点值,Hz直到两条曲线大致相同。

当然rpsmiDavid Zaslavsky的答案更加通用和可扩展。

于 2012-10-10T08:40:12.380 回答
1

就像你知道的那样,在(比如说)八度音程中实现 rpsmi 或 David 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
于 2012-10-10T12:11:28.033 回答