【问题标题】:Convert linear audio frequency distribution to logarithmic/perceptual distribution?将线性音频频率分布转换为对数/感知分布?
【发布时间】:2015-11-26 00:09:11
【问题描述】:

我正在为脚本创建一些音频提示,但一直遇到同样的问题:

人类的感知是对数的。如果我想将一系列声音分成 10 等份,我不能只从最高音调中减去最低音调并除以 10。这些步骤在感知上并不准确。

因此,当处理一个输出在 20-20000 范围 (kHz) 范围内的函数时,是否有一个基本的数学函数可以合理地近似将这些数字转换为它们的感知等价物——仍然在 20-20000 范围内进行映射?

例子:

我正在处理一个以 kHz 为范围的“哔”命令。

我从我自己的系统测试中知道,这个命令在被测系统上的功能范围是 38 到 9900Hz。

因此,如果我要创建一个音频倒计时来遍历 100 个项目,我会将 9900-38 / 100 划分为每个项目的 98.62Hz 范围。如果我要创建音频倒计时,我会简单地从最大范围开始创建一系列哔声,每次哔声降低 98.62Hz。

但这听起来并不准确。大多数时间都花在高音频率上。没有足够的时间花在低频上。

我确实设法为我的白噪声发生器解决了这个问题,但我无法将相同类型的修复应用于音频倒计时。 (主要是因为白噪声发生器有很大的出错余地。)在那种情况下,我只是将赫兹除以 10。但我这样做是随机的。它给了我想要的效果,但没有任何一致的映射功能:

        if  %@RANDOM[1,10] gt 6 (set BEEP_FREQUENCY_TEMP=%@FLOOR[%@EVAL[BEEP_FREQUENCY_TEMP / 10]] 
        if  %@RANDOM[1,10] gt 9 (set BEEP_FREQUENCY_TEMP=%@FLOOR[%@EVAL[BEEP_FREQUENCY_TEMP / 10]] 
        if  %@RANDOM[1,10] gt 8 (set BEEP_FREQUENCY_TEMP=%@FLOOR[%@EVAL[BEEP_FREQUENCY_TEMP / 10]]

你能告诉我我什至不知道如何问我的问题吗?

【问题讨论】:

    标签: math audio logarithm beep


    【解决方案1】:

    我最终查找了与音符匹配的所有频率的列表,制作了一个包含所有这些频率的文本文件,并以我想要的任何间隔简单地迭代它。例如,如果我想要一个指示 10% 上传进度的注释,它会获取总行数,并通过文件抓取 10% 的行。这解决了使我的音频倒计时听起来线性的问题,即使这样做所需的频率不是线性的。

    查找表。

    不优雅,但有效。

    【讨论】:

      【解决方案2】:

      您可能知道,从一个音调到一个高八度的音调,其频率会加倍。从那里再去一个八度加倍。所以你所拥有的是一个以二为底的指数的指数线性增加(每八度增加 1,或每半音增加 1/12):

      f = 440Hz · 2x

      现在将可能的 x 值范围划分为固定间隔,您应该完成了。要将频率 f 转换为音高 x,您需要计算一个对数,即

      x = log2(f / 440Hz) = ln(f / 440Hz)/ln(2)

      【讨论】:

        【解决方案3】:

        你需要使用对数间距:

        // start - start frequency
        // stop - stop frequency
        // n - the point which you wish to compute (zero based)
        // N - the number of points over which to divide the frequency
        // range.
        double logspace(double start, double stop, int n, int N)
        {
            return start * pow(stop/start, n/(double)(N-1));
        }
        

        例如:

        logspace(20, 200000, 0, 4) = 20
        logspace(20, 200000, 1, 4) = 200
        logspace(20, 200000, 2, 4) = 2000
        logspace(20, 200000, 3, 4) = 20000
        

        注意logspace(x,y,0,N) 可能不完全等于xlogspace(x,y,N-1,N) 可能不完全等于y。这是由于浮点精度和舍入误差造成的。

        【讨论】:

          猜你喜欢
          • 2015-03-31
          • 1970-01-01
          • 2016-01-04
          • 2011-02-05
          • 2017-07-04
          • 1970-01-01
          • 2014-07-15
          • 2013-01-06
          • 2016-07-29
          相关资源
          最近更新 更多