所以我有一个应用程序可以在音乐图表中播放和弦,允许您为歌曲构建背景音轨。我正在使用 Web Audio API(特别是 Howler.js,因为它的实用性和简单性),因为当我尝试使用 HTML5 音频时,它遇到了滞后问题。唯一的问题是,当我调整音频的播放速率时,音调也会发生变化!(这不是 HTML5 的问题,但我不得不再次放弃它)。由于这是一个音乐应用程序,您可以在其中动态更改 BPM 并仍然播放每个和弦,因此需要通过更改播放速率来保持音高。
我最初的解决方案是在更改播放速率后使用 Tone.js 的 PitchShift 效果来“纠正”音高。当我必须提高音高时(当歌曲变慢时)它效果最好,但是当歌曲加速时(因此需要降低音高以保持它)它会稍微走调并且非常金属的声音,即使我添加了一个小的“校正器”。然而,即使提高音高也会产生轻微的金属般的声音,尽管不太明显。
我有几个潜在的解决方案,但老实说,我并不精通音频处理领域,尤其是在网络上。因此,如果可能的话,我想帮助选择解决此问题的最佳解决方案。解决方案包括:
添加另一个 Tone.js 组件/效果,例如 EQ3,并尝试纠正金属声音。不幸的是,如上所述,我不确定应该使用哪种效果(如果有的话)。我试图切换到 .WAV 而不是 .FLAC 看看这是否有所作为,但遗憾的是并没有太大影响。
以某种方式连接 Tone.js GrainPlayer,因为它据称“使您能够独立调整音高和播放速率”,而不必担心在更改速率后必须纠正音高。但是,我知道 GrainPlayer 是一个源并且需要一个 AudioBuffer,并且我不知道如何将 Howl 连接到它或任何东西(Howl 是 Howler 用来播放声音的对象。)Howler 只提供对其 AudioContext 和它的主增益节点。
var chord = new Howl({src:['/A.flac']}); //chord I wish to play
var buffer = Howler.ctx.createBuffer(/*Somehow load the chord into this buffer?*/);
var grain = new Tone.GrainPlayer(buffer); //the GrainPlayer that can do the time stretch w/o pitch shifting
Tone.connect(Howler.masterGain, grain); //somehow connect the master gain node to the GrainPlayer, but I don't know if it works this way or not
grain.toDestination();
- 只需使用上面列出的 GrainPlayer 方法直接加载我的所有声音,然后忘记使用 Howler.js。我可以做到这一点,我唯一的问题是我希望仍然不存在滞后问题(当我使用 HTML5 音频元素时它们是一个问题,所以有可能它不会成为 Tone.js 的问题)。在这方面,我应该将它们保存为 .FLAC 文件吗?还是换成别的?共有 36 个声音文件,当它们是 .FLAC 时,每个文件的大小约为 130KB,但不幸的是,当涉及到网页认为“大型音频文件”时,我没有参考框架。
var grain = new Tone.GrainPlayer('/A.flac'); //direct load, skip using a Howl instance
grain.playbackRate = bpm/120; //will this change the tempo without changing the pitch?
grain.start(); //when I need to play the chord, after adjusting the BPM
如果我遗漏了一些明显的东西,再次道歉,对音频处理来说仍然很新!