museaikit
Version:
A powerful music-focused AI toolkit
91 lines • 4.06 kB
JavaScript
import { MAX_MIDI_PITCH, MIN_MIDI_PITCH, MIN_NOTE_LENGTH } from '../constants';
import * as sequences from '../sequences';
export class BaseVisualizer {
noteSequence;
config;
height;
width;
parentElement;
constructor(sequence, config = {}) {
const isQuantized = sequences.isQuantizedSequence(sequence);
const qpm = (sequence.tempos && sequence.tempos.length > 0) ?
sequence.tempos[0].qpm : undefined;
this.noteSequence = isQuantized ?
sequences.unquantizeSequence(sequence, qpm) : sequence;
const defaultPixelsPerTimeStep = 30;
this.config = {
noteHeight: config.noteHeight || 6,
noteSpacing: config.noteSpacing || 1,
pixelsPerTimeStep: config.pixelsPerTimeStep || defaultPixelsPerTimeStep,
noteRGB: config.noteRGB || '8, 41, 64',
activeNoteRGB: config.activeNoteRGB || '240, 84, 119',
minPitch: config.minPitch,
maxPitch: config.maxPitch,
};
const size = this.getSize();
this.width = size.width;
this.height = size.height;
}
updateMinMaxPitches(noExtraPadding = false) {
if (this.config.minPitch && this.config.maxPitch) {
return;
}
if (this.config.minPitch === undefined) {
this.config.minPitch = MAX_MIDI_PITCH;
}
if (this.config.maxPitch === undefined) {
this.config.maxPitch = MIN_MIDI_PITCH;
}
for (const note of this.noteSequence.notes) {
this.config.minPitch = Math.min(note.pitch, this.config.minPitch);
this.config.maxPitch = Math.max(note.pitch, this.config.maxPitch);
}
if (!noExtraPadding) {
this.config.minPitch -= 2;
this.config.maxPitch += 2;
}
}
getSize() {
this.updateMinMaxPitches();
const height = (this.config.maxPitch - this.config.minPitch) * this.config.noteHeight;
const endTime = this.noteSequence.totalTime;
if (!endTime) {
throw new Error('The sequence you are using with the visualizer does not have a ' +
'totalQuantizedSteps or totalTime ' +
'field set, so the visualizer can\'t be horizontally ' +
'sized correctly.');
}
const width = (endTime * this.config.pixelsPerTimeStep);
return { width, height };
}
getNotePosition(note, noteIndex) {
const duration = this.getNoteEndTime(note) - this.getNoteStartTime(note);
const x = (this.getNoteStartTime(note) * this.config.pixelsPerTimeStep);
const w = Math.max(this.config.pixelsPerTimeStep * duration - this.config.noteSpacing, MIN_NOTE_LENGTH);
const y = this.height -
((note.pitch - this.config.minPitch) * this.config.noteHeight);
return { x, y, w, h: this.config.noteHeight };
}
scrollIntoViewIfNeeded(scrollIntoView, activeNotePosition) {
if (scrollIntoView && this.parentElement) {
const containerWidth = this.parentElement.getBoundingClientRect().width;
if (activeNotePosition >
(this.parentElement.scrollLeft + containerWidth)) {
this.parentElement.scrollLeft = activeNotePosition - 20;
}
}
}
getNoteStartTime(note) {
return Math.round(note.startTime * 100000000) / 100000000;
}
getNoteEndTime(note) {
return Math.round(note.endTime * 100000000) / 100000000;
}
isPaintingActiveNote(note, playedNote) {
const isPlayedNote = this.getNoteStartTime(note) === this.getNoteStartTime(playedNote);
const heldDownDuringPlayedNote = this.getNoteStartTime(note) <= this.getNoteStartTime(playedNote) &&
this.getNoteEndTime(note) >= this.getNoteEndTime(playedNote);
return isPlayedNote || heldDownDuringPlayedNote;
}
}
//# sourceMappingURL=base_visualizer.js.map