aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--src/adlmidi_midiplay.cpp39
-rw-r--r--src/midi_sequencer_impl.hpp34
3 files changed, 63 insertions, 11 deletions
diff --git a/README.md b/README.md
index b7f5627..13ee760 100644
--- a/README.md
+++ b/README.md
@@ -185,6 +185,7 @@ To build that example you will need to have installed SDL2 library.
* Improved support of the EA-MUS files (Thanks to [dashodanger](https://github.com/dashodanger))
* Fixed crash on attempt to change the volume of a blank note
* Added an ability to supply the custom list of embedded banks using `-DGENADLDATA_CUSTOM_BANKLIST=/path/to/ini/file.ini` argument
+ * Improved support of the CMF files: added support for previously missing transpose, depth control, and song marker controllers
## 1.5.1 2022-10-31
* Added an ability to disable the automatical arpeggio
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 8d17eeb..35655d9 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -791,23 +791,42 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value)
break; // Phaser effect depth. We don't do.
case 98:
- m_midiChannels[channel].lastlrpn = value;
- m_midiChannels[channel].nrpn = true;
+ if(synth.m_musicMode != Synth::MODE_CMF)
+ {
+ m_midiChannels[channel].lastlrpn = value;
+ m_midiChannels[channel].nrpn = true;
+ }
break;
case 99:
- m_midiChannels[channel].lastmrpn = value;
- m_midiChannels[channel].nrpn = true;
+ if(synth.m_musicMode == Synth::MODE_CMF)
+ {
+ // CMF (ctrl 0x63) Depth control
+ synth.m_deepVibratoMode = (value & 1) != 0;
+ synth.m_deepTremoloMode = (value & 2) != 0;
+ synth.commitDeepFlags();
+ }
+ else
+ {
+ m_midiChannels[channel].lastmrpn = value;
+ m_midiChannels[channel].nrpn = true;
+ }
break;
case 100:
- m_midiChannels[channel].lastlrpn = value;
- m_midiChannels[channel].nrpn = false;
+ if(synth.m_musicMode != Synth::MODE_CMF)
+ {
+ m_midiChannels[channel].lastlrpn = value;
+ m_midiChannels[channel].nrpn = false;
+ }
break;
case 101:
- m_midiChannels[channel].lastmrpn = value;
- m_midiChannels[channel].nrpn = false;
+ if(synth.m_musicMode != Synth::MODE_CMF)
+ {
+ m_midiChannels[channel].lastmrpn = value;
+ m_midiChannels[channel].nrpn = false;
+ }
break;
case 113:
@@ -821,10 +840,10 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value)
setRPN(channel, value, false);
break;
- case 103:
+ case 103: // CMF (ctrl 0x67) rhythm mode
if(synth.m_musicMode == Synth::MODE_CMF)
m_cmfPercussionMode = (value != 0);
- break; // CMF (ctrl 0x67) rhythm mode
+ break;
default:
break;
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp
index 1bdb70b..5eb2d95 100644
--- a/src/midi_sequencer_impl.hpp
+++ b/src/midi_sequencer_impl.hpp
@@ -1761,7 +1761,7 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c
}
}
- if(m_format == Format_XMIDI)
+ else if(m_format == Format_XMIDI)
{
switch(evt.data[0])
{
@@ -1809,6 +1809,38 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c
break;
}
}
+
+ else if(m_format == Format_CMF)
+ {
+ switch(evt.data[0])
+ {
+ case 102: // Song markers (0x66)
+ evt.type = MidiEvent::T_SPECIAL;
+ evt.subtype = MidiEvent::ST_CALLBACK_TRIGGER;
+ evt.data.assign(1, evt.data[1]);
+ break;
+
+ case 104: // Transpose Up (0x68), convert into pitch bend
+ {
+ int16_t bend = 8192 + (((int)evt.data[1] * 8192) / 128);
+ evt.type = MidiEvent::T_WHEEL;
+ evt.data.resize(2);
+ evt.data[0] = (bend & 0x7F);
+ evt.data[1] = ((bend >> 7) & 0x7F);
+ break;
+ }
+
+ case 105: // Transpose Down (0x69), convert into pitch bend
+ {
+ int16_t bend = 8192 - (((int)evt.data[1] * 8192) / 128);
+ evt.type = MidiEvent::T_WHEEL;
+ evt.data.resize(2);
+ evt.data[0] = (bend & 0x7F);
+ evt.data[1] = ((bend >> 7) & 0x7F);
+ break;
+ }
+ }
+ }
}
return evt;