Merge pull request #2190 from rixnobis/psm-user-events

midi2psm: turn tag:payload cue points into PSM USER events
This commit is contained in:
Rix
2026-10-09 10:17:36 -07:00
committed by GitHub
2 changed files with 26 additions and 2 deletions
+3 -2
View File
@@ -59,6 +59,7 @@ enum MidiMeta : uint8_t {
MIDI_META_COPYRIGHT = 0x02,
MIDI_META_TRACK_NAME = 0x03,
MIDI_META_MARKER = 0x06,
MIDI_META_CUE_POINT = 0x07,
MIDI_META_END_OF_TRACK = 0x2F,
MIDI_META_TEMPO = 0x51,
};
@@ -302,8 +303,8 @@ inline void MidiFile::parseTrack(PCSX::IO<PCSX::File> track) {
uint8_t b2 = track->byte();
ev.tempo = (b0 << 16) | (b1 << 8) | b2;
events.push_back(ev);
} else if (metaType == MIDI_META_MARKER || metaType == MIDI_META_TEXT || metaType == MIDI_META_TRACK_NAME ||
metaType == MIDI_META_COPYRIGHT) {
} else if (metaType == MIDI_META_MARKER || metaType == MIDI_META_CUE_POINT || metaType == MIDI_META_TEXT ||
metaType == MIDI_META_TRACK_NAME || metaType == MIDI_META_COPYRIGHT) {
// Text-based meta events
MidiEvent ev = {};
ev.absoluteTick = absTick;
+23
View File
@@ -18,6 +18,7 @@
***************************************************************************/
#include <algorithm>
#include <charconv>
#include <cmath>
#include <cstdint>
#include <cstring>
@@ -55,6 +56,7 @@ using PCSX::MidiConverter::MIDI_CC_VOLUME;
using PCSX::MidiConverter::MIDI_DRUM_CHANNEL;
using PCSX::MidiConverter::MIDI_META;
using PCSX::MidiConverter::MIDI_META_COPYRIGHT;
using PCSX::MidiConverter::MIDI_META_CUE_POINT;
using PCSX::MidiConverter::MIDI_META_MARKER;
using PCSX::MidiConverter::MIDI_META_TRACK_NAME;
using PCSX::MidiConverter::MIDI_META_TEMPO;
@@ -92,6 +94,7 @@ enum PsmEventType : uint8_t {
PSM_TEMPO_CHANGE = 0x0A,
PSM_LOOP_POINT = 0x0B,
PSM_END = 0x0C,
PSM_USER = 0x0D,
PSM_LONG_WAIT = 0xFF,
};
@@ -498,6 +501,26 @@ void ConvertContext::generate() {
continue;
}
// A cue point whose text is "tag:payload" becomes a USER event for the program playing the song.
if (mev.type == MIDI_META && mev.data1 == MIDI_META_CUE_POINT) {
std::string_view text = mev.textData;
auto colon = text.find(':');
unsigned tag = 0;
uint32_t payload = 0;
if (colon != std::string_view::npos) {
auto end = text.data() + colon;
auto [p1, e1] = std::from_chars(text.data(), end, tag);
auto [p2, e2] = std::from_chars(end + 1, text.data() + text.size(), payload);
if (e1 == std::errc() && p1 == end && e2 == std::errc() && p2 == text.data() + text.size() &&
tag <= 255) {
emitEvent(PSM_USER, tag, payload, mev.absoluteTick);
continue;
}
}
fmt::print(stderr, "Ignoring cue point \"{}\" at tick {}: expected tag:payload\n", text, mev.absoluteTick);
continue;
}
if (mev.type == MIDI_META) continue;
if (mev.type == MIDI_PROGRAM_CHANGE) {