Adding a lot of MIDI files should hopefully be faster now.
parent
03b825ced3
commit
597a342838
|
@ -51,8 +51,14 @@ class midi_processor
|
|||
static bool process_lds( std::vector<uint8_t> const& p_file, midi_container & p_out );
|
||||
static bool process_gmf( std::vector<uint8_t> const& p_file, midi_container & p_out );
|
||||
static bool process_syx( std::vector<uint8_t> const& p_file, midi_container & p_out );
|
||||
|
||||
static bool process_standard_midi_count( std::vector<uint8_t> const& p_file, size_t & track_count );
|
||||
static bool process_riff_midi_count( std::vector<uint8_t> const& p_file, size_t & track_count );
|
||||
static bool process_xmi_count( std::vector<uint8_t> const& p_file, size_t & track_count );
|
||||
|
||||
public:
|
||||
static bool process_track_count( std::vector<uint8_t> const& p_file, const char * p_extension, size_t & track_count );
|
||||
|
||||
static bool process_file( std::vector<uint8_t> const& p_file, const char * p_extension, midi_container & p_out );
|
||||
|
||||
static bool process_syx_file( std::vector<uint8_t> const& p_file, midi_container & p_out );
|
||||
|
|
|
@ -67,3 +67,52 @@ bool midi_processor::process_syx_file( std::vector<uint8_t> const& p_file, midi_
|
|||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool midi_processor::process_track_count( std::vector<uint8_t> const& p_file, const char * p_extension, size_t & track_count )
|
||||
{
|
||||
track_count = 0;
|
||||
|
||||
if ( is_standard_midi( p_file ) )
|
||||
{
|
||||
return process_standard_midi_count( p_file, track_count );
|
||||
}
|
||||
else if ( is_riff_midi( p_file ) )
|
||||
{
|
||||
return process_riff_midi_count( p_file, track_count );
|
||||
}
|
||||
else if ( is_hmp( p_file ) )
|
||||
{
|
||||
track_count = 1;
|
||||
return true;
|
||||
}
|
||||
else if ( is_hmi( p_file ) )
|
||||
{
|
||||
track_count = 1;
|
||||
return true;
|
||||
}
|
||||
else if ( is_xmi( p_file ) )
|
||||
{
|
||||
return process_xmi_count( p_file, track_count );
|
||||
}
|
||||
else if ( is_mus( p_file ) )
|
||||
{
|
||||
track_count = 1;
|
||||
return true;
|
||||
}
|
||||
else if ( is_mids( p_file ) )
|
||||
{
|
||||
track_count = 1;
|
||||
return true;
|
||||
}
|
||||
else if ( is_lds( p_file, p_extension ) )
|
||||
{
|
||||
track_count = 1;
|
||||
return true;
|
||||
}
|
||||
else if ( is_gmf( p_file ) )
|
||||
{
|
||||
track_count = 1;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,43 @@ bool midi_processor::is_riff_midi( std::vector<uint8_t> const& p_file )
|
|||
return is_standard_midi( test );
|
||||
}
|
||||
|
||||
bool midi_processor::process_riff_midi_count( std::vector<uint8_t> const& p_file, size_t & track_count )
|
||||
{
|
||||
track_count = 0;
|
||||
|
||||
uint32_t file_size = p_file[ 4 ] | ( p_file[ 5 ] << 8 ) | ( p_file[ 6 ] << 16 ) | ( p_file[ 7 ] << 24 );
|
||||
|
||||
std::vector<uint8_t>::const_iterator it = p_file.begin() + 12;
|
||||
|
||||
std::vector<uint8_t>::const_iterator body_end = p_file.begin() + 8 + file_size;
|
||||
|
||||
std::vector<uint8_t> extra_buffer;
|
||||
|
||||
while ( it != body_end )
|
||||
{
|
||||
if ( body_end - it < 8 ) return false;
|
||||
uint32_t chunk_size = it[ 4 ] | ( it[ 5 ] << 8 ) | ( it[ 6 ] << 16 ) | ( it[ 7 ] << 24 );
|
||||
if ( (unsigned long)(body_end - it) < chunk_size ) return false;
|
||||
if ( it[ 0 ] == 'd' && it[ 1 ] == 'a' && it[ 2 ] == 't' && it[ 3 ] == 'a' )
|
||||
{
|
||||
std::vector<uint8_t> midi_file;
|
||||
midi_file.assign( it + 8, it + 8 + chunk_size );
|
||||
return process_standard_midi_count( midi_file, track_count );
|
||||
}
|
||||
else
|
||||
{
|
||||
it += chunk_size;
|
||||
if ( chunk_size & 1 && it != body_end ) ++it;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char * riff_tag_mappings[][2] =
|
||||
{
|
||||
{ "IALB", "album" },
|
||||
{ "IARL", "archival_location" },
|
||||
{ "IALB", "album" },
|
||||
{ "IARL", "archival_location" },
|
||||
{ "IART", "artist" },
|
||||
{ "ITRK", "tracknumber" },
|
||||
{ "ICMS", "commissioned" },
|
||||
|
|
|
@ -9,6 +9,26 @@ bool midi_processor::is_standard_midi( std::vector<uint8_t> const& p_file )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool midi_processor::process_standard_midi_count( std::vector<uint8_t> const& p_file, size_t & track_count )
|
||||
{
|
||||
track_count = 0;
|
||||
|
||||
if ( p_file[ 0 ] != 'M' || p_file[ 1 ] != 'T' || p_file[ 2 ] != 'h' || p_file[ 3 ] != 'd' ) return false;
|
||||
if ( p_file[ 4 ] != 0 || p_file[ 5 ] != 0 || p_file[ 6 ] != 0 || p_file[ 7 ] != 6 ) return false; /*throw exception_io_data("Bad MIDI header size");*/
|
||||
|
||||
std::vector<uint8_t>::const_iterator it = p_file.begin() + 8;
|
||||
|
||||
uint16_t form = ( it[0] << 8 ) | it[1];
|
||||
if ( form > 2 ) return false;
|
||||
|
||||
uint16_t track_count_16 = ( it[2] << 8 ) | it[3];
|
||||
|
||||
if ( form == 2 ) track_count = track_count_16;
|
||||
else track_count = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end, midi_container & p_out, bool needs_end_marker )
|
||||
{
|
||||
midi_track track;
|
||||
|
|
|
@ -163,9 +163,29 @@ static bool read_iff_stream( std::vector<uint8_t> const& p_file, iff_stream & p_
|
|||
return true;
|
||||
}
|
||||
|
||||
bool midi_processor::process_xmi_count( std::vector<uint8_t> const& p_file, size_t & track_count )
|
||||
{
|
||||
track_count = 0;
|
||||
|
||||
iff_stream xmi_file;
|
||||
if ( !read_iff_stream( p_file, xmi_file ) ) return false;
|
||||
|
||||
const iff_chunk & form_chunk = xmi_file.find_chunk( "FORM" );
|
||||
if ( memcmp( form_chunk.m_type, "XDIR", 4 ) ) return false; /*throw exception_io_data( "XMI IFF not XDIR type" );*/
|
||||
|
||||
const iff_chunk & cat_chunk = xmi_file.find_chunk( "CAT " );
|
||||
if ( memcmp( cat_chunk.m_type, "XMID", 4 ) ) return false; /*throw exception_io_data( "XMI CAT chunk not XMID type" );*/
|
||||
|
||||
unsigned _track_count = cat_chunk.get_chunk_count( "FORM" );
|
||||
|
||||
track_count = _track_count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool midi_processor::process_xmi( std::vector<uint8_t> const& p_file, midi_container & p_out )
|
||||
{
|
||||
iff_stream xmi_file;
|
||||
iff_stream xmi_file;
|
||||
if ( !read_iff_stream( p_file, xmi_file ) ) return false;
|
||||
|
||||
const iff_chunk & form_chunk = xmi_file.find_chunk( "FORM" );
|
||||
|
|
|
@ -40,10 +40,10 @@
|
|||
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
|
||||
|
||||
if (![source open:url])
|
||||
return 0;
|
||||
return [NSArray array];
|
||||
|
||||
if (![source seekable])
|
||||
return 0;
|
||||
return [NSArray array];
|
||||
|
||||
[source seek:0 whence:SEEK_END];
|
||||
long size = [source tell];
|
||||
|
@ -53,18 +53,16 @@
|
|||
data.resize( size );
|
||||
[source read:&data[0] amount:size];
|
||||
|
||||
midi_container midi_file;
|
||||
size_t track_count = 0;
|
||||
|
||||
if ( !midi_processor::process_file( data, [[url pathExtension] UTF8String], midi_file) )
|
||||
return 0;
|
||||
if ( !midi_processor::process_track_count( data, [[url pathExtension] UTF8String], track_count) )
|
||||
return [NSArray array];
|
||||
|
||||
long track_count = midi_file.get_subsong_count();
|
||||
|
||||
NSMutableArray *tracks = [NSMutableArray array];
|
||||
|
||||
long i;
|
||||
for (i = 0; i < track_count; i++) {
|
||||
[tracks addObject:[NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:@"#%li", midi_file.get_subsong( i )]]];
|
||||
[tracks addObject:[NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:@"#%li", i]]];
|
||||
}
|
||||
|
||||
return tracks;
|
||||
|
|
Loading…
Reference in New Issue