JS AudioContext 接口:我这样做对吗?

JS AudioContext Interface: Am I doing this right?

我有以下功能:

var PE_AudioManager_playSe = AudioManager.playSe;
AudioManager.playSe = function(se) {

    if (se.name.substring(0,5) === `data:`) {

        let audioContext = new (window.AudioContext || window.webkitAudioContext)();

        let gainNode = audioContext.createGain();
        gainNode.gain.value = (se.volume / 100) || 0;

        let panNode = audioContext.createStereoPanner();
        panNode.pan.value = (se.pan / 100) || 0;

        let source = audioContext.createBufferSource();
        audioContext.decodeAudioData(se.name.split(`,`)[1].base64ToArrayBuffer(), function(buffer) {
            source.buffer = buffer;
            source.connect(gainNode);
            source.connect(panNode);
            source.connect(audioContext.destination);
            source.detune.value = (se.pitch - 100);
            source.start(0);
         });

    } else {

        PE_AudioManager_playSe.call(this,se);
    };

};

它是现有函数的别名,处理音频音效的播放。如果源对象的 .name 属性 是数据 URI / base64 而不是文件名,则此别名 "intercepts" 例程并使用 AudioContext 接口播放声音。

音效播放没有问题,除了我不认为我在做平移 (.createStereoPanner) 或音量 (.createGain) 正确 - 我不认为如果我调整声像或音量我会听到什么不同。但我可能错了/疯了。

这段代码看起来正确吗?有人能指出我正确的方向吗?提前谢谢你。

Gain- 和 PannerNodes 有最小值和最大值。控制您的输入,以便遵守这些范围。但问题出在其他地方。

const ctx = new AudioContext();
const gainNode = ctx.createGain();
const panNode = ctx.createStereoPanner();

console.log(gainNode.gain.minValue, gainNode.gain.maxValue);
console.log(panNode.pan.minValue, panNode.pan.maxValue);

节点的连接很关键。对我有帮助的是把它看成是一把必须连接电线的吉他(或任何其他电子乐器)。一根电线从吉他连接到增益踏板,那根电线连接到声像踏板,那根电线连接到放大器以输出信号。

您的节点也是如此。将 source(吉他)连接到 gainNode(增益踏板),然后将 gainNode 连接到 panNode(声像踏板),将 panNode 连接到 audioContext.destination(放大器)。

audioContext.decodeAudioData(se.name.split(`,`)[1].base64ToArrayBuffer(), function(buffer) {
    source.buffer = buffer;
    source.connect(gainNode);
    gainNode.connect(panNode);
    panNode.connect(audioContext.destination);
    source.detune.value = (se.pitch - 100);
    source.start(0);
});

真的试着想象一下。如果你想让它更复杂,甚至可以把它画在纸上。

多个节点可以连接到一个目的地。就像有多个来源通过相同的效果流向目的地。您甚至可以根据需要将您的节点连接到不同的目的地或从不同的目的地断开连接,以此制作一个配电盘。

希望这对您有所帮助。如果您有任何疑问或我不清楚,请告诉我。