C++ 如何动态更改.wav或.wav的速度。实时使用arduino的aiff文件

C++ 如何动态更改.wav或.wav的速度。实时使用arduino的aiff文件,c++,audio,arduino,C++,Audio,Arduino,我正在研制一种光剑的原型,它可以在光剑移动时改变其嗡嗡声的音调和音量。目前的解决方案只改变音量(简单),听起来不够真实。我知道我需要使用.wav或.aiff(不像mp3那样有损)来完成这项工作。理想情况下,我正在寻找一个轻量级的解决方案,因为我计划在Arduino Nano extra上运行这个的最终迭代。所以,问题是,如何改变.wav或.aiff的读取/输出速度(从而改变声音的音调)?不管计算能力如何,有人知道任何可以实时完成这一任务的方法吗?嗯。。。我不完全确定这将如何工作。我的理解是,wa

我正在研制一种光剑的原型,它可以在光剑移动时改变其嗡嗡声的音调和音量。目前的解决方案只改变音量(简单),听起来不够真实。我知道我需要使用.wav或.aiff(不像mp3那样有损)来完成这项工作。理想情况下,我正在寻找一个轻量级的解决方案,因为我计划在Arduino Nano extra上运行这个的最终迭代。所以,问题是,如何改变.wav或.aiff的读取/输出速度(从而改变声音的音调)?不管计算能力如何,有人知道任何可以实时完成这一任务的方法吗?

嗯。。。我不完全确定这将如何工作。我的理解是,wav和.afff文件是原始音频(也许这就是为什么你说你需要使用它们)我确实找到了这个答案,但是它使用了Python,这对你的ARDUINO来说不起作用,但是你可以用C++来使用这个技术。也许其他更了解这一点的人可以看看这一点,并解释如何在C++中进行更改要更改音频采样流的音调,您需要更改其采样率。“简单”的方法是更改音频硬件采样时钟的频率,例如,如果您想将播放音调增加10%,您可以将DAC设置为每秒转换52800个采样,而不是正常的每秒48000个采样

但是,在我使用的大多数平台上,不允许对输出采样率设置进行那种级别的控制。通常,它们只允许您从少量的“标准”输出速率中进行选择,如44100、48000、96000等。然而,也许Arduino允许对DAC的采样速率进行细粒度控制;在这种情况下,您有一个简单的解决方案

如果不是,则替代方法是更改输入到音频设备的样本流的内容,使其表现为以不同速率播放样本。这就是所谓的,准确地做到这一点是非常重要的。如果你不需要精确性(例如,因为你只是在做光剑音效,在输出中添加噪音不是问题),你可以做一个快速而肮脏的工作,当你想增加音高时,只需删除每(n)个样本,或者当你想降低音高时,重复每(n)个样本。n的值由所需的“虚拟采样率”与音频输出的实际采样率之比决定;你需要做一些数学运算来解决这个问题,但这应该不会太难

如果,OTOH,您想要一个不向输出中添加伪影和噪声的高质量采样率转换,那么您需要使用一个合适的采样率转换库来为您处理必要的数学运算。它很好地避免了增加的噪声和伪影,如果需要权衡质量以降低CPU使用率,可以指定不同的质量级别。为了获得实时效果,您可能需要使用,以便可以动态更改俯仰比


请注意,上述两种方法中的任何一种不仅会改变播放的音调,还会改变播放的持续时间——例如,如果您将声音效果的感知音调增加10%,那么最终的声音效果也会比原始效果快10%。如果你想在不改变声音持续时间的情况下改变声音的音高,有很多方法可以做到这一点,但我对它们没有任何经验,所以我不能评论它们对这个用例的适用性。

伙计,你是一个传奇。我不知道Arduino是否会允许我使用第一种方法(更改DAC),但如果是这样,那么这将轻而易举地解决我的所有问题。对于第二种方法,你完全正确--我不需要完美的音质,而且因为我使用的硬件非常有限,它(显然)快得多这一事实是可取的。关于最后一点——幸运的是,我将简单地循环声音效果,所以它播放多长时间无关紧要。感谢这一点,这真的很有帮助,你今天过得很愉快:)顺便说一句,处理这个问题的另一个(非常粗糙)方法是预渲染多个音频文件,每个文件包含不同音高的声音,并根据你想要产生的音高播放来自不同音频文件的样本。您可以根据需要在文件之间交叉淡入淡出,以避免在从一个文件转换到另一个文件时出现任何明显的故障。缺点是这样做会占用额外的内存和磁盘空间,而且可能过于粗糙,无法给出所需的结果。为此,我将添加一个非常基本的线性插值。因此,如果您以分数速率(例如x1.25速度)通过样本,当您要求样本索引
1.25
时,您的输出应该是
(1-0.25)*样本[1]+0.25*样本[2]
。或者更一般地说:
(1-alpha)*样本[i]+alpha*样本[i+1];i=地板(浮动指数);alpha=float_index-i:
非常全面的答案