微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

以秒为单位为 Tone.js 提供音符和持续时间数组的最简单方法是什么?

如何解决以秒为单位为 Tone.js 提供音符和持续时间数组的最简单方法是什么?

我想给 Tone.js 一个音符列表和每个音符对应的持续时间,并让它播放序​​列。据我所知,没有简单的方法可以做到这一点。

在下面,对应的时间值不是我输入的(即0.25、0.5、0.25),如console.log所示:

var part = new Tone.Part(function(time,note){
    console.log(time);
    console.log(note);
    synth.triggerAttackRelease(note,time);
},[[0.25,"C2"],[0.5,"C3"],[0.25,"G2"]]);

part.start(0).loop = false;
Tone.Transport.start();

如何给 Tone.js 注释和对应的毫秒播放?

解决方法

我不熟悉 Tone.js,所以可能有更好的方法来做到这一点。您使用的数组简写的 official example 似乎不起作用,因此可能是库问题。

至于您想要实现的目标,我出于好奇而摆弄它,这是我得出的结论:

function timeFromDurations(value,i,arr) {
  const prevTime = arr[i - 1]?.time;
  value.time = prevTime + arr[i - 1]?.duration || 0;
  return value;
}

const notesAndDurations = [
  { note: 'C3',duration: .25 },{ note: 'C4',duration: .5 },{ note: 'G2',duration: 1 },].map(timeFromDurations);
console.log(notesAndDurations);

const synth = new Tone.Synth().toDestination();
// use an array of objects as long as the object has a "time" attribute
const part = new Tone.Part((time,value) => {
  // the value is an object which contains both the note and the velocity
  synth.triggerAttackRelease(value.note,value.duration,time);
},notesAndDurations).start(0);
Tone.Transport.start();

这个想法是你需要根据上一个音符的开始时间+持续时间来设置每个音符的开始时间。这消除了手动设置开始时间(非可选)的需要。

编辑

对于持续时间和音符在单独数组中的第二种情况,您可以使用以下 reduce 函数:

const notes = ['C3','C4','G2'];
const durations = [0.25,0.5,1];

const noteDurationTime = notes.reduce((acc,note,i) => {
  const prevTime = acc[i - 1]?.time;
  const time = prevTime + acc[i - 1]?.duration || 0;
  const duration = durations[i];

  acc.push({ note,duration,time });
  return acc;
},[]);

想法是一样的,您正在构建一个具有所有所需属性(音符、持续时间、时间)的对象数组,但这次来自不同的来源(音符数组和持续时间数组)。
您要确保这两个数组的长度相同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。