首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在播放传输时安排ToneJS事件

在播放传输时安排ToneJS事件
EN

Stack Overflow用户
提问于 2020-11-11 00:09:51
回答 1查看 377关注 0票数 1

我有4个音符在我的音调JS应用程序中播放,并想改变第三个音符是其他的东西,而交通工具目前正在播放。下面是我的代码:

JS:

代码语言:javascript
复制
import { Transport, start, Sampler } from "tone";

const notesToPlay = [
  {
    timing: 0.25,
    sameAsLast: false,
    duration: 0.1,
    velocity: 1
  },
  {
    timing: 0.5,
    sameAsLast: true,
    duration: 0.1,
    velocity: 1
  },
  {
    timing: 0.75,
    sameAsLast: false,
    duration: 0.1,
    velocity: 1
  },
  {
    timing: 1,
    sameAsLast: false,
    duration: 0.2,
    velocity: 1
  }
];

var eventIds = [];

(function () {
  function playSynth() {
    Transport.start();
    start();
  }

  const sampler = new Sampler({
    urls: {
      A1: "A1.mp3",
      A2: "A2.mp3"
    },
    baseUrl: "https://tonejs.github.io/audio/casio/",
    onload: () => {
      loadNotes();
    }
  }).toDestination();

  function loadNotes() {
    notesToPlay.forEach((n) => {
      const eventId = Transport.scheduleRepeat((time) => {
        sampler.triggerAttackRelease(
          ["A1"],
          n.duration,
          n.timing + time,
          n.velocity
        );
      }, 4);

      eventIds.push(eventId);
    });
  }

  document.getElementById("play").addEventListener("click", function () {
    playSynth();
  });

  document.getElementById("stop").addEventListener("click", function () {
    Transport.stop();
  });

  document.getElementById("replace").addEventListener("click", function () {
    const arrayIdxToReplace = 2;
    Transport.clear(eventIds[arrayIdxToReplace]);
    const note = notesToPlay[arrayIdxToReplace];
    Transport.scheduleRepeat((time) => {
      sampler.triggerAttackRelease(
        ["D1"],
        note.duration,
        note.timing + time,
        note.velocity
      );
    }, 4);
  });
})();

HTML:

代码语言:javascript
复制
<div id="app">
  <button id="play">play me</button>
  <button id="stop">stop</button>
  <button id="replace">Replace 3rd note</button>
</div>

当我点击替换第三个音符按钮时,它会删除旧的事件,这是好的,但当它在其中安排新的事件时,它与旧的第三个音符的位置不同步。

解决这个问题的一种方法是停止传输,然后单击以替换第三个音符,然后再次单击播放,但是我希望在传输仍在播放的情况下能够这样做。我哪里错了?

这是一个演示这个问题的小提琴:

https://codesandbox.io/s/tonejs-forked-fxhzm?file=/src/index.js:0-1643

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-11 00:47:51

这是相当笨拙的修复它现在的结构方式。麻烦的是,您添加的每个笔记都在它自己的循环中,每当您调用scheduleRepeat时,这个循环就会开始……你必须修正原始循环和新循环之间的偏移量,这看起来有点棘手。

我建议您只调用scheduleRepeat一次,并让回调读取您存储的笔记列表。这样,您只需替换或更改其中一个注释,下一次就会更改它,并且不会有任何时间问题。我认为这将意味着在你的笔记模式中包括音调。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64772505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档