以编程方式增加音频样本数组的音高

Eri*_*tto 12 audio signal-processing pitch

你好,音频计算世界的人,

我有一系列样本可以呈现录音.让我们说它在44100Hz时是5秒.如何以更高的音高播放这个?是否可以动态增加和减少音高?就像让音调慢慢增加到速度加倍然后再下降.

换句话说,我想录制并播放它,好像被dj"划伤"一样

伪代码总是受欢迎的.我将用C写这篇文章.

谢谢,


编辑1

请允许我澄清我的意图.我想将播放保持在44100Hz,因此我需要在播放前操作样本.这也是因为我想要将音调增加的音频与以正常速率运行的音频混合.

用另一种方式表达,也许我需要以某种方式在相同数量的样本上缩小音频?这样播放时听起来会更快吗?


编辑2

另外,我想自己这样做.请不要图书馆(除非你觉得我可以选择代码并找到有趣的东西).


编辑3

用C语言编写的一段代码示例,它带有2个参数(样本数组和音高因子),然后返回一个新音频数组就太棒了!


PS我开始对此表示赏心,不是因为我认为已经给出的答案无效.我只是觉得在这个问题上获得更多反馈会很好.



获得奖项

老实说,我希望我可以将赏金分配给几个不同的答案,因为我认为这些答案非常有用.特别感谢丹尼尔向我传递了一些代码,而AShelly和Hotpaw2则提供了如此详细的回复.

最终,虽然我使用了数据专家引用的另一个SO问题的答案,因此该奖项归他所有.

再次感谢大家!

dat*_*ist 10

看看Nosredna的答案中的"大象"论文(非常相似)问题: 你如何对重新采样的音频数据进行双三次(或其他非线性)插值?

从第37页开始提供示例实现,作为参考,AShelly的答案对应于线性插值(在同一页面上).通过一些调整,本文中的任何其他公式都可以插入到该框架中.

要评估给定插值方法的质量(并了解使用"更便宜"方案的潜在问题),请查看此页面:

http://www.discodsp.com/highlife/aliasing/

对于比您可能想要处理的更多理论(使用源代码),这也是一个很好的参考:

https://ccrma.stanford.edu/~jos/resample/


ASh*_*lly 8

一种方法是将浮点索引保持在原始波中,并将内插样本混合到输出波中.

//Simulate scratching of `inwave`: 
// `rate` is the speedup/slowdown factor. 
// result mixed into `outwave`
// "Sample" is a typedef for the raw audio type.
void ScratchMix(Sample* outwave, Sample* inwave, float rate)
{
   float index = 0;
   while (index < inputLen)
   {
      int i = (int)index;          
      float frac = index-i;      //will be between 0 and 1
      Sample s1 = inwave[i];
      Sample s2 = inwave[i+1];
      *outwave++ += s1 + (s2-s1)*frac;   //do clipping here if needed
      index+=rate;
   }
Run Code Online (Sandbox Code Playgroud)

}

如果你想rate在飞行中改变,你也可以这样做.

如果在速率> 1时这会产生噪声瑕疵,请尝试*outwave++ += s1 + (s2-s1)*frac;使用此技术替换(来自此问题)

*outwave++ = InterpolateHermite4pt3oX(inwave+i-1,frac);
Run Code Online (Sandbox Code Playgroud)

哪里

public static float InterpolateHermite4pt3oX(Sample* x, float t)
{
    float c0 = x[1];
    float c1 = .5F * (x[2] - x[0]);
    float c2 = x[0] - (2.5F * x[1]) + (2 * x[2]) - (.5F * x[3]);
    float c3 = (.5F * (x[3] - x[0])) + (1.5F * (x[1] - x[2]));
    return (((((c3 * t) + c2) * t) + c1) * t) + c0;
}
Run Code Online (Sandbox Code Playgroud)

在"Windows Startup.wav"上使用线性插值技术的因子为1.1.原件位于顶部,加速版本位于底部:

它可能不是数学上完美的,但它听起来应该是,并且应该适合OP的需要..

  • 我仍然建议OP首先尝试这个.模拟在背景轨道上抓一条轨道可能不需要最纯粹的转换.至少,这种方法很容易实现,如果需要,可以从中轻松替换更复杂的过滤器. (2认同)