做网站前台后台是怎么连接的,长沙网站建设技术,宁波公司排名,信息流投放平台文章目录 背景实现TransportLoop代码 在线尝试 背景
我们看吉他谱时#xff0c;经常看到拍号#xff0c;例如6/8。它的含义是一拍是一个八分音符#xff0c;一小节有六拍。四分音符的时长是一秒#xff0c;即60拍/分钟。基于这样的背景知识#xff0c;我们就可以根据一些… 文章目录 背景实现TransportLoop代码 在线尝试 背景
我们看吉他谱时经常看到拍号例如6/8。它的含义是一拍是一个八分音符一小节有六拍。四分音符的时长是一秒即60拍/分钟。基于这样的背景知识我们就可以根据一些定时循环的包来实现节拍器。
实现
这边依然采用的ToneJs。我们需要认识几个类Transport、Loop。
Transport
Transport是一个计时器类。它有两个属性值得关注bpm和timeSignature。 bpm表示每分钟的拍子数 timeSignature表示拍号用数组表示例如6/8拍表达为[6, 8]。需要注意的是这个属性最后会返回 6 / 8 * 4 3默认值是4即标准的4/4拍。
Loop
Loop是一个循环类用于循环执行一个回调方法我们可以在这个回调中进行语音播放实现打节拍的效果。 需要注意的是如果只是在每一拍都播放一次声音我们是无法区分重音和弱音的因此应该写两个循环一个专门播放重音的拍子一个播放所有的拍子。
代码
templatedivdiv stylemargin: 10pxv-text-field v-modelbpm labelbpm/v-text-fieldv-select v-modeltimeSignature labeltimeSignature :itemstimeSignatureList/v-selectv-btn clickstart{{ isPlaying ? 暂停 : 开始 }}/v-btn/div/div
/templatescript
import { Oscillator, Transport, Loop } from tone;export default {name: Beat,data() {return {bpm: 0,timeSignature: ,timeSignatureList: [2/4, 3/4, 4/4, 3/8, 6/8],isPlaying: false,}},mounted() {this.bpm 120;this.timeSignature 4/4;},watch: {bpm(val) {Transport.bpm.value val;},},beforeUnmount() {this.stop();},methods: {start() {if (this.isPlaying) {this.stop();} else {const osc1 new Oscillator().toDestination();const osc2 new Oscillator().toDestination();const res this.timeSignature.split(/);Transport.timeSignature res.map(a Number(a)); // [6, 8] 返回 6 / 8 * 4 表示 实际拍数和标准拍数的比例// 创建一个每拍触发的事件this.loopA new Loop((time) {osc1.start(time).stop(time 0.1);}, res[1] n).start(0);// 重音时间间隔标准一拍的秒数 *实际拍数 / 标准拍数 实际一拍的秒数this.loopB new Loop((time) {osc2.start(time).stop(time 0.1);}, 60 / this.bpm * Transport.timeSignature).start(0);Transport.start();}this.isPlaying !this.isPlaying;},stop() {Transport?.stop();this.loopA?.stop();this.loopB?.stop();}}
}
/script
在线尝试 这个功能已经集成到了我的个人网站YUERGS中快来试试吧