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 <kode54@gmail.com>
CQTexperiment
Christopher Snowhill 2022-02-03 13:50:25 -08:00
parent e820e2bbd6
commit bf6627aa73
6 changed files with 57 additions and 16 deletions

View File

@ -375,7 +375,7 @@ bool AUPlayer::startup()
initialized = true;
setFilterMode(mode);
setFilterMode(mode, reverb_chorus_disabled);
return true;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -87,7 +87,7 @@ bool MSPlayer::startup()
initialized = true;
setFilterMode(mode);
setFilterMode(mode, reverb_chorus_disabled);
return true;
}

View File

@ -255,7 +255,7 @@ bool SFPlayer::startup()
initialized = true;
setFilterMode(mode);
setFilterMode(mode, reverb_chorus_disabled);
return true;
}