gpt4 book ai didi

javascript - 使用 WebAudio 制作字节节拍

转载 作者:行者123 更新时间:2023-12-02 22:26:24 25 4
gpt4 key购买 nike

Byte-beats是制作低保真音乐的一种有趣方式。我想使用 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 :/');

我对这个解决方案的问题是我必须创建一个必须保存在内存中的巨大缓冲区。我希望有一种动态的方式来设置声音的幅度以节省内存。

字节节拍将是完整的音乐作品,并且可能会很长。因此,帧数可能会变得相当大。

有人可以建议我如何做到这一点吗?使用其他库是一种选择,但我宁愿避免这种情况。

最佳答案

这听起来像是 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,或者您可以使用诸如 standardized-audio-context 之类的填充代码。它允许您对所有浏览器使用相同的代码。

关于javascript - 使用 WebAudio 制作字节节拍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59052136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com