我有4个音符在我的音调JS应用程序中播放,并想改变第三个音符是其他的东西,而交通工具目前正在播放。下面是我的代码:
JS:
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:
<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
发布于 2020-11-11 00:47:51
这是相当笨拙的修复它现在的结构方式。麻烦的是,您添加的每个笔记都在它自己的循环中,每当您调用scheduleRepeat时,这个循环就会开始……你必须修正原始循环和新循环之间的偏移量,这看起来有点棘手。
我建议您只调用scheduleRepeat一次,并让回调读取您存储的笔记列表。这样,您只需替换或更改其中一个注释,下一次就会更改它,并且不会有任何时间问题。我认为这将意味着在你的笔记模式中包括音调。
https://stackoverflow.com/questions/64772505
复制相似问题