From bf6627aa73faefc29a5f7b4e9ca229164e81c904 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 3 Feb 2022 13:50:25 -0800 Subject: [PATCH] MIDI input: Fix general pacing issues with AU The timing of block based mode was kind of off. Now it should be just fine. Thanks to testing on Windows in foo_midi. Signed-off-by: Christopher Snowhill --- Plugins/MIDI/MIDI/AUPlayer.mm | 2 +- Plugins/MIDI/MIDI/MIDIDecoder.mm | 2 +- Plugins/MIDI/MIDI/MIDIPlayer.cpp | 55 ++++++++++++++++++++++++++------ Plugins/MIDI/MIDI/MIDIPlayer.h | 10 ++++-- Plugins/MIDI/MIDI/MSPlayer.cpp | 2 +- Plugins/MIDI/MIDI/SFPlayer.cpp | 2 +- 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/Plugins/MIDI/MIDI/AUPlayer.mm b/Plugins/MIDI/MIDI/AUPlayer.mm index 974ee4019..29b075060 100644 --- a/Plugins/MIDI/MIDI/AUPlayer.mm +++ b/Plugins/MIDI/MIDI/AUPlayer.mm @@ -375,7 +375,7 @@ bool AUPlayer::startup() initialized = true; - setFilterMode(mode); + setFilterMode(mode, reverb_chorus_disabled); return true; } diff --git a/Plugins/MIDI/MIDI/MIDIDecoder.mm b/Plugins/MIDI/MIDI/MIDIDecoder.mm index ae2957916..29dc9a619 100755 --- a/Plugins/MIDI/MIDI/MIDIDecoder.mm +++ b/Plugins/MIDI/MIDI/MIDIDecoder.mm @@ -265,7 +265,7 @@ static OSType getOSType(const char * in_) } } - player->setFilterMode( mode ); + player->setFilterMode( mode, false ); unsigned int loop_mode = framesFade ? MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force : 0; unsigned int clean_flags = midi_container::clean_flag_emidi; diff --git a/Plugins/MIDI/MIDI/MIDIPlayer.cpp b/Plugins/MIDI/MIDI/MIDIPlayer.cpp index 0e24a1b3e..a0e1fda47 100644 --- a/Plugins/MIDI/MIDI/MIDIPlayer.cpp +++ b/Plugins/MIDI/MIDI/MIDIPlayer.cpp @@ -140,7 +140,7 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) while ( uSamplesRemaining ) { unsigned long todo = uSamplesRemaining; - if (todo > count) todo = count; + if (todo > done - count) todo = done - count; if (needs_block_size && todo > needs_block_size) todo = needs_block_size; if (todo < needs_block_size) @@ -149,7 +149,7 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) into_block = todo; break; } - render( out, todo ); + render( out + done * 2, todo ); uSamplesRemaining -= todo; done += todo; uTimeCurrent += todo; @@ -171,7 +171,7 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) { midi_stream_event * me = &mStream[uStreamPosition]; - unsigned long samples_todo = me->m_timestamp - uTimeCurrent; + unsigned long samples_todo = me->m_timestamp - uTimeCurrent - into_block; if ( samples_todo ) { if ( samples_todo > count - done ) @@ -193,6 +193,7 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) } } + if (needs_block_size) { into_block += samples_todo; @@ -207,20 +208,19 @@ unsigned long MIDIPlayer::Play(float * out, unsigned long count) } else send_event_filtered( me->m_event ); - - uTimeCurrent = me->m_timestamp; } } if ( done < count ) { unsigned long samples_todo; - if ( uStreamPosition < mStream.size() ) samples_todo = -mStream[uStreamPosition].m_timestamp; + if ( uStreamPosition < mStream.size() ) samples_todo = mStream[uStreamPosition].m_timestamp; else samples_todo = uTimeEnd; samples_todo -= uTimeCurrent; - if ( samples_todo > count - done ) samples_todo = count -- done; + if ( needs_block_size ) + into_block = samples_todo; + if ( samples_todo > count - done ) + samples_todo = count - done; if ( needs_block_size && samples_todo > needs_block_size ) samples_todo = needs_block_size; if ( samples_todo >= needs_block_size ) @@ -228,6 +228,8 @@ mStream[uStreamPosition].m_timestamp; render( out + done * 2, samples_todo ); done += samples_todo; uTimeCurrent += samples_todo; + if (needs_block_size) + into_block -= samples_todo; } } @@ -413,6 +415,12 @@ void MIDIPlayer::send_event_time_filtered(uint32_t b, unsigned int time) { if (!(b & 0x80000000u)) { + if (reverb_chorus_disabled) + { + uint32_t _b = b & 0x7FF0; + if (_b == 0x5BB0 || _b == 0x5DB0) + return; + } send_event_time(b, time); } else @@ -425,9 +433,10 @@ void MIDIPlayer::send_event_time_filtered(uint32_t b, unsigned int time) } } -void MIDIPlayer::setFilterMode(filter_mode m) +void MIDIPlayer::setFilterMode(filter_mode m, bool disable_reverb_chorus) { mode = m; + reverb_chorus_disabled = disable_reverb_chorus; if (initialized) { sysex_reset(0, 0); @@ -616,6 +625,27 @@ void MIDIPlayer::sysex_reset(size_t port, unsigned int time) send_event(0xC9 + (port << 24)); } } + + if (reverb_chorus_disabled) + { + unsigned int i; + if (time) + { + for (i = 0; i < 16; ++i) + { + send_event_time(0x5BB0 + i + (port << 24), time); + send_event_time(0x5DB0 + i + (port << 24), time); + } + } + else + { + for (i = 0; i < 16; ++i) + { + send_event(0x5BB0 + i + (port << 24)); + send_event(0x5DB0 + i + (port << 24)); + } + } + } } } @@ -636,3 +666,8 @@ void MIDIPlayer::send_sysex_time_filtered(const uint8_t *data, size_t size, size sysex_reset(port, time); } } + +bool MIDIPlayer::GetLastError(std::string& p_out) +{ + return get_last_error(p_out); +} diff --git a/Plugins/MIDI/MIDI/MIDIPlayer.h b/Plugins/MIDI/MIDI/MIDIPlayer.h index c2f25353a..171e45383 100644 --- a/Plugins/MIDI/MIDI/MIDIPlayer.h +++ b/Plugins/MIDI/MIDI/MIDIPlayer.h @@ -34,12 +34,14 @@ public: // setup void setSampleRate(unsigned long rate); void setLoopMode(unsigned int mode); - void setFilterMode(filter_mode m); + void setFilterMode(filter_mode m, bool disable_reverb_chorus); bool Load(const midi_container & midi_file, unsigned subsong, unsigned loop_mode, unsigned clean_flags); unsigned long Play(float * out, unsigned long count); void Seek(unsigned long sample); + bool GetLastError(std::string& p_out); + protected: // this should return the block size that the renderer expects, otherwise 0 virtual unsigned int send_event_needs_time() { return 0; } @@ -49,6 +51,8 @@ protected: virtual void shutdown() {}; virtual bool startup() {return false;} + + virtual bool get_last_error(std::string& p_out) { return false; } // time should only be block level offset virtual void send_event_time(uint32_t b, unsigned int time) {}; @@ -58,6 +62,9 @@ protected: system_exclusive_table mSysexMap; bool initialized; filter_mode mode; + bool reverb_chorus_disabled; + + void sysex_reset(size_t port, unsigned int time); private: void send_event_filtered(uint32_t b); @@ -65,7 +72,6 @@ private: void send_event_time_filtered(uint32_t b, unsigned int time); void send_sysex_time_filtered(const uint8_t * event, size_t size, size_t port, unsigned int time); - void sysex_reset(size_t port, unsigned int time); void sysex_send_gs(size_t port, uint8_t * data, size_t size, unsigned int time); void sysex_reset_sc(uint32_t port, unsigned int time); diff --git a/Plugins/MIDI/MIDI/MSPlayer.cpp b/Plugins/MIDI/MIDI/MSPlayer.cpp index 4ec350afa..f48590dcd 100644 --- a/Plugins/MIDI/MIDI/MSPlayer.cpp +++ b/Plugins/MIDI/MIDI/MSPlayer.cpp @@ -87,7 +87,7 @@ bool MSPlayer::startup() initialized = true; - setFilterMode(mode); + setFilterMode(mode, reverb_chorus_disabled); return true; } diff --git a/Plugins/MIDI/MIDI/SFPlayer.cpp b/Plugins/MIDI/MIDI/SFPlayer.cpp index d64d29af9..2700970b2 100644 --- a/Plugins/MIDI/MIDI/SFPlayer.cpp +++ b/Plugins/MIDI/MIDI/SFPlayer.cpp @@ -255,7 +255,7 @@ bool SFPlayer::startup() initialized = true; - setFilterMode(mode); + setFilterMode(mode, reverb_chorus_disabled); return true; }