|
2 | 2 | import { onMount, onDestroy } from 'svelte'; |
3 | 3 | import { editorStore } from '$lib/stores/editor'; |
4 | 4 | import { getToolkit } from '$lib/verovio/toolkit'; |
5 | | - import { MIDI, MusicNotation, MidiPlayer } from '@k-l-lambda/music-widgets'; |
| 5 | + import { MIDI, MidiPlayer, MusicNotation } from '@k-l-lambda/music-widgets'; |
6 | 6 | import { MidiAudio } from '@k-l-lambda/music-widgets/dist/musicWidgetsBrowser.es.js'; |
7 | 7 |
|
8 | 8 | let isPlaying = false; |
9 | 9 | let currentTime = 0; |
10 | 10 | let duration = 0; |
11 | 11 | let midiPlayer: any = null; |
12 | | - let midiNotation: any = null; |
| 12 | + let midiData: any = null; |
13 | 13 | let isAudioLoaded = false; |
14 | 14 |
|
15 | 15 | onMount(async () => { |
|
39 | 39 | bytes[i] = binaryString.charCodeAt(i); |
40 | 40 | } |
41 | 41 |
|
42 | | - const midiData = MIDI.parseMidiData(bytes.buffer); |
43 | | - midiNotation = MusicNotation.Notation.parseMidi(midiData); |
44 | | - |
| 42 | + const rawMidiData = MIDI.parseMidiData(bytes.buffer); |
| 43 | + // Parse to notation and add default tempo if missing |
| 44 | + const notation = MusicNotation.Notation.parseMidi(rawMidiData); |
| 45 | + if (!notation.tempos || notation.tempos.length === 0) { |
| 46 | + // Add default tempo (120 BPM = 500000 microseconds per beat) |
| 47 | + notation.tempos = [{ tempo: 500000, tick: 0, time: 0 }]; |
| 48 | + } |
| 49 | + midiData = notation; |
| 50 | +
|
45 | 51 | if (midiPlayer) { |
46 | 52 | midiPlayer.dispose(); |
47 | 53 | } |
48 | 54 |
|
49 | | - midiPlayer = new MidiPlayer(midiNotation, { |
| 55 | + midiPlayer = new MidiPlayer(midiData, { |
50 | 56 | cacheSpan: 400, |
51 | 57 | onMidi: (data: any, timestamp: number) => { |
52 | 58 | switch (data.subtype) { |
53 | 59 | case 'noteOn': |
54 | | - MidiAudio.noteOn(data.channel, data.noteNumber, data.velocity, timestamp / 1000); |
| 60 | + MidiAudio.noteOn(data.channel, data.noteNumber, data.velocity, timestamp); |
55 | 61 | break; |
56 | 62 | case 'noteOff': |
57 | | - MidiAudio.noteOff(data.channel, data.noteNumber, timestamp / 1000); |
| 63 | + MidiAudio.noteOff(data.channel, data.noteNumber, timestamp); |
58 | 64 | break; |
59 | 65 | case 'programChange': |
60 | 66 | MidiAudio.programChange(data.channel, data.programNumber); |
|
75 | 81 | } |
76 | 82 | }); |
77 | 83 |
|
78 | | - duration = midiNotation.endTime; |
| 84 | + duration = midiData.endTime; |
79 | 85 | } catch (error) { |
80 | 86 | console.error('Failed to initialize player:', error); |
81 | 87 | } |
|
0 commit comments