import {Note, parseNote, PITCH_CLASSES} from "./note"; import {toRawDuration} from './duration'; export interface Playable { key?: number, start: number, end: number, startIndex: number, endIndex: number, } export interface SongData { playables: T[], duration: number, index: number, } export * from './note' export * from './duration' export const toPlayable = (n: Note, tempo: number) => { const rawDurationBase = toRawDuration(n.duration, tempo) const duration = n.dotted ? rawDurationBase * 1.5 : rawDurationBase const pitchClassIndex = PITCH_CLASSES.indexOf(n.pitchClass!) if (!isNaN(pitchClassIndex) && 0 <= pitchClassIndex && pitchClassIndex <= 11 && !isNaN(n.octave!)) { return { duration, key: pitchClassIndex + (12 * (n.octave! + 1)) } } return { duration, } } export const parseSong = (s: string, tempo: number) => { return s.split(' ').reduce( (state, n, i, nn) => { let note try { note = parseNote(n) } catch { return state } const playable = toPlayable(note, tempo) return { ...state, playables: [ ...state.playables, { key: playable.key, start: state.duration, end: state.duration + playable.duration, startIndex: state.index, endIndex: state.index + n.length } ], duration: ( i < nn.length - 1 ? state.duration + playable.duration : state.duration + playable.duration + 100 ), index: state.index + n.length + 1 } as SongData }, { playables: [] as T[], duration: 100, index: 0, } ) }