aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi.cpp19
-rw-r--r--src/midi_sequencer.hpp22
-rw-r--r--src/midi_sequencer_impl.hpp36
3 files changed, 72 insertions, 5 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index 37e0c21..d839399 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -1413,6 +1413,25 @@ ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t tra
#endif
}
+ADLMIDI_EXPORT int adl_setTriggerHandler(struct ADL_MIDIPlayer *device, ADL_TriggerHandler handler, void *userData)
+{
+#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
+ if(!device)
+ return -1;
+ MidiPlayer *play = GET_MIDI_PLAYER(device);
+ if(!play)
+ return -1;
+ MidiSequencer &seq = play->m_sequencer;
+ seq.setTriggerHandler(handler, userData);
+ return 0;
+#else
+ ADL_UNUSED(device);
+ ADL_UNUSED(handler);
+ ADL_UNUSED(userData);
+ return -1;
+#endif
+}
+
ADLMIDI_EXPORT void adl_panic(struct ADL_MIDIPlayer *device)
{
if(!device)
diff --git a/src/midi_sequencer.hpp b/src/midi_sequencer.hpp
index 8cb8c6e..2c75da4 100644
--- a/src/midi_sequencer.hpp
+++ b/src/midi_sequencer.hpp
@@ -131,6 +131,8 @@ class BW_MidiSequencer
ST_LOOPSTACK_END = 0xE5,//size == 0 <CUSTOM>
//! [Non-Standard] Loop End point with support of multi-loops
ST_LOOPSTACK_BREAK = 0xE6,//size == 0 <CUSTOM>
+ //! [Non-Standard] Callback Trigger
+ ST_CALLBACK_TRIGGER = 0xE7,//size == 1 <CUSTOM>
};
//! Main type of event
uint8_t type;
@@ -453,6 +455,19 @@ private:
//! Index of solo track, or max for disabled
size_t m_trackSolo;
+ /**
+ * @brief Handler of callback trigger events
+ * @param userData Pointer to user data (usually, context of something)
+ * @param trigger Value of the event which triggered this callback.
+ * @param track Identifier of the track which triggered this callback.
+ */
+ typedef void (*TriggerHandler)(void *userData, unsigned trigger, size_t track);
+
+ //! Handler of callback trigger events
+ TriggerHandler m_triggerHandler;
+ //! User data of callback trigger events
+ void *m_triggerUserData;
+
//! File parsing errors string (adding into m_errorString on aborting of the process)
std::string m_parsingErrorsString;
//! Common error string
@@ -495,6 +510,13 @@ public:
void setSoloTrack(size_t track);
/**
+ * @brief Defines a handler for callback trigger events
+ * @param handler Handler to invoke from the sequencer when triggered, or NULL.
+ * @param userData Instance of the library
+ */
+ void setTriggerHandler(TriggerHandler handler, void *userData);
+
+ /**
* @brief Get the list of CMF instruments (CMF only)
* @return Array of raw CMF instruments entries
*/
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp
index 2749e26..bd0a226 100644
--- a/src/midi_sequencer_impl.hpp
+++ b/src/midi_sequencer_impl.hpp
@@ -277,7 +277,9 @@ BW_MidiSequencer::BW_MidiSequencer() :
m_loopEndTime(-1.0),
m_tempoMultiplier(1.0),
m_atEnd(false),
- m_trackSolo(~(size_t)0)
+ m_trackSolo(~(size_t)0),
+ m_triggerHandler(NULL),
+ m_triggerUserData(NULL)
{
m_loop.reset();
m_loop.invalidLoop = false;
@@ -335,6 +337,12 @@ void BW_MidiSequencer::setSoloTrack(size_t track)
m_trackSolo = track;
}
+void BW_MidiSequencer::setTriggerHandler(TriggerHandler handler, void *userData)
+{
+ m_triggerHandler = handler;
+ m_triggerUserData = userData;
+}
+
const std::vector<BW_MidiSequencer::CmfInstrument> BW_MidiSequencer::getRawCmfInstruments()
{
return m_cmfInstruments;
@@ -1345,8 +1353,9 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c
if(m_format == Format_XMIDI)
{
- if(evt.data[0] == 116)
+ switch(evt.data[0])
{
+ case 116: // For Loop Controller
evt.type = MidiEvent::T_SPECIAL;
evt.subtype = MidiEvent::ST_LOOPSTACK_BEGIN;
evt.data[0] = evt.data[1];
@@ -1362,10 +1371,9 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c
evt.data[0]
);
}
- }
+ break;
- if(evt.data[0] == 117)
- {
+ case 117: // Next/Break Loop Controller
evt.type = MidiEvent::T_SPECIAL;
evt.subtype = evt.data[1] < 64 ?
MidiEvent::ST_LOOPSTACK_BREAK :
@@ -1382,6 +1390,13 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c
m_loop.stackLevel - 1
);
}
+ break;
+
+ case 119: // Callback Trigger
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_CALLBACK_TRIGGER;
+ evt.data.assign(1, evt.data[1]);
+ break;
}
}
}
@@ -1518,6 +1533,17 @@ void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEve
}
}
+ if(evtype == MidiEvent::ST_CALLBACK_TRIGGER)
+ {
+#if 0 /* Print all callback triggers events */
+ if(m_interface->onDebugMessage)
+ m_interface->onDebugMessage(m_interface->onDebugMessage_userData, "Callback Trigger: %02X", evt.data[0]);
+#endif
+ if(m_triggerHandler)
+ m_triggerHandler(m_triggerUserData, data[0], track);
+ return;
+ }
+
if(evtype == MidiEvent::ST_RAWOPL) // Special non-spec ADLMIDI special for IMF playback: Direct poke to AdLib
{
if(m_interface->rt_rawOPL)