问题描述
我将一些JS与tonejs库拼凑在一起,以打开/关闭一些声音。
function togglePlay() {
const status = Tone.Transport.state; // Is either 'started','stopped' or 'paused'
const element = document.getElementById("play-stop-toggle");
if (status == "started") {
element.innerText = "PLAY";
Tone.Transport.stop()
} else {
element.innerText = "STOP";
Tone.Transport.start()
}
document.querySelector('#status').textContent = status;
}
var filter = new Tone.Filter({
type: 'lowpass',Q: 12
}).toMaster()
var fmOsc = new Tone.AMOscillator("Ab3","sine","square").toMaster()
var fmOsc2 = new Tone.AMOscillator("Cb3","square").toMaster()
var fmOsc3 = new Tone.AMOscillator("Eb3","square").toMaster()
var synth = new Tone.Membranesynth().toMaster()
//create a loop
var loop = new Tone.Loop(function(time){
// synth.triggerAttackRelease("A1","8n",time)
// fmOsc.start()
fmOsc2.start()
fmOsc3.start();
},"4n")
//play the loop between 0-2m on the transport
loop.start(0)
// loop.start(0).stop('2m')
在loop
里面,我有一个鼓点,目前我已经注释掉了。注释后,togglePlay()
函数将按预期启动和停止。
但是,fmOsc2
和fmOsc3
函数将在我切换开始时启动,但在我切换停止时不会终止。
作为参考,以下是HTML的外观:<div class="trackPlay" id="play-stop-toggle" onclick="togglePlay()">PLAY</div>
解决方法
音调Transport并不能以这种方式用于启动或停止振荡器(当然,它可以启动/停止振荡器,但是我不认为它在做您想要的事情要做):-)
如果在传递给console.log
的函数中添加Tone.Loop
,将会看到它被重复调用,即,您一次又一次地调用fmOsc.start()
。 (不过在Loop
中重复敲鼓确实很有意义)
调用Tone.Transport.stop()
不会停止振荡器-它只会停止Loop
/传输功能(即“计时”)。鼓声很明显-在用户界面中按Stop
会杀死鼓声,但振荡器会不断振荡。
最简单/最直接(也是唯一的)停止振荡器的方法是在振荡器上调用.stop()
:
if (status == "started") {
element.innerText = "PLAY";
Tone.Transport.stop()
fmOsc2.stop()
fmOsc3.stop()
} else {
// ... [snip] ...