MIDI decoder only initializes synthesizer if decoding actually begins, which should speed up loading file metadata.

This commit is contained in:
Chris Moeller 2016-06-29 22:12:58 -07:00
parent cd3901f00d
commit a1fab29749
2 changed files with 56 additions and 38 deletions

View file

@ -16,6 +16,9 @@ class AUPlayer;
class BMPlayer; class BMPlayer;
@interface MIDIDecoder : NSObject <CogDecoder> { @interface MIDIDecoder : NSObject <CogDecoder> {
id<CogSource> source;
int track_num;
BMPlayer* bmplayer; BMPlayer* bmplayer;
AUPlayer* auplayer; AUPlayer* auplayer;
MIDIPlayer* player; MIDIPlayer* player;

View file

@ -47,6 +47,8 @@ static OSType getOSType(const char * in_)
return NO; return NO;
} }
source = s;
std::vector<uint8_t> file_data; std::vector<uint8_t> file_data;
[s seek:0 whence:SEEK_END]; [s seek:0 whence:SEEK_END];
@ -58,7 +60,7 @@ static OSType getOSType(const char * in_)
if ( !midi_processor::process_file(file_data, [[[s url] pathExtension] UTF8String], midi_file) ) if ( !midi_processor::process_file(file_data, [[[s url] pathExtension] UTF8String], midi_file) )
return NO; return NO;
int track_num = [[[s url] fragment] intValue]; //What if theres no fragment? Assuming we get 0. track_num = [[[s url] fragment] intValue]; //What if theres no fragment? Assuming we get 0.
midi_file.scan_for_loops( true, true, true ); midi_file.scan_for_loops( true, true, true );
@ -89,13 +91,37 @@ static OSType getOSType(const char * in_)
totalFrames = framesLength + framesFade; totalFrames = framesLength + framesFade;
framesRead = 0;
[self willChangeValueForKey:@"properties"];
[self didChangeValueForKey:@"properties"];
return YES;
}
- (NSDictionary *)properties
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:0], @"bitrate",
[NSNumber numberWithFloat:44100], @"sampleRate",
[NSNumber numberWithLong:totalFrames], @"totalFrames",
[NSNumber numberWithInt:32], @"bitsPerSample",
[NSNumber numberWithBool:YES], @"floatingPoint",
[NSNumber numberWithInt:2], @"channels", //output from gme_play is in stereo
[NSNumber numberWithBool:YES], @"seekable",
@"host", @"endian",
nil];
}
- (BOOL)initDecoder
{
NSString * soundFontPath = @""; NSString * soundFontPath = @"";
if ( [[s url] isFileURL] ) if ( [[source url] isFileURL] )
{ {
// Let's check for a SoundFont // Let's check for a SoundFont
NSArray * extensions = [NSArray arrayWithObjects:@"sflist", @"sf2pack", @"sf2", nil]; NSArray * extensions = [NSArray arrayWithObjects:@"sflist", @"sf2pack", @"sf2", nil];
NSString * filePath = [[s url] path]; NSString * filePath = [[source url] path];
NSString * fileNameBase = [filePath lastPathComponent]; NSString * fileNameBase = [filePath lastPathComponent];
filePath = [filePath stringByDeletingLastPathComponent]; filePath = [filePath stringByDeletingLastPathComponent];
soundFontPath = [filePath stringByAppendingPathComponent:fileNameBase]; soundFontPath = [filePath stringByAppendingPathComponent:fileNameBase];
@ -118,24 +144,24 @@ static OSType getOSType(const char * in_)
else else
soundFontPath = @""; soundFontPath = @"";
} }
DLog(@"Length: %li", totalFrames); DLog(@"Length: %li", totalFrames);
DLog(@"Track num: %i", track_num); DLog(@"Track num: %i", track_num);
NSString * plugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"]; NSString * plugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"];
if (!plugin || [plugin isEqualToString:@"BASSMIDI"]) if (!plugin || [plugin isEqualToString:@"BASSMIDI"])
{ {
bmplayer = new BMPlayer; bmplayer = new BMPlayer;
bool resampling_sinc = false; bool resampling_sinc = false;
NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"]; NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"];
if ([resampling isEqualToString:@"sinc"]) if ([resampling isEqualToString:@"sinc"])
resampling_sinc = true; resampling_sinc = true;
bmplayer->setSincInterpolation( resampling_sinc ); bmplayer->setSincInterpolation( resampling_sinc );
bmplayer->setSampleRate( 44100 ); bmplayer->setSampleRate( 44100 );
if ( [soundFontPath length] ) if ( [soundFontPath length] )
bmplayer->setFileSoundFont( [soundFontPath UTF8String] ); bmplayer->setFileSoundFont( [soundFontPath UTF8String] );
@ -151,7 +177,7 @@ static OSType getOSType(const char * in_)
msplayer->set_bank([[plugin substringFromIndex:4] intValue]); msplayer->set_bank([[plugin substringFromIndex:4] intValue]);
msplayer->set_extp(1); msplayer->set_extp(1);
msplayer->setSampleRate( 44100 ); msplayer->setSampleRate( 44100 );
} }
else if ([[plugin substringToIndex:5] isEqualToString:@"OPL3W"]) else if ([[plugin substringToIndex:5] isEqualToString:@"OPL3W"])
@ -162,9 +188,9 @@ static OSType getOSType(const char * in_)
msplayer->set_synth(1); msplayer->set_synth(1);
msplayer->set_bank([[plugin substringFromIndex:5] intValue]); msplayer->set_bank([[plugin substringFromIndex:5] intValue]);
msplayer->set_extp(1); msplayer->set_extp(1);
msplayer->setSampleRate( 44100 ); msplayer->setSampleRate( 44100 );
} }
else else
@ -179,7 +205,7 @@ static OSType getOSType(const char * in_)
if (componentManufacturer == 'rolD' && componentSubType == 'Sc55') if (componentManufacturer == 'rolD' && componentSubType == 'Sc55')
{ {
SCPlayer * scplayer = new SCPlayer; SCPlayer * scplayer = new SCPlayer;
SCPlayer::sc_mode mode = SCPlayer::sc_sc55; SCPlayer::sc_mode mode = SCPlayer::sc_sc55;
NSString * flavor = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.flavor"]; NSString * flavor = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.flavor"];
if ([flavor isEqualToString:@"gm"]) if ([flavor isEqualToString:@"gm"])
@ -206,16 +232,16 @@ static OSType getOSType(const char * in_)
else else
{ {
auplayer = new AUPlayer; auplayer = new AUPlayer;
auplayer->setComponent(componentSubType, componentManufacturer); auplayer->setComponent(componentSubType, componentManufacturer);
auplayer->setSampleRate( 44100 ); auplayer->setSampleRate( 44100 );
if ( [soundFontPath length] ) if ( [soundFontPath length] )
{ {
auplayer->setSoundFont( [soundFontPath UTF8String] ); auplayer->setSoundFont( [soundFontPath UTF8String] );
soundFontsAssigned = YES; soundFontsAssigned = YES;
} }
player = auplayer; player = auplayer;
} }
} }
@ -226,26 +252,7 @@ static OSType getOSType(const char * in_)
if ( !player->Load( midi_file, track_num, loop_mode, clean_flags) ) if ( !player->Load( midi_file, track_num, loop_mode, clean_flags) )
return NO; return NO;
framesRead = 0; return YES;
[self willChangeValueForKey:@"properties"];
[self didChangeValueForKey:@"properties"];
return YES;
}
- (NSDictionary *)properties
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:0], @"bitrate",
[NSNumber numberWithFloat:44100], @"sampleRate",
[NSNumber numberWithLong:totalFrames], @"totalFrames",
[NSNumber numberWithInt:32], @"bitsPerSample",
[NSNumber numberWithBool:YES], @"floatingPoint",
[NSNumber numberWithInt:2], @"channels", //output from gme_play is in stereo
[NSNumber numberWithBool:YES], @"seekable",
@"host", @"endian",
nil];
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames - (int)readAudio:(void *)buf frames:(UInt32)frames
@ -254,6 +261,12 @@ static OSType getOSType(const char * in_)
long localFramesLength = framesLength; long localFramesLength = framesLength;
long localTotalFrames = totalFrames; long localTotalFrames = totalFrames;
if (!player)
{
if (![self initDecoder])
return -1;
}
player->SetLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0); player->SetLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0);
if ( !repeatone && framesRead >= localTotalFrames ) if ( !repeatone && framesRead >= localTotalFrames )
@ -320,6 +333,8 @@ static OSType getOSType(const char * in_)
{ {
delete player; delete player;
player = NULL; player = NULL;
[source close];
source = nil;
} }
- (void)dealloc - (void)dealloc