javascript振荡器音量未完全正常工作

Cli*_*iff 2 javascript audio javascript-oscillator

我有以下代码段,它创建了一个振荡器并以一定的音量播放。我将oscillator变量保留在函数范围之外,以便我可以在需要时用其他函数停止它。

var oscillator = null;
var isPlaying = false;

function play(freq, gain) {

    //stop the oscillator if it's already playing
    if (isPlaying) {
        o.stop();
        isPlaying = false;
    }

    //re-initialize the oscillator
    var context = new AudioContext();

    //create the volume node;
    var volume = context.createGain();
    volume.connect(context.destination);
    volume.gain.value = gain;

    //connect the oscillator to the nodes
    oscillator = context.createOscillator();
    oscillator.type = 'sine';
    oscillator.frequency.value = freq;

    oscillator.connect(volume);
    oscillator.connect(context.destination);

    //start playing
    oscillator.start();
    isPlaying = true;

    //log
    console.log('Playing at frequency ' + freq + ' with volume ' + gain);
}
Run Code Online (Sandbox Code Playgroud)

问题是,增益节点volume似乎不像您期望的那样工作。据我了解,增益0为静音,增益1为 100% 音量。但是,在这种情况下,0作为gain值传递只会播放低沉的声音,而不是完全静音(我希望我能正确解释)。

我究竟做错了什么?有人可以帮忙吗?

jak*_*ket 5

问题是振荡器节点连接到增益节点和目标节点。

                +---------------+
                |               |
 oscillator ----+----> gain ----+---> destination
Run Code Online (Sandbox Code Playgroud)

因此,即使增益节点衰减到 0,仍然存在另一条通往目的地的路径。问题可能出在删除第二oscillator.connect行。

oscillator.connect(volume);
//oscillator.connect(context.destination);
Run Code Online (Sandbox Code Playgroud)


San*_*fon 5

对于任何从谷歌掉到这里的人。我通常这样做:

    // I create the class with best available
    var ctxClass = window.audioContext || window.AudioContext || window.AudioContext || window.webkitAudioContext
    // We instance the class, create the context
    var ctx = new ctxClass();
    // Create the oscillator
    var osc = ctx.createOscillator();
    // Define type of wave
    osc.type = 'sine';
    // We create a gain intermediary
    var volume = ctx.createGain();
    // We connect the oscillator with the gain knob
    osc.connect(volume);
    // Then connect the volume to the context destination
    volume.connect(ctx.destination);
    // We can set & modify the gain knob
    volume.gain.value = 0.1;

    //We can test it with some frequency at current time
    osc.frequency.setValueAtTime(440.0, ctx.currentTime);
    if (osc.noteOn) osc.noteOn(0);
    if (osc.start) osc.start();

    // We'll have to stop it at some point
    setTimeout(function () {
        if (osc.noteOff) osc.noteOff(0);
        if (osc.stop) osc.stop();
        // We can insert a callback here, let them know you've finished, may be play next note?
        //finishedCallback();
    }, 5000);
Run Code Online (Sandbox Code Playgroud)