我有以下片段创建一个振荡器并以特定音量播放。我将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);
}
麻烦的是,增益节点volume
似乎无法正常工作。根据我的理解,0
的增益被静音,1
的增益为100%。但是,在这种情况下,将0
作为gain
值传递只会使声音低沉,而不是完全静音(我希望我能正确解释)。
我做错了什么?有人可以帮忙吗?
答案 0 :(得分:1)
问题是振荡器节点连接到增益节点和目标节点。
+---------------+
| |
oscillator ----+----> gain ----+---> destination
因此,即使增益节点衰减为0,仍有另一条路径到目的地。问题可能在于删除第二个oscillator.connect
行。
oscillator.connect(volume);
//oscillator.connect(context.destination);
答案 1 :(得分:0)
对于任何从Google来这里的人。我通常这样做:
// 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);