Various MIDI input fixes

This commit is contained in:
Chris Moeller 2015-02-21 18:09:33 -08:00
parent c17dcc01bc
commit 6a66946823
8 changed files with 142 additions and 189 deletions

View file

@ -43,8 +43,8 @@ void midi_event::copy_data( uint8_t * p_out, unsigned long p_offset, unsigned lo
p_count = std::min( p_count, max_count );
if ( p_offset < max_static_data_count )
{
unsigned long max_count = max_static_data_count - p_offset;
unsigned long count = std::min( max_count, p_count );
unsigned long _max_count = max_static_data_count - p_offset;
unsigned long count = std::min( _max_count, p_count );
memcpy( p_out, m_data + p_offset, count );
p_offset -= count;
p_count -= count;
@ -388,16 +388,16 @@ void midi_container::add_track( const midi_track & p_track )
unsigned channel = event.m_channel;
if ( device_name.length() )
{
unsigned long i, j;
for ( i = 0, j = m_device_names[ channel ].size(); i < j; ++i )
unsigned long j, k;
for ( j = 0, k = m_device_names[ channel ].size(); j < k; ++j )
{
if ( !strcmp( m_device_names[ channel ][ i ].c_str(), device_name.c_str() ) ) break;
if ( !strcmp( m_device_names[ channel ][ j ].c_str(), device_name.c_str() ) ) break;
}
if ( i < j ) port_number = i;
if ( j < k ) port_number = j;
else
{
m_device_names[ channel ].push_back( device_name );
port_number = j;
port_number = k;
}
device_name.clear();
limit_port_number( port_number );
@ -405,11 +405,11 @@ void midi_container::add_track( const midi_track & p_track )
channel += 16 * port_number;
channel %= 48;
if ( m_form != 2 ) m_channel_mask[ 0 ] |= 1 << channel;
if ( m_form != 2 ) m_channel_mask[ 0 ] |= 1ULL << channel;
else
{
m_channel_mask.resize( m_tracks.size(), 0 );
m_channel_mask[ m_tracks.size() - 1 ] |= 1 << channel;
m_channel_mask[ m_tracks.size() - 1 ] |= 1ULL << channel;
}
}
}
@ -444,11 +444,11 @@ void midi_container::add_track_event( std::size_t p_track_index, const midi_even
}
else if ( p_event.m_type == midi_event::note_on || p_event.m_type == midi_event::note_off )
{
if ( m_form != 2 ) m_channel_mask[ 0 ] |= 1 << p_event.m_channel;
if ( m_form != 2 ) m_channel_mask[ 0 ] |= 1ULL << p_event.m_channel;
else
{
m_channel_mask.resize( m_tracks.size(), 0 );
m_channel_mask[ p_track_index ] |= 1 << p_event.m_channel;
m_channel_mask[ p_track_index ] |= 1ULL << p_event.m_channel;
}
}
@ -488,16 +488,16 @@ void midi_container::apply_hackfix( unsigned hack )
for (unsigned i = 0; i < m_tracks.size(); ++i)
{
midi_track & t = m_tracks[ i ];
for ( unsigned i = 0; i < t.get_count(); )
for ( unsigned j = 0; j < t.get_count(); )
{
if ( t[ i ].m_type != midi_event::extended &&
t[ i ].m_channel == 16 )
if ( t[ j ].m_type != midi_event::extended &&
t[ j ].m_channel == 16 )
{
t.remove_event( i );
t.remove_event( j );
}
else
{
++i;
++j;
}
}
}
@ -507,16 +507,16 @@ void midi_container::apply_hackfix( unsigned hack )
for (unsigned i = 0; i < m_tracks.size(); ++i)
{
midi_track & t = m_tracks[ i ];
for ( unsigned i = 0; i < t.get_count(); )
for ( unsigned j = 0; j < t.get_count(); )
{
if ( t[ i ].m_type != midi_event::extended &&
( t[ i ].m_channel - 10 < 6 ) )
if ( t[ j ].m_type != midi_event::extended &&
( t[ j ].m_channel - 10 < 6 ) )
{
t.remove_event( i );
t.remove_event( j );
}
else
{
++i;
++j;
}
}
}
@ -626,7 +626,7 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
{
if ( !strcmp( m_device_names[ event.m_channel ][ i ].c_str(), device_names[ next_track ].c_str() ) ) break;
}
port_numbers[ next_track ] = i;
port_numbers[ next_track ] = (uint8_t) i;
device_names[ next_track ].clear();
limit_port_number( port_numbers[ next_track ] );
}
@ -649,7 +649,7 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
{
if ( !strcmp( m_device_names[ event.m_channel ][ i ].c_str(), device_names[ next_track ].c_str() ) ) break;
}
port_numbers[ next_track ] = i;
port_numbers[ next_track ] = (uint8_t) i;
device_names[ next_track ].clear();
limit_port_number( port_numbers[ next_track ] );
}
@ -666,11 +666,11 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
{
if ( event.m_data[ 1 ] == 4 || event.m_data[ 1 ] == 9 )
{
unsigned long data_count = event.get_data_count() - 2;
data.resize( data_count );
event.copy_data( &data[0], 2, data_count );
unsigned long _data_count = event.get_data_count() - 2;
data.resize( _data_count );
event.copy_data( &data[0], 2, _data_count );
device_names[ next_track ].clear();
device_names[ next_track ].assign( data.begin(), data.begin() + data_count );
device_names[ next_track ].assign( data.begin(), data.begin() + _data_count );
std::transform( device_names[ next_track ].begin(), device_names[ next_track ].end(), device_names[ next_track ].begin(), ::tolower );
}
else if ( event.m_data[ 1 ] == 0x21 )
@ -680,6 +680,24 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
limit_port_number( port_numbers[ next_track ] );
}
}
else if ( data_count == 1 && event.m_data[ 0 ] >= 0xF8 )
{
if ( device_names[ next_track ].length() )
{
unsigned long i, j;
for ( i = 0, j = m_device_names[ event.m_channel ].size(); i < j; ++i )
{
if ( !strcmp( m_device_names[ event.m_channel ][ i ].c_str(), device_names[ next_track ].c_str() ) ) break;
}
port_numbers[ next_track ] = (uint8_t) i;
device_names[ next_track ].clear();
limit_port_number( port_numbers[ next_track ] );
}
uint32_t event_code = port_numbers[ next_track ] << 24;
event_code += event.m_data[ 0 ];
p_stream.push_back( midi_stream_event( timestamp_ms, event_code ) );
}
}
}
@ -704,8 +722,8 @@ void midi_container::serialize_as_standard_midi_file( std::vector<uint8_t> & p_m
p_midi_file.push_back( 6 );
p_midi_file.push_back( 0 );
p_midi_file.push_back( m_form );
p_midi_file.push_back( (m_tracks.size() >> 8) );
p_midi_file.push_back( m_tracks.size() );
p_midi_file.push_back( (uint8_t) (m_tracks.size() >> 8) );
p_midi_file.push_back( (uint8_t) m_tracks.size() );
p_midi_file.push_back( (m_dtx >> 8) );
p_midi_file.push_back( m_dtx );
@ -716,8 +734,8 @@ void midi_container::serialize_as_standard_midi_file( std::vector<uint8_t> & p_m
unsigned char last_event_code = 0xFF;
std::size_t length_offset;
const char signature[] = "MTrk";
p_midi_file.insert( p_midi_file.end(), signature, signature + 4 );
const char _signature[] = "MTrk";
p_midi_file.insert( p_midi_file.end(), _signature, _signature + 4 );
length_offset = p_midi_file.size();
p_midi_file.push_back( 0 );
@ -770,6 +788,12 @@ void midi_container::serialize_as_standard_midi_file( std::vector<uint8_t> & p_m
p_midi_file.insert( p_midi_file.end(), data.begin(), data.begin() + data_count );
}
}
else
{
data.resize( data_count );
event.copy_data( &data[0], 1, data_count );
p_midi_file.insert( p_midi_file.end(), data.begin(), data.begin() + data_count );
}
}
}
}
@ -1168,7 +1192,21 @@ void midi_container::scan_for_loops( bool p_xmi_loops, bool p_marker_loops, bool
for ( unsigned long i = 0; i < subsong_count; ++i )
{
if ( m_timestamp_loop_start[ i ] != ~0UL && m_timestamp_loop_start[ i ] == m_timestamp_loop_end[ i ] )
unsigned long timestamp_song_end;
if ( m_form == 2 )
timestamp_song_end = m_tracks[i][m_tracks[i].get_count()-1].m_timestamp;
else
{
timestamp_song_end = 0;
for (unsigned long j = 0; j < m_tracks.size(); ++j)
{
const midi_track & track = m_tracks[j];
unsigned long timestamp = track[track.get_count()-1].m_timestamp;
if (timestamp > timestamp_song_end)
timestamp_song_end = timestamp;
}
}
if ( m_timestamp_loop_start[ i ] != ~0UL && ( ( m_timestamp_loop_start[ i ] == m_timestamp_loop_end[ i ] ) || ( m_timestamp_loop_start[ i ] == timestamp_song_end ) ) )
{
m_timestamp_loop_start[ i ] = ~0UL;
m_timestamp_loop_end[ i ] = ~0UL;

View file

@ -5,6 +5,12 @@
#include <string>
#include <vector>
#ifdef _MSC_VER
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define snprintf sprintf_s
#endif
struct midi_event
{
enum
@ -182,7 +188,7 @@ private:
return;
}
}
m_port_numbers.push_back( number );
m_port_numbers.push_back( (const uint8_t) number );
number = m_port_numbers.size() - 1;
}

View file

@ -116,8 +116,8 @@ bool midi_processor::process_hmp( std::vector<uint8_t> const& p_file, midi_conta
unsigned current_timestamp = 0;
std::vector<uint8_t> buffer;
buffer.resize( 3 );
std::vector<uint8_t> _buffer;
_buffer.resize( 3 );
std::vector<uint8_t>::const_iterator track_end = it + track_size_32;
@ -126,33 +126,33 @@ bool midi_processor::process_hmp( std::vector<uint8_t> const& p_file, midi_conta
unsigned delta = decode_hmp_delta( it, track_end );
current_timestamp += delta;
if ( it == track_end ) return false;
buffer[ 0 ] = *it++;
if ( buffer[ 0 ] == 0xFF )
_buffer[ 0 ] = *it++;
if ( _buffer[ 0 ] == 0xFF )
{
if ( it == track_end ) return false;
buffer[ 1 ] = *it++;
_buffer[ 1 ] = *it++;
int meta_count = decode_delta( it, track_end );
if ( meta_count < 0 ) return false; /*throw exception_io_data( "Invalid HMP meta message" );*/
if ( track_end - it < meta_count ) return false;
buffer.resize( meta_count + 2 );
std::copy( it, it + meta_count, buffer.begin() + 2 );
_buffer.resize( meta_count + 2 );
std::copy( it, it + meta_count, _buffer.begin() + 2 );
it += meta_count;
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, &buffer[0], meta_count + 2 ) );
if ( buffer[ 1 ] == 0x2F ) break;
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, &_buffer[0], meta_count + 2 ) );
if ( _buffer[ 1 ] == 0x2F ) break;
}
else if ( buffer[ 0 ] >= 0x80 && buffer[ 0 ] <= 0xEF )
else if ( _buffer[ 0 ] >= 0x80 && _buffer[ 0 ] <= 0xEF )
{
unsigned bytes_read = 2;
switch ( buffer[ 0 ] & 0xF0 )
switch ( _buffer[ 0 ] & 0xF0 )
{
case 0xC0:
case 0xD0:
bytes_read = 1;
}
if ( (unsigned long)(track_end - it) < bytes_read ) return false;
std::copy( it, it + bytes_read, buffer.begin() + 1 );
std::copy( it, it + bytes_read, _buffer.begin() + 1 );
it += bytes_read;
track.add_event( midi_event( current_timestamp, (midi_event::event_type)( ( buffer[ 0 ] >> 4 ) - 8 ), buffer[ 0 ] & 0x0F, &buffer[1], bytes_read ) );
track.add_event( midi_event( current_timestamp, (midi_event::event_type)( ( _buffer[ 0 ] >> 4 ) - 8 ), _buffer[ 0 ] & 0x0F, &_buffer[1], bytes_read ) );
}
else return false; /*throw exception_io_data( "Unexpected status code in HMP track" );*/
}

View file

@ -351,6 +351,7 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
if ( end - it < 2 ) return false;
patch_count = it[ 0 ] | ( it[ 1 ] << 8 );
if ( !patch_count ) return false;
it += 2;
patches.resize( patch_count );
if ( end - it < 46 * patch_count ) return false;
@ -404,6 +405,7 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
if ( end - it < 2 ) return false;
position_count = it[ 0 ] | ( it[ 1 ] << 8 );
if ( !position_count ) return false;
it += 2;
positions.resize( 9 * position_count );
if ( end - it < 3 * position_count ) return false;
@ -573,16 +575,16 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
// handle channel delay
for(chan = 0; chan < 9; ++chan)
{
channel_state * c = &channel[chan];
if(c->chancheat.chandelay)
channel_state * _c = &channel[chan];
if(_c->chancheat.chandelay)
{
if(!(--c->chancheat.chandelay))
if(!(--_c->chancheat.chandelay))
{
playsound( current_instrument, patches, last_note, last_channel, last_instrument, last_volume, last_sent_volume,
#ifdef ENABLE_WHEEL
last_pitch_wheel,
#endif
c, allvolume, current_timestamp, c->chancheat.sound, chan, c->chancheat.high, tracks[ chan ] );
_c, allvolume, current_timestamp, _c->chancheat.sound, chan, _c->chancheat.high, tracks[ chan ] );
ticks_without_notes[ last_channel[ chan ] ] = 0;
}
}
@ -597,24 +599,24 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
}
vbreak = false;
for(unsigned chan = 0; chan < 9; chan++)
for(unsigned _chan = 0; _chan < 9; _chan++)
{
channel_state * c = &channel[chan];
if(!c->packwait)
channel_state * _c = &channel[_chan];
if(!_c->packwait)
{
unsigned short patnum = positions[posplay * 9 + chan].pattern_number;
unsigned char transpose = positions[posplay * 9 + chan].transpose;
unsigned short patnum = positions[posplay * 9 + _chan].pattern_number;
unsigned char transpose = positions[posplay * 9 + _chan].transpose;
if ( (unsigned long)(patnum + c->packpos) >= patterns.size() ) return false; /*throw exception_io_data( "Invalid LDS pattern number" );*/
if ( (unsigned long)(patnum + _c->packpos) >= patterns.size() ) return false; /*throw exception_io_data( "Invalid LDS pattern number" );*/
unsigned comword = patterns[patnum + c->packpos];
unsigned comword = patterns[patnum + _c->packpos];
unsigned comhi = comword >> 8;
unsigned comlo = comword & 0xff;
if(comword)
{
if(comhi == 0x80)
{
c->packwait = comlo;
_c->packwait = comlo;
}
else if(comhi >= 0x80)
{
@ -622,13 +624,13 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
case 0xff:
{
unsigned volume = ( comlo & 0x3F ) * 127 / 63;
last_volume[ chan ] = volume;
if ( volume != last_sent_volume[ last_channel[ chan ] ] )
last_volume[ _chan ] = volume;
if ( volume != last_sent_volume[ last_channel[ _chan ] ] )
{
buffer[ 0 ] = 7;
buffer[ 1 ] = volume;
tracks[ chan ].add_event( midi_event( current_timestamp, midi_event::control_change, last_channel[ chan ], buffer, 2 ) );
last_sent_volume[ last_channel [ chan ] ] = volume;
tracks[ _chan ].add_event( midi_event( current_timestamp, midi_event::control_change, last_channel[ _chan ], buffer, 2 ) );
last_sent_volume[ last_channel [ _chan ] ] = volume;
}
}
break;
@ -636,14 +638,14 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
tempo = comword & 0x3f;
break;
case 0xfd:
c->nextvol = comlo;
_c->nextvol = comlo;
break;
case 0xfc:
playing = false;
// in real player there's also full keyoff here, but we don't need it
break;
case 0xfb:
c->keycount = 1;
_c->keycount = 1;
break;
case 0xfa:
vbreak = true;
@ -662,24 +664,24 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
break;
case 0xf8:
#ifdef ENABLE_WHEEL
c->lasttune = 0;
_c->lasttune = 0;
#endif
break;
case 0xf7:
#ifdef ENABLE_VIB
c->vibwait = 0;
// PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2;
c->vibspeed = (comlo >> 4) + 2;
c->vibrate = (comlo & 15) + 1;
_c->vibwait = 0;
// PASCAL: _c->vibspeed = ((comlo >> 4) & 15) + 2;
_c->vibspeed = (comlo >> 4) + 2;
_c->vibrate = (comlo & 15) + 1;
#endif
break;
case 0xf6:
#ifdef ENABLE_WHEEL
c->glideto = comlo;
_c->glideto = comlo;
#endif
break;
case 0xf5:
c->finetune = comlo;
_c->finetune = comlo;
break;
case 0xf4:
if(!hardfade) {
@ -692,22 +694,22 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
break;
case 0xf2:
#ifdef ENABLE_TREM
c->trmstay = comlo;
_c->trmstay = comlo;
#endif
break;
case 0xf1:
buffer[ 0 ] = 10;
buffer[ 1 ] = ( comlo & 0x3F ) * 127 / 63;
tracks[ chan ].add_event( midi_event( current_timestamp, midi_event::control_change, last_channel[ chan ], buffer, 2 ) );
tracks[ _chan ].add_event( midi_event( current_timestamp, midi_event::control_change, last_channel[ _chan ], buffer, 2 ) );
break;
case 0xf0:
buffer[ 0 ] = comlo & 0x7F;
tracks[ chan ].add_event( midi_event( current_timestamp, midi_event::program_change, last_channel[ chan ], buffer, 1 ) );
tracks[ _chan ].add_event( midi_event( current_timestamp, midi_event::program_change, last_channel[ _chan ], buffer, 1 ) );
break;
default:
#ifdef ENABLE_WHEEL
if(comhi < 0xa0)
c->glideto = comhi & 0x1f;
_c->glideto = comhi & 0x1f;
#endif
break;
}
@ -733,28 +735,28 @@ bool midi_processor::process_lds( std::vector<uint8_t> const& p_file, midi_conta
high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4;
*/
if( !channel_delay[ chan ] )
if( !channel_delay[ _chan ] )
{
playsound( current_instrument, patches, last_note, last_channel, last_instrument, last_volume, last_sent_volume,
#ifdef ENABLE_WHEEL
last_pitch_wheel,
#endif
c, allvolume, current_timestamp, sound, chan, high, tracks[ chan ] );
ticks_without_notes[ last_channel[ chan ] ] = 0;
_c, allvolume, current_timestamp, sound, _chan, high, tracks[ _chan ] );
ticks_without_notes[ last_channel[ _chan ] ] = 0;
}
else
{
c->chancheat.chandelay = channel_delay[chan];
c->chancheat.sound = sound;
c->chancheat.high = high;
_c->chancheat.chandelay = channel_delay[_chan];
_c->chancheat.sound = sound;
_c->chancheat.high = high;
}
}
}
c->packpos++;
_c->packpos++;
}
else
{
c->packwait--;
_c->packwait--;
}
}

View file

@ -11,7 +11,7 @@ bool midi_processor::is_mus( std::vector<uint8_t> const& p_file )
uint16_t length = p_file[ 4 ] | ( p_file[ 5 ] << 8 );
uint16_t offset = p_file[ 6 ] | ( p_file[ 7 ] << 8 );
uint16_t instrument_count = p_file[ 12 ] | ( p_file[ 13 ] << 8 );
if ( offset >= 16 + instrument_count * 2 && offset < 16 + instrument_count * 4 && offset + length <= p_file.size() ) return true;
if ( offset >= 16 + instrument_count * 2 && offset < 16 + instrument_count * 4 && (size_t)(offset + length) <= p_file.size() ) return true;
return false;
}
@ -35,7 +35,7 @@ bool midi_processor::process_mus( std::vector<uint8_t> const& p_file, midi_conta
uint8_t velocity_levels[ 16 ] = { 0 };
if ( offset >= p_file.size() || offset + length > p_file.size() )
if ( (size_t)offset >= p_file.size() || (size_t)(offset + length) > p_file.size() )
return false;
std::vector<uint8_t>::const_iterator it = p_file.begin() + offset, end = p_file.begin() + offset + length;

View file

@ -93,9 +93,11 @@ bool midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
break;
}
}
else if ( event_code == 0xFB || event_code == 0xFC )
else if ( event_code >= 0xF8 && event_code <= 0xFE )
{
/*console::formatter() << "MIDI " << ( ( event_code == 0xFC ) ? "stop" : "start" ) << " status code ignored";*/
/* Sequencer specific events, single byte */
buffer[ 0 ] = event_code;
track.add_event( midi_event( current_timestamp, midi_event::extended, 0, &buffer[0], 1 ) );
}
else return false; /*throw exception_io_data("Unhandled MIDI status code");*/
}

View file

@ -15,23 +15,6 @@
#define _countof(arr) (sizeof(arr) / sizeof((arr)[0]))
static const uint8_t sysex_gm_reset[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7 };
static const uint8_t sysex_gm2_reset[]= { 0xF0, 0x7E, 0x7F, 0x09, 0x03, 0xF7 };
static const uint8_t sysex_gs_reset[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7 };
static const uint8_t sysex_xg_reset[] = { 0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7 };
static bool is_gs_reset(const unsigned char * data, unsigned long size)
{
if ( size != _countof( sysex_gs_reset ) ) return false;
if ( memcmp( data, sysex_gs_reset, 5 ) != 0 ) return false;
if ( memcmp( data + 7, sysex_gs_reset + 7, 2 ) != 0 ) return false;
if ( ( ( data[ 5 ] + data[ 6 ] + 1 ) & 127 ) != data[ 9 ] ) return false;
if ( data[ 10 ] != sysex_gs_reset[ 10 ] ) return false;
return true;
}
struct Cached_SoundFont
{
unsigned long ref_count;
@ -247,29 +230,8 @@ void BMPlayer::send_event(uint32_t b)
unsigned event_length = ( command == 0xC0 || command == 0xD0 ) ? 2 : 3;
channel += 16 * port;
channel %= 48;
if ( command == 0xB0 && event[ 1 ] == 0x20 ) return;
if ( bank_lsb_overridden && command == 0xB0 && event[ 1 ] == 0x20 ) return;
BASS_MIDI_StreamEvents( _stream, BASS_MIDI_EVENTS_RAW + 1 + channel, event, event_length );
if ( command == 0xB0 && event[ 1 ] == 0 )
{
if ( synth_mode == mode_xg )
{
if ( event[ 2 ] == 127 ) drum_channels[ channel ] = 1;
else drum_channels[ channel ] = 0;
}
else if ( synth_mode == mode_gm2 )
{
if ( event[ 2 ] == 120 ) drum_channels[ channel ] = 1;
else if ( event[ 2 ] == 121 ) drum_channels[ channel ] = 0;
}
}
else if ( command == 0xC0 )
{
unsigned channel_masked = channel & 0x0F;
unsigned drum_channel = drum_channels[ channel ];
if ( ( channel_masked == 9 && !drum_channel ) ||
( channel_masked != 9 && drum_channel ) )
BASS_MIDI_StreamEvent( _stream, channel, MIDI_EVENT_DRUMS, drum_channel );
}
}
else
{
@ -279,38 +241,6 @@ void BMPlayer::send_event(uint32_t b)
mSysexMap.get_entry( n, data, size, port );
if ( port > 2 ) port = 2;
BASS_MIDI_StreamEvents( _stream, BASS_MIDI_EVENTS_RAW, data, (unsigned int) size );
if ( ( size == _countof( sysex_gm_reset ) && !memcmp( data, sysex_gm_reset, _countof( sysex_gm_reset ) ) ) ||
( size == _countof( sysex_gm2_reset ) && !memcmp( data, sysex_gm2_reset, _countof( sysex_gm2_reset ) ) ) ||
is_gs_reset( data, size ) ||
( size == _countof( sysex_xg_reset ) && !memcmp( data, sysex_xg_reset, _countof( sysex_xg_reset ) ) ) )
{
reset_parameters();
synth_mode = ( size == _countof( sysex_xg_reset ) ) ? mode_xg :
( size == _countof( sysex_gs_reset ) ) ? mode_gs :
( data [4] == 0x01 ) ? mode_gm :
mode_gm2;
}
else if ( synth_mode == mode_gs && size == 11 &&
data [0] == 0xF0 && data [1] == 0x41 && data [3] == 0x42 &&
data [4] == 0x12 && data [5] == 0x40 && (data [6] & 0xF0) == 0x10 &&
data [10] == 0xF7)
{
if (data [7] == 2)
{
// GS MIDI channel to part assign
gs_part_to_ch [ port ][ data [6] & 15 ] = data [8];
}
else if ( data [7] == 0x15 )
{
// GS part to rhythm allocation
unsigned int drum_channel = gs_part_to_ch [ port ][ data [6] & 15 ];
if ( drum_channel < 16 )
{
drum_channel += 16 * port;
drum_channels [ drum_channel ] = data [8];
}
}
}
}
}
@ -628,31 +558,16 @@ bool BMPlayer::startup()
reset_parameters();
synth_mode = mode_gm;
return true;
}
void BMPlayer::reset_parameters()
{
static const uint8_t part_to_ch[16] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15 };
memset( drum_channels, 0, sizeof( drum_channels ) );
drum_channels[ 9 ] = 1;
drum_channels[ 25 ] = 1;
drum_channels[ 41 ] = 1;
for ( unsigned long i = 0; i < 3; i++ )
memcpy( gs_part_to_ch[ i ], part_to_ch, sizeof( gs_part_to_ch[ i ] ) );
if ( _stream )
{
for ( unsigned i = 0; i < 48; ++i )
{
BASS_MIDI_StreamEvent( _stream, i, MIDI_EVENT_DRUMS, drum_channels[ i ] );
}
}
bank_lsb_overridden = false;
for ( unsigned int i = 0; i < 48; ++i )
{
if (bank_lsb_override[i])
bank_lsb_overridden = true;
BASS_MIDI_StreamEvent( _stream, i, MIDI_EVENT_BANK_LSB, bank_lsb_override[i] );
}
}

View file

@ -38,17 +38,7 @@ private:
bool bSincInterpolation;
enum
{
mode_gm = 0,
mode_gm2,
mode_gs,
mode_xg
}
synth_mode;
uint8_t gs_part_to_ch[3][16];
uint8_t drum_channels[48];
bool bank_lsb_overridden;
uint8_t bank_lsb_override[48];
};