UNPKG

museaikit

Version:

A powerful music-focused AI toolkit

91 lines 4.06 kB
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