无法切换ToneJS振荡器的start/ stop

问题描述

我将一些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()函数将按预期启动和停止。

但是,fmOsc2fmOsc3函数将在我切换开始时启动,但在我切换停止时不会终止。

作为参考,以下是HTML的外观:<div class="trackPlay" id="play-stop-toggle" onclick="togglePlay()">PLAY</div>

如何获取fmOsc2fmOsc3函数来切换按钮状态?

解决方法

音调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] ...