javascript 尝试在html中创建一个播放按钮,可以重复按下该按钮来播放一组音符,(使用Tone.js)

gcuhipw9  于 2023-02-18  发布在  Java
关注(0)|答案(1)|浏览(149)

我有这个代码在html:

<script src="https://unpkg.com/tone"></script>

<button id="tunebtn">Play Notes</button>

<script>
  let synth = new Tone.Synth().toDestination();
  let notes = [
    { note: "C4", duration: "8n" , time: 0},
    { note: "D4", duration: "8n" , time: 0.5},
    { note: "E4", duration: "8n", time: 1}
  ];
  let time = 0;

  const playNotes = () => {
    notes.forEach(note => {
      synth.triggerAttackRelease(note.note, note.duration, note.time);
    });
  };

  document.getElementById("tunebtn").addEventListener("click", playNotes);
</script>

我可以按下按钮一次,以便播放数组“note”中的这三个音符。但当我再次按下它时,按钮停止工作,什么也不播放。你知道是什么导致了这一点,以及如何修复这一点吗?

mrfwxfqh

mrfwxfqh1#

是的!我找到了一个修复方法!我在Github上查看了这个链接,那里有人遇到了类似的问题:https://github.com/Tonejs/Tone.js/issues/281
代码执行时,在调用第一个triggerAttackRelease之前会有一个延迟,此时第一个音符的预定时间0已经过去,不能进行追溯调度,导致第一个音符可能突然被第二个音符打断或完全压制。
使用时间常数可以解决这个问题。下面是我的解决方案:

<script src="https://unpkg.com/tone"></script>

<button id="tunebtn">Play Notes</button>

<script>
  let synth = new Tone.Synth().toDestination();
  let notes = [
    { note: "C4", duration: "8n" , time: 0},
    { note: "D4", duration: "8n" , time: 0.5},
    { note: "E4", duration: "8n", time: 1}
  ];

  const playNotes = () => {
    notes.forEach(note => {
        const now = Tone.now()
      synth.triggerAttackRelease(note.note, note.duration, note.time + now);
    });
  };

  document.getElementById("tunebtn").addEventListener("click", playNotes);
</script>

相关问题