museaikit
Version:
A powerful music-focused AI toolkit
95 lines • 3 kB
JavaScript
import * as Tone from 'tone';
const QUARTERS_PER_BAR = 4;
export class MetronomeCallbackObject {
}
export class Metronome {
clicksPerQuarter = 1;
muted = false;
loClick = new Tone
.MembraneSynth({
pitchDecay: 0.008,
envelope: { attack: 0.001, decay: 0.3, sustain: 0 },
})
.toDestination();
hiClick = new Tone
.MembraneSynth({
pitchDecay: 0.008,
envelope: { attack: 0.001, decay: 0.3, sustain: 0 },
})
.toDestination();
loClickNote = 'c5';
hiClickNote = 'g5';
ticking = false;
startedAt = null;
step = -1;
callbackObject;
constructor(callbackObject, clicksPerQuarter = 1) {
this.reset();
this.callbackObject = callbackObject;
this.clicksPerQuarter = clicksPerQuarter;
}
isTicking() {
return this.ticking;
}
getStartedAt() {
return this.startedAt;
}
getOffsetTime() {
return Tone.immediate() - this.startedAt;
}
start(bpm = 120) {
this.reset();
this.ticking = true;
if (!this.callbackObject.click) {
this.callbackObject.click = () => { };
}
if (!this.callbackObject.quarter) {
this.callbackObject.quarter = () => { };
}
if (!this.callbackObject.bar) {
this.callbackObject.bar = () => { };
}
let bar = 0;
const clicksInBar = QUARTERS_PER_BAR * this.clicksPerQuarter;
Tone.Transport.scheduleRepeat((time) => {
if (!this.startedAt) {
this.startedAt = time;
}
const offsetTime = time - this.startedAt;
this.step++;
const clickInBar = this.step % clicksInBar;
const clickInQuarter = Math.floor(clickInBar / this.clicksPerQuarter);
const quarter = clickInBar % this.clicksPerQuarter;
this.callbackObject.click(offsetTime, clickInBar);
if (quarter === 0) {
this.callbackObject.quarter(offsetTime, clickInQuarter);
}
if (!this.muted) {
if (clickInBar === 0) {
this.hiClick.triggerAttack(this.hiClickNote, time, 0.1);
}
else {
this.loClick.triggerAttack(this.loClickNote, time, 0.1);
}
}
if (clickInBar === 0) {
this.callbackObject.bar(offsetTime, bar);
bar++;
}
}, `${clicksInBar}n`);
Tone.Transport.bpm.value = bpm;
Tone.Transport.start();
}
stop() {
this.ticking = false;
Tone.Transport.cancel();
Tone.Transport.stop();
}
reset() {
this.muted = false;
this.ticking = false;
this.step = -1;
this.startedAt = null;
}
}
//# sourceMappingURL=metronome.js.map