djipco / webmidi

Tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).
Apache License 2.0
1.54k stars 116 forks source link

SPP MSB and LSB reset to 0 after beat 1024 — not a bug, but driving me crazy! What I'm missing? #442

Closed centomila closed 1 month ago

centomila commented 1 month ago

I'm working on a project written in Svelte (TypeScript) using the awesome WebMidi library. 😉

My project successfully receives SPP (Song Position Pointer) messages and converts them into seconds using the following function:

function sppArrayToTime(midiData: MessageEvent, bpm: number) {
    console.log('SPP message received: ', midiData.data);
    // Extract the LSB and MSB from the array
    const lsb = midiData.data[1]; // Least significant byte
    const msb = midiData.data[2]; // Most significant byte

    console.log({ lsb, msb });

    // Calculate the 14-bit SPP value from the LSB and MSB
    const sppValue = (msb << 7) | lsb; // Combine MSB and LSB to get the SPP value

    // Convert the SPP value to time in seconds
    const timeInSeconds = (sppValue * 60) / Math.round(bpm * 4);

    // Calculate hours, minutes, seconds, and milliseconds as floating-point values
    const hours = timeInSeconds / 3600;
    const minutes = (timeInSeconds % 3600) / 60;
    const seconds = timeInSeconds % 60;
    const milliseconds = (timeInSeconds % 1) * 1000;

    sppData.update((data: SPPData) => ({
        ...data,
        hours,
        minutes,
        seconds,
        milliseconds,
        seekPosition: timeInSeconds,
        secondsOnSPP: timeInSeconds
    }));

}

Everything works fine when the tempo starts from beat 0 up to 1024. However, when I try to start from beat 1025 (which is 34:08 at 120 bpm), both the LSB and MSB are 0.

I suspect this might be due to a byte size limitation, but my understanding and research have reached a dead end.

Is this a known limitation in MIDI? I haven't been able to find any information about it. I've tested with different DAWs and MIDI loop ports, but the issue persists. Is there an obvious workaround I'm missing?

centomila commented 1 month ago

After further research, I found that this behavior is a limitation of the MIDI protocol