字节拍是制作lo音乐的一种有趣的方式。我想使用WebAudio API自己做一些音乐。以下是我的当前代码:
const sampleRate = 8000;
const frameCount = sampleRate * 5;
const audioCtx = new AudioContext({ sampleRate: sampleRate });
const src = audioCtx.createBufferSource();
const buf = audioCtx.createBuffer(1, frameCount, sampleRate);
buf.getChannelData(0).set(buf.getChannelData(0).map((_, t) => {
return (Math.sin(t / 10 + Math.sin(t * Math.pow(2, t >> 10)))) * 64 + 128;
}));
src.buffer = buf;
src.connect(audioCtx.destination);
src.start(0, 0, 100);
console.log('Reached the end :/');这个解决方案的问题是,我必须创建一个巨大的缓冲区,它必须保存在内存中。我希望有一种动态的方式来设置声音的振幅,以节省内存。
字节节拍将是整个音乐创作,可以是相当长的。因此,帧数可能会变得相当大。
有人能给我建议一下怎么做吗?使用其他库是一种选择,但我更愿意避免这种情况。
发布于 2019-11-26 17:23:16
这听起来是AudioWorklet的一个很好的用例。在使用AudioWorklet时,一次只需提供128个样本。出于性能原因,它在另一个线程上运行。这使得它的代码更加复杂。下面是一个基本示例,它使用动态创建的URL来加载AudioWorklet的代码。
const play = async () => {
const audioContext = new AudioContext({ sampleRate: 8000 });
const source = `registerProcessor(
'byte-beats-processor',
class extends AudioWorkletProcessor {
process (_, [ output ]) {
for (let i = 0; i < 128; i += 1) {
const t = currentFrame + i;
output[0][i] = Math.sin(t);
}
return true;
}
}
);`
const blob = new Blob([ source ], { type: 'application/javascript' });
const url = URL.createObjectURL(blob);
await audioContext.audioWorklet.addModule(url);
const audioWorkletNode = new AudioWorkletNode(audioContext, 'byte-beats-processor');
audioWorkletNode.connect(audioContext.destination);
};
play();当然,使用Math.sin(t)只是一个例子。你可能想用更有趣的东西来代替它。
AudioWorklet目前只能在Chrome上使用。这意味着您仍然需要对其他浏览器使用不推荐的ScriptProcessorNode,或者您可以使用标准化-音频上下文这样的多边形填充,它允许您对所有浏览器使用相同的代码。
https://stackoverflow.com/questions/59052136
复制相似问题