0

我正在使用 ToneJS 的网站上创建多个切换按钮。基本上,我希望不同的按钮播放不同的曲目。

我已经像这样创建了两个相同的按钮。

按钮 1:

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;
}

按钮 2:

function togglePlay2() {
  const status = Tone.Transport.state; // Is either 'started', 'stopped' or 'paused'
  const element = document.getElementById("play-stop-toggle2");
  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 synth = new Tone.MembraneSynth().toMaster()

//create a loop
var loop = new Tone.Loop(function(time){
    synth.triggerAttackRelease("A1", "8n", time)
}, "2n")


//play the loop between 0-2m on the transport
loop.start(0)
// loop.start(0).stop('2m')

我将如何将 、 和 嵌套在其中filtersynth以便loopfunction togglePlay()可以根据切换的按钮定义不同的声音?

4

2 回答 2

0

这是一个同时允许多个音调的解决方案。如果您希望一种音调开始停止当前正在运行的任何其他音调,则必须进行更多的状态管理。此代码让您了解如何将特定于上下文的配置绑定到单击处理程序以专门处理按钮的行为。

但是,我不知道Tone,并且您的代码没有完整的设置,因此您可能需要做更多的事情来为每个处理程序提供自己的 Tone 实例。

function createTogglePlayClickhandler(config) {
    var filter = new Tone.Filter(config.filter).toMaster()
    var synth = config.synth
      //create a loop
    var loop = config.loop
    const element = document.getElementById(elementId);

    return function togglePlay() {
        const status = Tone.Transport.state; // Is either 'started', 'stopped' or 'paused'
        
        if (status == "started") {
        element.innerText = "PLAY";
        Tone.Transport.stop()
        } else {
        element.innerText = "STOP";
        Tone.Transport.start()
        }
    
        document.querySelector('#status').textContent = status;
    }
}

// Generate click handlers
createTogglePlayClickhandler({ 
    elementId: "play-stop-toggle",
    filter: {
        type: 'lowpass',
        Q: 12
      },
    synth: new Tone.MembraneSynth().toMaster(),
    loop: new Tone.Loop(function(time){
        synth.triggerAttackRelease("A1", "8n", time)
    }, "2n")
});
createTogglePlayClickhandler({ 
    elementId: "play-stop-toggle2",
    filter: {
        type: 'lowpass',
        Q: 12
      },
    synth: new Tone.MembraneSynth().toMaster(),
    loop: new Tone.Loop(function(time){
        synth.triggerAttackRelease("A1", "8n", time)
    }, "2n")
});

看起来你只有一个状态元素,所以我认为你想要的行为是一次一个音调?因此,如果我单击 Tone A,然后单击 Tone B,Tone B 应该开始,而 Tone A 应该停止?

或者你想要多音色?

于 2020-07-24T06:41:06.440 回答
0

这样做有什么问题吗?

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";
    var filter = new Tone.Filter({
       type: 'lowpass',
       Q: 12
    }).toMaster()

    var synth = new Tone.MembraneSynth().toMaster()

    //create a loop
    var loop = new Tone.Loop(function(time){
        synth.triggerAttackRelease("A1", "8n", time)
    }, "2n")

    //play the loop between 0-2m on the transport
    loop.start(0)
    // loop.start(0).stop('2m')
    Tone.Transport.start()
  }

  document.querySelector('#status').textContent = status;
}
于 2020-07-24T05:53:45.260 回答