Javascript Tone.js Tone.Transport.scheduleRepeat 循环逻辑错误

Javascript loop logic error with Tone.js Tone.Transport.scheduleRepeat

只是玩玩 Tone.js 并不太了解 Tone.Transport.scheduleRepeat

的细节

当多次使用一个功能时,声音开始失真并且时序发生变化。

我正在关注这个 tutorial, and trying to duplicate within Codepen

我的 "playScore" 函数每次 运行 都会改变,尽管索引计数器被重置为零。

<!-- HTML -- >
<button onclick="playScore()">
  TEST SCORE
</button>



//js
function playScore() {
  console.clear();
  console.log("TEST SCORE");
  const synthScore = new Tone.Synth
  synthScore.oscillator.type = 'sine';
  synthScore.toMaster();
  //synth.triggerAttackRelease ('E4', '8n' );  
  const notes = [
    'C4', 'E4', 'G4',
    'C5', 'E5', 'G5' 
  ];

  let index = 0;

  Tone.Transport.scheduleRepeat(time => {
    repeat(time);
  }, "8n");

  function repeat(time) {
    console.log("index: " + index + " notes.length: " + notes.length);
    let note = notes[index % notes.length];
    synthScore.triggerAttackRelease(note, '8n', time);
    console.log("note:" + note + " time: " + time);
    index++;
  }

  Tone.Transport.start();

  setTimeout(() => {
    Tone.Transport.stop();
  }, 5000)

  // Tone.Transport.bpm.value = 120  

我希望相同的音符以相同的顺序以相同的方式演奏。

相反,我看到它在每次迭代中都会发生变化。

我发现这是因为显然,我有 2 个索引变量和逻辑,函数内有局部实例,函数外有全局实例。

找到一个简单的解决方案。 按钮功能 "playScore" 只是启动和停止 Tone.Transport 音符在它们停止的地方开始拾取,而不是从数组的顶部开始。

console.clear();

  const synthScore = new Tone.Synth
  synthScore.oscillator.type = 'sine';
  synthScore.toMaster();
  //synth.triggerAttackRelease ('E4', '8n' );  
  const notes = [
    'C4', 'E4', 'G4',
    'C5', 'E5', 'G5' 
  ]; 
  let speed = '8n'
  let index = 0;

  Tone.Transport.scheduleRepeat(time => {
    repeat(time);
  }, "8n");

  let repeat = ( time ) => {
    console.log("index: " + index + " notes.length: " + notes.length);
    let note = notes[index % notes.length];
    //console.log(note)
    synthScore.triggerAttackRelease(note, '8n', time);
    addOutput(note, '8n')  
    index++;
  }  


function playScore() {
  console.log("TEST SCORE");
  Tone.Transport.start();

  setTimeout(() => {
    Tone.Transport.stop();
  }, 5000);
  // Tone.Transport.bpm.value = 120  
}