使用不同的值增加音频的音高

时间:2011-04-20 15:45:35

标签: c math audio signal-processing interpolation

好的,这有点数学和DSP问题。

我们说我有20,000个样本,我想以不同的间距重新取样。例如,正常速率的两倍。使用Interpolate cubic method found here我会通过将迭代中的i变量乘以新音高(在本例中为2.0)来设置我的新数组索引值。这也将我的新样本数组设置为10,000。由于插值速度是其速度的两倍,因此只需要一半的时间即可完成。

但是,如果我希望我的音调在整个录音中变化怎么办?基本上我希望它从正常速率缓慢增加到8倍(在10,000个样本标记处)然后再回到1.0。这将是一个弧形。我的问题是:

如何计算最终音轨的样本数量?

如何创建一个音高值数组,表示从1.0到8.0的增加回到1.0

请注意,这不是用于实时音频输出,而是用于转换录制的声音。我主要在C工作,但我不知道这是否相关。

我知道这可能很复杂,所以请随时要求澄清。

2 个答案:

答案 0 :(得分:3)

要表示从1.0增加到8.0并返回,您可以使用以下形式的函数:

f(x) = 1 + 7/2*(1 - cos(2*pi*x/y))

其中y是结果曲目中的样本数。

x=0从1开始,x=y/2增加到8,x=y减少到1。

以下是y=10的内容: plot 1 + 7/2*(1 - cos(2*pi*x/10)) from 0 to 10

现在我们需要找到y的值取决于z,原始样本数量(在这种情况下为20,000,但让我们一般)。为此,我们解决integral 1+7/2 (1-cos(2 pi x/y)) dx from 0 to y = z。解决方案是y = 2*z/9 = z/4.5,非常简单:)

因此,对于包含20,000个样本的输入,您将在输出中获得4,444个样本。

最后,不是将输出索引乘以音高值,而是可以访问原始样本:output[i] = input[g(i)],其中g是上述函数f的积分:

g(x) = (9*x)/2-(7*y*sin((2*pi*x)/y))/(4*pi)

对于y=4444,它看起来像这样:

plot (9*x)/2-(7*4444*sin((2*pi*x)/4444))/(4*pi) from 0 to 4444

答案 1 :(得分:1)

为了不在结果中产生混叠,您还需要在插值之前或插值期间使用可变转换频率低于本地采样率的滤波器或具有固定截止频率的滤波器进行低通滤波比当前采样率低16倍(峰值间距增加8倍)。这将需要比三次样条更复杂的插值器。为了获得最佳结果,您可能需要尝试使用可变宽度窗口sinc内核插值器。