不改变音调情况下Audio音频的倍速合成JS实现
内容提要
本文介绍了使用JavaScript实现音频倍速合成的方法,包括解决变速后音调变化的问题和改进的算法实现。作者提供了两个项目链接,分别是timestretch和OLA-TS.js,后者效果更好。文章还提到了其他与音频时间速率和音调相关的项目,并表示将在下篇文章中继续讨论。
延伸解读
简单采样变速为何改变音调
文章指出,直接通过重复或间隔采样实现倍速,虽然时长正确,但会改变音调。这是因为播放速率变化导致波形变陡或变缓,从而音调升高或降低。慢速时声音低沉,快速时音调变高,这是音频处理中的常见问题,需要专门算法解决。
颗粒合成算法的解决思路
为保持音调不变,文章介绍了颗粒合成算法。其原理是将音频波形截成小颗粒,调整颗粒起点位置以匹配目标速率,同时保持每个颗粒的波形曲度不变。这样播放速度改变,但音调不受影响。该算法涉及复杂数学计算,作者选择使用现有实现。
timestretch 项目的实际效果与局限
作者尝试了 timestretch 项目,其代码简单,但实际效果不佳。测试中音频出现明显噪点和杂音,即使使用 AI 语音,背景也有刺耳噪音。项目作者也承认这不是最佳实现。因此,该算法不适合真实项目,尤其是对音质要求较高的场景。
OLA-TS.js 的改进与使用建议
文章推荐 OLA-TS.js,它采用改进的重叠相加算法,效果更好。作者整合后提供了使用示例,处理后的音频无杂音、流畅。但该项目年久失修,上手需调试。对于需要高质量音频变速的开发者,这是一个值得尝试的解决方案。
Q&A
为什么用JavaScript对音频进行倍速处理后音调会发生变化?
因为声音是一种波,播放速率变快会使波形变得更陡峭,从而导致音调升高;播放速率变慢则波形更平缓,音调降低。所以简单的采样重复或间隔取样虽然能改变时长,但会连带改变音调。
颗粒合成算法是如何在改变音频播放速率的同时保持音调不变的?
颗粒合成算法将音频采样曲线截成一段一段的颗粒,让每段颗粒的曲度与默认播放曲线一致,然后通过偏移这些颗粒的起点位置来保持设定的播放速率。这样用户听起来播放速度快了,但音调并未改变。
timestretch项目在音频倍速处理中的实际效果如何?
timestretch项目代码简单,但效果较差。使用后虽然能保持音调,但会产生很多噪点杂音,音频波形细节丢失,甚至出现刺耳的重金属噪音,不适合在真实项目中使用。作者也承认这不是最好的实现。
如何使用OLA-TS.js实现音频倍速且保持音调不变?
首先引入bufferedOla.js,然后创建新的AudioBuffer,接着实例化BufferedOLA,设置原始音频缓冲,将alpha设为1/rate,最后调用process方法处理新缓冲。执行后newAudioBuffer就是处理后的倍速音频数据。
OLA-TS.js相比timestretch有哪些优势?
OLA-TS.js是一种改进的重叠和添加(OLA)算法的音频时间拉伸实现,使用后音频处理效果流畅且无杂音,而timestretch会产生明显噪点和杂音。因此OLA-TS.js的声音质量更好,更适合实际项目。
文章最后提到了哪些与音频时间速率和音调相关的项目?
文章最后附上了一些与音频时间速率和音调相关的项目链接,但未具体列出项目名称,仅说明这些都是很多年之前的项目,并表示将在下篇文章中继续讨论。