aboutsummaryrefslogtreecommitdiff
path: root/src/midi_sequencer_impl.hpp
diff options
context:
space:
mode:
authorVitaly Novichkov <admin@wohlnet.ru>2018-09-19 03:38:12 +0300
committerVitaly Novichkov <admin@wohlnet.ru>2018-09-19 03:38:12 +0300
commit02581cd7b0250000492b57fac74b4e2dfe13896d (patch)
tree3938825b0ddd87bb07f9fb6c1495a0b5545449ed /src/midi_sequencer_impl.hpp
parentb294333d585256182da160377c363a1f771a4c8b (diff)
downloadlibADLMIDI-02581cd7b0250000492b57fac74b4e2dfe13896d.tar.gz
libADLMIDI-02581cd7b0250000492b57fac74b4e2dfe13896d.tar.bz2
libADLMIDI-02581cd7b0250000492b57fac74b4e2dfe13896d.zip
Added automatic detection of HMI / RPG-Maker loop format
#175
Diffstat (limited to 'src/midi_sequencer_impl.hpp')
-rw-r--r--src/midi_sequencer_impl.hpp92
1 files changed, 87 insertions, 5 deletions
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp
index 59da621..6d6b2d8 100644
--- a/src/midi_sequencer_impl.hpp
+++ b/src/midi_sequencer_impl.hpp
@@ -270,6 +270,7 @@ BW_MidiSequencer::BW_MidiSequencer() :
m_interface(NULL),
m_format(Format_MIDI),
m_smfFormat(0),
+ m_loopFormat(Loop_Default),
m_loopEnabled(false),
m_fullSongTimeLength(0.0),
m_postSongWaitDelay(1.0),
@@ -399,6 +400,7 @@ void BW_MidiSequencer::buildSmfSetupReset(size_t trackCount)
m_fullSongTimeLength = 0.0;
m_loopStartTime = -1.0;
m_loopEndTime = -1.0;
+ m_loopFormat = Loop_Default;
m_trackDisable.clear();
m_trackSolo = ~(size_t)0;
m_musTitle.clear();
@@ -1374,12 +1376,92 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c
if(evType == MidiEvent::T_CTRLCHANGE)
{
//111'th loopStart controller (RPG Maker and others)
- if((m_format == Format_MIDI) && (evt.data[0] == 111))
+ if(m_format == Format_MIDI)
{
- //Change event type to custom Loop Start event and clear data
- evt.type = MidiEvent::T_SPECIAL;
- evt.subtype = MidiEvent::ST_LOOPSTART;
- evt.data.clear();
+ switch(evt.data[0])
+ {
+ case 110:
+ if(m_loopFormat == Loop_Default)
+ {
+ //Change event type to custom Loop Start event and clear data
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_LOOPSTART;
+ evt.data.clear();
+ m_loopFormat = Loop_HMI;
+ }
+ else if(m_loopFormat == Loop_HMI)
+ {
+ // Repeating of 110'th point is BAD practice, treat as EMIDI
+ m_loopFormat = Loop_EMIDI;
+ }
+ break;
+
+ case 111:
+ if(m_loopFormat == Loop_HMI)
+ {
+ //Change event type to custom Loop End event and clear data
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_LOOPEND;
+ evt.data.clear();
+ }
+ else if(m_loopFormat != Loop_EMIDI)
+ {
+ // Change event type to custom Loop Start event and clear data
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_LOOPSTART;
+ evt.data.clear();
+ }
+ break;
+
+ case 113:
+ if(m_loopFormat == Loop_EMIDI)
+ {
+ //EMIDI does using of CC113 with same purpose as CC7
+ evt.data[0] = 7;
+ }
+ break;
+#if 0 //WIP
+ case 116:
+ if(m_loopFormat == Loop_EMIDI)
+ {
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_LOOPSTACK_BEGIN;
+ evt.data[0] = evt.data[1];
+ evt.data.pop_back();
+
+ if(m_interface->onDebugMessage)
+ {
+ m_interface->onDebugMessage(
+ m_interface->onDebugMessage_userData,
+ "Stack EMIDI Loop Start at %d to %d level with %d loops",
+ m_loop.stackLevel,
+ m_loop.stackLevel + 1,
+ evt.data[0]
+ );
+ }
+ }
+ break;
+
+ case 117: // Next/Break Loop Controller
+ if(m_loopFormat == Loop_EMIDI)
+ {
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_LOOPSTACK_END;
+ evt.data.clear();
+
+ if(m_interface->onDebugMessage)
+ {
+ m_interface->onDebugMessage(
+ m_interface->onDebugMessage_userData,
+ "Stack EMIDI Loop End at %d to %d level",
+ m_loop.stackLevel,
+ m_loop.stackLevel - 1
+ );
+ }
+ }
+ break;
+#endif
+ }
}
if(m_format == Format_XMIDI)