diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 39 | ||||
-rw-r--r-- | src/midi_sequencer_impl.hpp | 34 |
3 files changed, 63 insertions, 11 deletions
@@ -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; |