From 252e65097e9b8a815485fc03e4358698803f1a73 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 20 Jun 2018 21:45:54 +0200 Subject: basic framework of sysex handling and sequencer support --- src/adlmidi.cpp | 21 ++++++ src/adlmidi_midiplay.cpp | 178 +++++++++++++++++++++++++++++++++++++++++++++++ src/adlmidi_private.hpp | 29 ++++++++ 3 files changed, 228 insertions(+) (limited to 'src') diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index 9210b5b..e3d2326 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -68,6 +68,17 @@ ADLMIDI_EXPORT struct ADL_MIDIPlayer *adl_init(long sample_rate) return midi_device; } +ADLMIDI_EXPORT int adl_setDeviceIdentifier(ADL_MIDIPlayer *device, unsigned id) +{ + if(!device || id > 0x0f) + return -1; + MIDIplay *play = reinterpret_cast(device->adl_midiPlayer); + if(!play) + return -1; + play->setDeviceId(id); + return 0; +} + ADLMIDI_EXPORT int adl_setNumChips(ADL_MIDIPlayer *device, int numCards) { if(device == NULL) @@ -1267,3 +1278,13 @@ ADLMIDI_EXPORT void adl_rt_bankChange(struct ADL_MIDIPlayer *device, ADL_UInt8 c return; player->realTime_BankChange(channel, (uint16_t)bank); } + +ADLMIDI_EXPORT int adl_rt_systemExclusive(struct ADL_MIDIPlayer *device, const ADL_UInt8 *msg, unsigned size) +{ + if(!device) + return -1; + MIDIplay *player = reinterpret_cast(device->adl_midiPlayer); + if(!player) + return -1; + return player->realTime_SysEx(msg, size); +} diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 2f186a6..e0cacfa 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -680,6 +680,7 @@ bool MIDIplay::buildTrackData() MIDIplay::MIDIplay(unsigned long sampleRate): cmf_percussion_mode(false), + m_sysExDeviceId(0), m_arpeggioCounter(0) #if defined(ADLMIDI_AUDIO_TICK_HANDLER) , m_audioTickCounter(0) @@ -1459,6 +1460,172 @@ void MIDIplay::realTime_BankChange(uint8_t channel, uint16_t bank) Ch[channel].bank_msb = uint8_t((bank >> 8) & 0xFF); } +void MIDIplay::setDeviceId(uint8_t id) +{ + m_sysExDeviceId = id; +} + +bool MIDIplay::realTime_SysEx(const uint8_t *msg, unsigned size) +{ + if(size < 4 || msg[0] != 0xF0 || msg[size - 1] != 0xF7) + return false; + + unsigned manufacturer = msg[1]; + unsigned dev = msg[2]; + msg += 3; + size -= 4; + + switch(manufacturer) + { + default: + break; + case Manufacturer_UniversalNonRealtime: + case Manufacturer_UniversalRealtime: + return doUniversalSysEx( + dev, manufacturer == Manufacturer_UniversalRealtime, msg, size); + case Manufacturer_Roland: + return doRolandSysEx(dev, msg, size); + case Manufacturer_Yamaha: + return doYamahaSysEx(dev, msg, size); + } + + return false; +} + +bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, unsigned size) +{ + bool devicematch = dev == 0x7F || dev == m_sysExDeviceId; + if(size < 2 || !devicematch) + return false; + + unsigned address = + (((unsigned)data[0] & 0x7F) << 8) | + (((unsigned)data[1] & 0x7F)); + data += 2; + size -= 2; + + switch(((unsigned)realtime << 16) | address) + { + case (0 << 16) | 0x0901: // GM System On + /*TODO*/ + return true; + case (0 << 16) | 0x0902: // GM System Off + /*TODO*/ + return true; + case (1 << 16) | 0x0401: // MIDI Master Volume + if(size != 2) + break; + unsigned volume = + (((unsigned)data[0] & 0x7F)) | + (((unsigned)data[1] & 0x7F) << 7); + /*TODO*/ + (void)volume; + return true; + } + + return false; +} + +bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, unsigned size) +{ + bool devicematch = dev == 0x7F || (dev & 0x0F) == m_sysExDeviceId; + if(size < 6 || !devicematch) + return false; + + unsigned model = data[0] & 0x7F; + unsigned mode = data[1] & 0x7F; + unsigned checksum = data[size - 1] & 0x7F; + data += 2; + size -= 3; + +#if !defined(ADLMIDI_SKIP_ROLAND_CHECKSUM) + { + unsigned checkvalue = 0; + for(unsigned i = 0; i < size; ++i) + checkvalue += data[i] & 0x7F; + checkvalue = (128 - (checkvalue & 127)) & 127; + if(checkvalue != checksum) + return false; + } +#endif + + unsigned address = + (((unsigned)data[0] & 0x7F) << 16) | + (((unsigned)data[1] & 0x7F) << 8) | + (((unsigned)data[2] & 0x7F)); + data += 3; + size -= 3; + + if(mode != RolandMode_Send) // don't have MIDI-Out reply ability + return false; + + switch((model << 24) | address) + { + case (RolandModel_GS << 24) | 0x00007F: // System Mode Set + { + if(size != 1 || (dev & 0xF0) != 0x10) + break; + unsigned mode = data[0] & 0x7F; + /*TODO*/ + (void)mode; + return true; + } + case (RolandModel_GS << 24) | 0x40007F: // Mode Set + { + if(size != 1 || (dev & 0xF0) != 0x10) + break; + unsigned value = data[0] & 0x7F; + /*TODO*/ + (void)value; + return true; + } + } + + return false; +} + +bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, unsigned size) +{ + bool devicematch = dev == 0x7F || (dev & 0x0F) == m_sysExDeviceId; + if(size < 1 || !devicematch) + return false; + + unsigned model = data[0] & 0x7F; + ++data; + --size; + + switch((model << 8) | (dev & 0xF0)) + { + case (YamahaModel_XG << 8) | 0x10: // parameter change + { + if(size < 3) + break; + + unsigned address = + (((unsigned)data[0] & 0x7F) << 16) | + (((unsigned)data[1] & 0x7F) << 8) | + (((unsigned)data[2] & 0x7F)); + data += 3; + size -= 3; + + switch(address) + { + case 0x00007E: // XG System On + if(size != 1) + break; + unsigned value = data[0] & 0x7F; + /*TODO*/ + (void)value; + return true; + } + + break; + } + } + + return false; +} + void MIDIplay::realTime_panic() { Panic(); @@ -1845,6 +2012,10 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat evt.isValid = 0; return evt; } + evt.type = MidiEvent::T_SYSEX; + evt.data.clear(); + evt.data.push_back(byte); + std::copy(ptr, ptr + length, std::back_inserter(evt.data)); ptr += (size_t)length; return evt; } @@ -2067,6 +2238,13 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu { //std::string data( length?(const char*) &TrackData[tk][CurrentPosition.track[tk].ptr]:0, length ); //UI.PrintLn("SysEx %02X: %u bytes", byte, length/*, data.c_str()*/); +#if 0 + fputs("SysEx:", stderr); + for(size_t i = 0; i < evt.data.size(); ++i) + fprintf(stderr, " %02X", evt.data[i]); + fputc('\n', stderr); +#endif + realTime_SysEx(evt.data.data(), (unsigned)evt.data.size()); return; } diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index fda629d..4b3ab10 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -108,6 +108,7 @@ typedef int32_t ssize_t; #include #include +#include /* * Workaround for some compilers are has no those macros in their headers! @@ -984,6 +985,7 @@ public: std::vector Ch; bool cmf_percussion_mode; + uint8_t m_sysExDeviceId; MIDIEventHooks hooks; @@ -1198,6 +1200,9 @@ public: void realTime_BankChangeMSB(uint8_t channel, uint8_t msb); void realTime_BankChange(uint8_t channel, uint16_t bank); + void setDeviceId(uint8_t id); + bool realTime_SysEx(const uint8_t *msg, unsigned size); + void realTime_panic(); #if defined(ADLMIDI_AUDIO_TICK_HANDLER) @@ -1205,6 +1210,30 @@ public: void AudioTick(uint32_t chipId, uint32_t rate); #endif +private: + enum + { + Manufacturer_Roland = 0x41, + Manufacturer_Yamaha = 0x43, + Manufacturer_UniversalNonRealtime = 0x7E, + Manufacturer_UniversalRealtime = 0x7F + }; + enum + { + RolandMode_Request = 0x11, + RolandMode_Send = 0x12 + }; + enum + { + RolandModel_GS = 0x42, + RolandModel_SC55 = 0x45, + YamahaModel_XG = 0x4C + }; + + bool doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, unsigned size); + bool doRolandSysEx(unsigned dev, const uint8_t *data, unsigned size); + bool doYamahaSysEx(unsigned dev, const uint8_t *data, unsigned size); + private: enum { -- cgit v1.2.3 From ebee7962d7a2691e38d585dac9b9c0e3d286364c Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Thu, 21 Jun 2018 09:43:34 +0300 Subject: SysEx: Use `size_t` for size values instead of `unsigned int` --- src/adlmidi.cpp | 2 +- src/adlmidi_midiplay.cpp | 10 +++++----- src/adlmidi_private.hpp | 8 ++++---- src/adlmidi_sequencer.cpp | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index e77278c..c3c07a7 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -1342,7 +1342,7 @@ ADLMIDI_EXPORT void adl_rt_bankChange(struct ADL_MIDIPlayer *device, ADL_UInt8 c player->realTime_BankChange(channel, (uint16_t)bank); } -ADLMIDI_EXPORT int adl_rt_systemExclusive(struct ADL_MIDIPlayer *device, const ADL_UInt8 *msg, unsigned size) +ADLMIDI_EXPORT int adl_rt_systemExclusive(struct ADL_MIDIPlayer *device, const ADL_UInt8 *msg, size_t size) { if(!device) return -1; diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 8b4f27f..ba5b1ef 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -712,7 +712,7 @@ void MIDIplay::setDeviceId(uint8_t id) m_sysExDeviceId = id; } -bool MIDIplay::realTime_SysEx(const uint8_t *msg, unsigned size) +bool MIDIplay::realTime_SysEx(const uint8_t *msg, size_t size) { if(size < 4 || msg[0] != 0xF0 || msg[size - 1] != 0xF7) return false; @@ -739,7 +739,7 @@ bool MIDIplay::realTime_SysEx(const uint8_t *msg, unsigned size) return false; } -bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, unsigned size) +bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, size_t size) { bool devicematch = dev == 0x7F || dev == m_sysExDeviceId; if(size < 2 || !devicematch) @@ -773,7 +773,7 @@ bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data return false; } -bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, unsigned size) +bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) { bool devicematch = dev == 0x7F || (dev & 0x0F) == m_sysExDeviceId; if(size < 6 || !devicematch) @@ -788,7 +788,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, unsigned size) #if !defined(ADLMIDI_SKIP_ROLAND_CHECKSUM) { unsigned checkvalue = 0; - for(unsigned i = 0; i < size; ++i) + for(size_t i = 0; i < size; ++i) checkvalue += data[i] & 0x7F; checkvalue = (128 - (checkvalue & 127)) & 127; if(checkvalue != checksum) @@ -831,7 +831,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, unsigned size) return false; } -bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, unsigned size) +bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size) { bool devicematch = dev == 0x7F || (dev & 0x0F) == m_sysExDeviceId; if(size < 1 || !devicematch) diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 67f1ccb..280232f 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -914,7 +914,7 @@ public: * @param size Length of SysEx message * @return true if message was passed successfully. False on any errors */ - bool realTime_SysEx(const uint8_t *msg, unsigned size); + bool realTime_SysEx(const uint8_t *msg, size_t size); /** * @brief Turn off all notes and mute the sound of releasing notes @@ -967,9 +967,9 @@ private: YamahaModel_XG = 0x4C }; - bool doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, unsigned size); - bool doRolandSysEx(unsigned dev, const uint8_t *data, unsigned size); - bool doYamahaSysEx(unsigned dev, const uint8_t *data, unsigned size); + bool doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, size_t size); + bool doRolandSysEx(unsigned dev, const uint8_t *data, size_t size); + bool doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size); private: enum diff --git a/src/adlmidi_sequencer.cpp b/src/adlmidi_sequencer.cpp index ac983d0..b8bf3dd 100644 --- a/src/adlmidi_sequencer.cpp +++ b/src/adlmidi_sequencer.cpp @@ -79,7 +79,7 @@ static void rtPitchBend(void *userdata, uint8_t channel, uint8_t msb, uint8_t ls static void rtSysEx(void *userdata, const uint8_t *msg, size_t size) { MIDIplay *context = reinterpret_cast(userdata); - context->realTime_SysEx(msg, (unsigned)size); + context->realTime_SysEx(msg, size); } -- cgit v1.2.3 From b2259a0ad2da07729eb285eda4a833e5b0f1f7eb Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Thu, 21 Jun 2018 14:11:48 +0300 Subject: Attempt to fix MSVC 2015 build --- src/adlmidi_private.hpp | 1 - src/midi_sequencer_impl.hpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 280232f..54d69b8 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -108,7 +108,6 @@ typedef int32_t ssize_t; #include #include -#include /* * Workaround for some compilers are has no those macros in their headers! diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index 7ecefa2..92be133 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -26,6 +26,8 @@ #include #include #include +#include // std::back_inserter +#include // std::copy #include #include -- cgit v1.2.3 From 8075701abfe8e5b1fc6705eb2b1d35b407784c82 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 03:35:06 +0300 Subject: Portamento must use previously played note in a channel like S-YXG50 does --- src/adlmidi_midiplay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index ba5b1ef..089fd43 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -478,7 +478,8 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) midiChan.portamentoEnable && currentPortamentoRate != HUGE_VAL && !isPercussion && !isXgPercussion; // Record the last note on MIDI channel as source of portamento - midiChan.portamentoSource = portamentoEnable ? (int8_t)note : (int8_t)-1; + midiChan.portamentoSource = static_cast(note); + // midiChan.portamentoSource = portamentoEnable ? (int8_t)note : (int8_t)-1; // Enable gliding on portamento note if (portamentoEnable && currentPortamentoSource >= 0) -- cgit v1.2.3 From be2e41fe5d800520ee50ca93729c8633407fb1fc Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Fri, 22 Jun 2018 17:30:34 +0200 Subject: handle sysex resets --- src/adlmidi_midiplay.cpp | 10 +++++----- src/adlmidi_private.hpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 089fd43..bd979bd 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -606,7 +606,7 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) break; case 120: // All sounds off - NoteUpdate_All(channel, Upt_OffMute); + NoteUpdate_All(channel, Upd_OffMute); break; case 123: // All notes off @@ -755,10 +755,10 @@ bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data switch(((unsigned)realtime << 16) | address) { case (0 << 16) | 0x0901: // GM System On - /*TODO*/ + realTime_ResetState(); return true; case (0 << 16) | 0x0902: // GM System Off - /*TODO*/ + realTime_ResetState(); return true; case (1 << 16) | 0x0401: // MIDI Master Volume if(size != 2) @@ -814,8 +814,8 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1 || (dev & 0xF0) != 0x10) break; unsigned mode = data[0] & 0x7F; - /*TODO*/ (void)mode; + realTime_ResetState(); return true; } case (RolandModel_GS << 24) | 0x40007F: // Mode Set @@ -823,8 +823,8 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1 || (dev & 0xF0) != 0x10) break; unsigned value = data[0] & 0x7F; - /*TODO*/ (void)value; + realTime_ResetState(); return true; } } diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 54d69b8..b7bdc17 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -980,7 +980,7 @@ private: Upd_All = Upd_Pan + Upd_Volume + Upd_Pitch, Upd_Off = 0x20, Upd_Mute = 0x40, - Upt_OffMute = Upd_Off + Upd_Mute + Upd_OffMute = Upd_Off + Upd_Mute }; void NoteUpdate(uint16_t MidCh, -- cgit v1.2.3 From 16831e97a68049d27329db4630dcfbfa58b1d8fd Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Fri, 22 Jun 2018 17:58:31 +0200 Subject: handle MIDI master volume --- src/adlmidi_midiplay.cpp | 29 +++++++++++++++++------------ src/adlmidi_private.hpp | 1 + 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index bd979bd..3aa307d 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -93,6 +93,8 @@ static const uint8_t PercussionMap[256] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; +enum { MasterVolumeDefault = 127 }; + inline bool isXgPercChannel(uint8_t msb, uint8_t lsb) { return (msb == 0x7E || msb == 0x7F) && (lsb == 0); @@ -117,6 +119,7 @@ void MIDIplay::AdlChannel::AddAge(int64_t ms) MIDIplay::MIDIplay(unsigned long sampleRate): cmf_percussion_mode(false), + m_masterVolume(MasterVolumeDefault), m_sysExDeviceId(0), m_arpeggioCounter(0) #if defined(ADLMIDI_AUDIO_TICK_HANDLER) @@ -220,6 +223,7 @@ void MIDIplay::realTime_ResetState() NoteUpdate_All(uint16_t(ch), Upd_All); NoteUpdate_All(uint16_t(ch), Upd_Off); } + m_masterVolume = MasterVolumeDefault; } bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) @@ -766,8 +770,9 @@ bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data unsigned volume = (((unsigned)data[0] & 0x7F)) | (((unsigned)data[1] & 0x7F) << 7); - /*TODO*/ - (void)volume; + m_masterVolume = volume >> 7; + for(size_t ch = 0; ch < Ch.size(); ch++) + NoteUpdate_All(uint16_t(ch), Upd_Volume); return true; } @@ -1029,7 +1034,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, case OPL3::VOLUME_Generic: { - volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; + volume = vol * m_masterVolume * Ch[MidCh].volume * Ch[MidCh].expression; /* If the channel has arpeggio, the effective volume of * *this* instrument is actually lower due to timesharing. @@ -1040,10 +1045,10 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, */ //volume = (int)(volume * std::sqrt( (double) ch[c].users.size() )); - // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A) - volume = volume > 8725 ? static_cast(std::log(static_cast(volume)) * 11.541561 + (0.5 - 104.22845)) : 0; - // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A) - //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0); + // The formula below: SOLVE(V=127^4 * 2^( (A-63.49999) / 8), A) + volume = volume > (8725 * 127) ? static_cast(std::log(static_cast(volume) * (1.0 / 127.0)) * 11.541561 + (0.5 - 104.22845)) : 0; + // The incorrect formula below: SOLVE(V=127^4 * (2^(A/63)-1), A) + //opl.Touch_Real(c, volume>(11210*127) ? 91.61112 * std::log((4.8819E-7/127)*volume + 1.0)+0.5 : 0); opl.Touch_Real(c, volume, brightness); //opl.Touch(c, volume); @@ -1053,14 +1058,14 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, case OPL3::VOLUME_NATIVE: { volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; - volume = volume * 127 / (127 * 127 * 127) / 2; + volume = volume * m_masterVolume / (127 * 127 * 127) / 2; opl.Touch_Real(c, volume, brightness); } break; case OPL3::VOLUME_DMX: { - volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1; + volume = 2 * (Ch[MidCh].volume * Ch[MidCh].expression * m_masterVolume / 16129) + 1; //volume = 2 * (Ch[MidCh].volume) + 1; volume = (DMX_volume_mapping_table[(vol < 128) ? vol : 127] * volume) >> 9; opl.Touch_Real(c, volume, brightness); @@ -1069,7 +1074,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, case OPL3::VOLUME_APOGEE: { - volume = ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129); + volume = (Ch[MidCh].volume * Ch[MidCh].expression * m_masterVolume / 16129); volume = ((64 * (vol + 0x80)) * volume) >> 15; //volume = ((63 * (vol + 0x80)) * Ch[MidCh].volume) >> 15; opl.Touch_Real(c, volume, brightness); @@ -1078,8 +1083,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, case OPL3::VOLUME_9X: { - //volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume /** Ch[MidCh].expression*/) * 127 / 16129 /*2048383*/) >> 2)]; - volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 2048383) >> 2)]; + //volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume /** Ch[MidCh].expression*/) * m_masterVolume / 16129 /*2048383*/) >> 2)]; + volume = 63 - W9X_volume_mapping_table[((vol * Ch[MidCh].volume * Ch[MidCh].expression * m_masterVolume / 2048383) >> 2)]; //volume = W9X_volume_mapping_table[vol >> 2] + volume; opl.Touch_Real(c, volume, brightness); } diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index b7bdc17..71f0068 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -723,6 +723,7 @@ public: std::vector Ch; bool cmf_percussion_mode; + uint8_t m_masterVolume; uint8_t m_sysExDeviceId; MIDIEventHooks hooks; -- cgit v1.2.3 From faaab13482d1e8334712232b7f64a59ec8ae6f07 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Fri, 22 Jun 2018 18:41:31 +0200 Subject: Yamaha XG reset --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 3aa307d..a6fc2a5 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -867,8 +867,8 @@ bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1) break; unsigned value = data[0] & 0x7F; - /*TODO*/ (void)value; + realTime_ResetState(); return true; } -- cgit v1.2.3 From 2e88f9b9303ce1b9ef5512d6b84b3bb190dbfe75 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Fri, 22 Jun 2018 19:08:17 +0200 Subject: simplify the volume formula --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index a6fc2a5..5637da4 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1046,7 +1046,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, //volume = (int)(volume * std::sqrt( (double) ch[c].users.size() )); // The formula below: SOLVE(V=127^4 * 2^( (A-63.49999) / 8), A) - volume = volume > (8725 * 127) ? static_cast(std::log(static_cast(volume) * (1.0 / 127.0)) * 11.541561 + (0.5 - 104.22845)) : 0; + volume = volume > (8725 * 127) ? static_cast(std::log(static_cast(volume)) * 11.541560327111707 - 1.601379199767093e+02) : 0; // The incorrect formula below: SOLVE(V=127^4 * (2^(A/63)-1), A) //opl.Touch_Real(c, volume>(11210*127) ? 91.61112 * std::log((4.8819E-7/127)*volume + 1.0)+0.5 : 0); -- cgit v1.2.3 From 51081828bbc756f81ac4b5c58cd3605a31047f61 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 21:22:44 +0300 Subject: Move `opl.Touch_Real()` call out of volume model switch --- src/adlmidi_midiplay.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 5637da4..625f8f7 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1049,9 +1049,6 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, volume = volume > (8725 * 127) ? static_cast(std::log(static_cast(volume)) * 11.541560327111707 - 1.601379199767093e+02) : 0; // The incorrect formula below: SOLVE(V=127^4 * (2^(A/63)-1), A) //opl.Touch_Real(c, volume>(11210*127) ? 91.61112 * std::log((4.8819E-7/127)*volume + 1.0)+0.5 : 0); - - opl.Touch_Real(c, volume, brightness); - //opl.Touch(c, volume); } break; @@ -1059,7 +1056,6 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; volume = volume * m_masterVolume / (127 * 127 * 127) / 2; - opl.Touch_Real(c, volume, brightness); } break; @@ -1068,7 +1064,6 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, volume = 2 * (Ch[MidCh].volume * Ch[MidCh].expression * m_masterVolume / 16129) + 1; //volume = 2 * (Ch[MidCh].volume) + 1; volume = (DMX_volume_mapping_table[(vol < 128) ? vol : 127] * volume) >> 9; - opl.Touch_Real(c, volume, brightness); } break; @@ -1077,7 +1072,6 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, volume = (Ch[MidCh].volume * Ch[MidCh].expression * m_masterVolume / 16129); volume = ((64 * (vol + 0x80)) * volume) >> 15; //volume = ((63 * (vol + 0x80)) * Ch[MidCh].volume) >> 15; - opl.Touch_Real(c, volume, brightness); } break; @@ -1086,11 +1080,12 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, //volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume /** Ch[MidCh].expression*/) * m_masterVolume / 16129 /*2048383*/) >> 2)]; volume = 63 - W9X_volume_mapping_table[((vol * Ch[MidCh].volume * Ch[MidCh].expression * m_masterVolume / 2048383) >> 2)]; //volume = W9X_volume_mapping_table[vol >> 2] + volume; - opl.Touch_Real(c, volume, brightness); } break; } + opl.Touch_Real(c, volume, brightness); + /* DEBUG ONLY!!! static uint32_t max = 0; -- cgit v1.2.3 From db96b37884c4e32f2d6b7cd1745f829e1c2cb564 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 21:23:01 +0300 Subject: Added some debug message hooks into SysEx processors --- src/adlmidi_midiplay.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 625f8f7..336c40c 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -759,9 +759,13 @@ bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data switch(((unsigned)realtime << 16) | address) { case (0 << 16) | 0x0901: // GM System On + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: GM System On"); realTime_ResetState(); return true; case (0 << 16) | 0x0902: // GM System Off + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: GM System Off"); realTime_ResetState(); return true; case (1 << 16) | 0x0401: // MIDI Master Volume @@ -819,7 +823,9 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1 || (dev & 0xF0) != 0x10) break; unsigned mode = data[0] & 0x7F; - (void)mode; + ADL_UNUSED(mode); + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caugh Roland System Mode Set: %02X", mode); realTime_ResetState(); return true; } @@ -828,7 +834,9 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1 || (dev & 0xF0) != 0x10) break; unsigned value = data[0] & 0x7F; - (void)value; + ADL_UNUSED(value); + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caugh Roland Mode Set: %02X", value); realTime_ResetState(); return true; } @@ -867,7 +875,9 @@ bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1) break; unsigned value = data[0] & 0x7F; - (void)value; + ADL_UNUSED(value); + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caugh Yamaha XG System On: %02X", value); realTime_ResetState(); return true; } -- cgit v1.2.3 From a8fa66e8444da96b39699489bf75587a0ae94721 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 21:30:00 +0300 Subject: Use Generic volume model by default when VM value has received some junk --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 336c40c..8a4e8cd 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1041,7 +1041,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, switch(opl.m_volumeScale) { - + default: case OPL3::VOLUME_Generic: { volume = vol * m_masterVolume * Ch[MidCh].volume * Ch[MidCh].expression; -- cgit v1.2.3 From be1cd07a227783553406e144e9235901e792c5b1 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 22:31:18 +0300 Subject: Sequencer: give SysEx events have highest priority while re-ordering --- src/midi_sequencer_impl.hpp | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index 92be133..0e71c2a 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -160,31 +160,48 @@ void BW_MidiSequencer::MidiTrackRow::clear() void BW_MidiSequencer::MidiTrackRow::sortEvents(bool *noteStates) { typedef std::vector EvtArr; + EvtArr sysEx; EvtArr metas; EvtArr noteOffs; EvtArr controllers; EvtArr anyOther; - metas.reserve(events.size()); - noteOffs.reserve(events.size()); - controllers.reserve(events.size()); - anyOther.reserve(events.size()); - for(size_t i = 0; i < events.size(); i++) { if(events[i].type == MidiEvent::T_NOTEOFF) + { + if(noteOffs.capacity() == 0) + noteOffs.reserve(events.size()); noteOffs.push_back(events[i]); + } + else if(events[i].type == MidiEvent::T_SYSEX || + events[i].type == MidiEvent::T_SYSEX2) + { + if(sysEx.capacity() == 0) + sysEx.reserve(events.size()); + sysEx.push_back(events[i]); + } else if((events[i].type == MidiEvent::T_CTRLCHANGE) || (events[i].type == MidiEvent::T_PATCHCHANGE) || (events[i].type == MidiEvent::T_WHEEL) || (events[i].type == MidiEvent::T_CHANAFTTOUCH)) { + if(controllers.capacity() == 0) + controllers.reserve(events.size()); controllers.push_back(events[i]); } else if((events[i].type == MidiEvent::T_SPECIAL) && (events[i].subtype == MidiEvent::ST_MARKER)) + { + if(metas.capacity() == 0) + metas.reserve(events.size()); metas.push_back(events[i]); + } else + { + if(anyOther.capacity() == 0) + anyOther.reserve(events.size()); anyOther.push_back(events[i]); + } } /* @@ -246,10 +263,16 @@ void BW_MidiSequencer::MidiTrackRow::sortEvents(bool *noteStates) /***********************************************************************************/ events.clear(); - events.insert(events.end(), noteOffs.begin(), noteOffs.end()); - events.insert(events.end(), metas.begin(), metas.end()); - events.insert(events.end(), controllers.begin(), controllers.end()); - events.insert(events.end(), anyOther.begin(), anyOther.end()); + if(!sysEx.empty()) + events.insert(events.end(), sysEx.begin(), sysEx.end()); + if(!noteOffs.empty()) + events.insert(events.end(), noteOffs.begin(), noteOffs.end()); + if(!metas.empty()) + events.insert(events.end(), metas.begin(), metas.end()); + if(!controllers.empty()) + events.insert(events.end(), controllers.begin(), controllers.end()); + if(!anyOther.empty()) + events.insert(events.end(), anyOther.begin(), anyOther.end()); } BW_MidiSequencer::BW_MidiSequencer() : -- cgit v1.2.3 From 2f30eb0596d3fc9788ffe99b72a09ceca596b792 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 22:33:36 +0300 Subject: Fix the typo in "Caught" word in debug messages --- src/adlmidi_midiplay.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 8a4e8cd..eca5282 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -335,7 +335,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(hooks.onDebugMessage) { if(caugh_missing_instruments.insert(static_cast(midiins)).second) - hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank); + hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caught a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank); } bank = 0; midiins = midiChan.patch; @@ -825,7 +825,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) unsigned mode = data[0] & 0x7F; ADL_UNUSED(mode); if(hooks.onDebugMessage) - hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caugh Roland System Mode Set: %02X", mode); + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Roland System Mode Set: %02X", mode); realTime_ResetState(); return true; } @@ -836,7 +836,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) unsigned value = data[0] & 0x7F; ADL_UNUSED(value); if(hooks.onDebugMessage) - hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caugh Roland Mode Set: %02X", value); + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Roland Mode Set: %02X", value); realTime_ResetState(); return true; } @@ -877,7 +877,7 @@ bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size) unsigned value = data[0] & 0x7F; ADL_UNUSED(value); if(hooks.onDebugMessage) - hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caugh Yamaha XG System On: %02X", value); + hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Yamaha XG System On: %02X", value); realTime_ResetState(); return true; } -- cgit v1.2.3 From 159bb5b202cd088db920ccc073d952122dea85ba Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 23:25:13 +0300 Subject: Added support for synthesizer mode - in GS mode, RPN XG-related vibrato depth events will be ignored (GS does using NRPN values are stored separately and are NOT handled) - in GS mode ignore LSB value of the bank number --- src/adlmidi_midiplay.cpp | 40 +++++++++++++++++++++++++++++----------- src/adlmidi_private.hpp | 9 +++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index eca5282..dd5c9bf 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -121,6 +121,7 @@ MIDIplay::MIDIplay(unsigned long sampleRate): cmf_percussion_mode(false), m_masterVolume(MasterVolumeDefault), m_sysExDeviceId(0), + m_synthMode(Mode_XG), m_arpeggioCounter(0) #if defined(ADLMIDI_AUDIO_TICK_HANDLER) , m_audioTickCounter(0) @@ -262,10 +263,13 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) uint16_t bank = 0; if(midiChan.bank_msb || midiChan.bank_lsb) { - bank = (uint16_t(midiChan.bank_msb) * 256) + uint16_t(midiChan.bank_lsb); + if((m_synthMode & Mode_GS) != 0) //in GS mode ignore LSB + bank = (uint16_t(midiChan.bank_msb) * 256); + else + bank = (uint16_t(midiChan.bank_msb) * 256) + uint16_t(midiChan.bank_lsb); //0x7E00 - XG SFX1/SFX2 channel (16128 signed decimal) //0x7F00 - XG Percussion channel (16256 signed decimal) - if(bank == 0x7E00 || bank == 0x7F00) + if(((m_synthMode & Mode_XG) != 0) && (bank == 0x7E00 || bank == 0x7F00)) { //Let XG SFX1/SFX2 bank will have LSB==1 (128...255 range in WOPN file) //Let XG Percussion bank will use (0...127 range in WOPN file) @@ -761,11 +765,13 @@ bool MIDIplay::doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data case (0 << 16) | 0x0901: // GM System On if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: GM System On"); + m_synthMode = Mode_GM; realTime_ResetState(); return true; case (0 << 16) | 0x0902: // GM System Off if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: GM System Off"); + m_synthMode = Mode_XG;//TODO: TEMPORARY, make something RIGHT realTime_ResetState(); return true; case (1 << 16) | 0x0401: // MIDI Master Volume @@ -826,6 +832,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) ADL_UNUSED(mode); if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Roland System Mode Set: %02X", mode); + m_synthMode = Mode_GS; realTime_ResetState(); return true; } @@ -837,6 +844,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) ADL_UNUSED(value); if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Roland Mode Set: %02X", value); + m_synthMode = Mode_GS; realTime_ResetState(); return true; } @@ -878,6 +886,7 @@ bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size) ADL_UNUSED(value); if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Yamaha XG System On: %02X", value); + m_synthMode = Mode_XG; realTime_ResetState(); return true; } @@ -1396,17 +1405,26 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB) Ch[MidCh].bendsense_lsb = value; Ch[MidCh].updateBendSensitivity(); break; - case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed - if(value == 64) Ch[MidCh].vibspeed = 1.0; - else if(value < 100) Ch[MidCh].vibspeed = 1.0 / (1.6e-2 * (value ? value : 1)); - else Ch[MidCh].vibspeed = 1.0 / (0.051153846 * value - 3.4965385); - Ch[MidCh].vibspeed *= 2 * 3.141592653 * 5.0; + case 0x0108 + 1*0x10000 + 1*0x20000: + if((m_synthMode & Mode_XG) != 0) // Vibrato speed + { + if(value == 64) Ch[MidCh].vibspeed = 1.0; + else if(value < 100) Ch[MidCh].vibspeed = 1.0 / (1.6e-2 * (value ? value : 1)); + else Ch[MidCh].vibspeed = 1.0 / (0.051153846 * value - 3.4965385); + Ch[MidCh].vibspeed *= 2 * 3.141592653 * 5.0; + } break; - case 0x0109 + 1*0x10000 + 1*0x20000: // Vibrato depth - Ch[MidCh].vibdepth = ((value - 64) * 0.15) * 0.01; + case 0x0109 + 1*0x10000 + 1*0x20000: + if((m_synthMode & Mode_XG) != 0) // Vibrato depth + { + Ch[MidCh].vibdepth = ((value - 64) * 0.15) * 0.01; + } break; - case 0x010A + 1*0x10000 + 1*0x20000: // Vibrato delay in millisecons - Ch[MidCh].vibdelay = value ? int64_t(0.2092 * std::exp(0.0795 * (double)value)) : 0; + case 0x010A + 1*0x10000 + 1*0x20000: + if((m_synthMode & Mode_XG) != 0) // Vibrato delay in millisecons + { + Ch[MidCh].vibdelay = value ? int64_t(0.2092 * std::exp(0.0795 * (double)value)) : 0; + } break; default:/* UI.PrintLn("%s %04X <- %d (%cSB) (ch %u)", "NRPN"+!nrpn, addr, value, "LM"[MSB], MidCh);*/ diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 71f0068..ec194c6 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -726,6 +726,15 @@ public: uint8_t m_masterVolume; uint8_t m_sysExDeviceId; + enum SynthMode + { + Mode_GM = 0x00, + Mode_GS = 0x01, + Mode_XG = 0x02, + Mode_GM2 = 0x04, + }; + uint32_t m_synthMode; + MIDIEventHooks hooks; private: -- cgit v1.2.3 From de7550a4cc643b37449eb791f09b625bf1af17fb Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 22 Jun 2018 23:27:07 +0300 Subject: Added some TODOs [ci skip] --- src/adlmidi_midiplay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index dd5c9bf..3faa299 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -829,7 +829,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1 || (dev & 0xF0) != 0x10) break; unsigned mode = data[0] & 0x7F; - ADL_UNUSED(mode); + ADL_UNUSED(mode);//TODO: Hook this correctly! if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Roland System Mode Set: %02X", mode); m_synthMode = Mode_GS; @@ -841,7 +841,7 @@ bool MIDIplay::doRolandSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1 || (dev & 0xF0) != 0x10) break; unsigned value = data[0] & 0x7F; - ADL_UNUSED(value); + ADL_UNUSED(value);//TODO: Hook this correctly! if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Roland Mode Set: %02X", value); m_synthMode = Mode_GS; @@ -883,7 +883,7 @@ bool MIDIplay::doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size) if(size != 1) break; unsigned value = data[0] & 0x7F; - ADL_UNUSED(value); + ADL_UNUSED(value);//TODO: Hook this correctly! if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "SysEx: Caught Yamaha XG System On: %02X", value); m_synthMode = Mode_XG; -- cgit v1.2.3