使用 WebAudio 播放一系列音符 - 如何异步停止?
Using WebAudio to play a sequence of notes - how to stop asynchronously?
我正在使用 WebAudio 播放一系列音符。我有一个 playNote 功能,效果很好;我将音符频率以及每个音符的开始和停止时间发送给它。序列参数的生成发生在 之前 实际声音开始,这有点令人困惑。该函数只是为每个音符创建一个振荡器。 (我试过其他方法,这是最干净的)。
但我想停止 异步序列(例如,当发生外部事件时)。我试着设置了一个可以用来门控输出的主增益节点,但似乎需要 "inside" 这个功能,所以以后无法控制。如果我尝试关闭函数内的增益对象,那么为时已晚 - 因为开始和停止时间已经传递给函数。
这是我的函数:
function playNote(audioContext,frequency, startTime, endTime, last) {
gainNode = audioContext.createGain(); //to get smooth rise/fall
oscillator = audioContext.createOscillator();
oscillator.frequency.value=frequency;
oscillator.connect(gainNode);
gainNode.connect(analyserScale); //analyser is global
analyserScale.connect(audioContext.destination);
gainNode.gain.exponentialRampToValueAtTime(toneOn, startTime + trf);
gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
oscillator.start(startTime);
oscillator.stop(endTime);
}
感谢任何帮助!
这样做:。解决方案是使用数组跟踪预定的振荡器。
函数现在变为:
变种振荡器= []; //振荡器列表
function playNote(audioContext,frequency, startTime, endTime, last, index) {
gainNode = audioContext.createGain(); //to get smooth rise/fall
oscillator = audioContext.createOscillator();
oscillator.frequency.value=frequency;
oscillator.connect(gainNode);
//keep track of alll the oscs so that they can be switched off if scale is stopped by user
oscs[index] = oscillator;
gainNode.connect(analyserScale); //analyser is global
analyserScale.connect(audioContext.destination);
gainNode.gain.exponentialRampToValueAtTime(toneOn, startTime + trf);
gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
oscillator.start(startTime);
oscillator.stop(endTime);
}
然后编写停止振荡器的代码:
for(let i=0; i<oscs.length; i++) {
if(oscs[i]){
oscs[i].stop(0);
}
}
我正在使用 WebAudio 播放一系列音符。我有一个 playNote 功能,效果很好;我将音符频率以及每个音符的开始和停止时间发送给它。序列参数的生成发生在 之前 实际声音开始,这有点令人困惑。该函数只是为每个音符创建一个振荡器。 (我试过其他方法,这是最干净的)。
但我想停止 异步序列(例如,当发生外部事件时)。我试着设置了一个可以用来门控输出的主增益节点,但似乎需要 "inside" 这个功能,所以以后无法控制。如果我尝试关闭函数内的增益对象,那么为时已晚 - 因为开始和停止时间已经传递给函数。
这是我的函数:
function playNote(audioContext,frequency, startTime, endTime, last) {
gainNode = audioContext.createGain(); //to get smooth rise/fall
oscillator = audioContext.createOscillator();
oscillator.frequency.value=frequency;
oscillator.connect(gainNode);
gainNode.connect(analyserScale); //analyser is global
analyserScale.connect(audioContext.destination);
gainNode.gain.exponentialRampToValueAtTime(toneOn, startTime + trf);
gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
oscillator.start(startTime);
oscillator.stop(endTime);
}
感谢任何帮助!
这样做:
函数现在变为: 变种振荡器= []; //振荡器列表
function playNote(audioContext,frequency, startTime, endTime, last, index) {
gainNode = audioContext.createGain(); //to get smooth rise/fall
oscillator = audioContext.createOscillator();
oscillator.frequency.value=frequency;
oscillator.connect(gainNode);
//keep track of alll the oscs so that they can be switched off if scale is stopped by user
oscs[index] = oscillator;
gainNode.connect(analyserScale); //analyser is global
analyserScale.connect(audioContext.destination);
gainNode.gain.exponentialRampToValueAtTime(toneOn, startTime + trf);
gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
oscillator.start(startTime);
oscillator.stop(endTime);
}
然后编写停止振荡器的代码:
for(let i=0; i<oscs.length; i++) {
if(oscs[i]){
oscs[i].stop(0);
}
}