MIDI decoder only initializes synthesizer if decoding actually begins, which should speed up loading file metadata.
This commit is contained in:
parent
cd3901f00d
commit
a1fab29749
2 changed files with 56 additions and 38 deletions
|
@ -16,6 +16,9 @@ class AUPlayer;
|
|||
class BMPlayer;
|
||||
|
||||
@interface MIDIDecoder : NSObject <CogDecoder> {
|
||||
id<CogSource> source;
|
||||
int track_num;
|
||||
|
||||
BMPlayer* bmplayer;
|
||||
AUPlayer* auplayer;
|
||||
MIDIPlayer* player;
|
||||
|
|
|
@ -47,6 +47,8 @@ static OSType getOSType(const char * in_)
|
|||
return NO;
|
||||
}
|
||||
|
||||
source = s;
|
||||
|
||||
std::vector<uint8_t> file_data;
|
||||
|
||||
[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) )
|
||||
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 );
|
||||
|
||||
|
@ -89,13 +91,37 @@ static OSType getOSType(const char * in_)
|
|||
|
||||
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 = @"";
|
||||
|
||||
if ( [[s url] isFileURL] )
|
||||
if ( [[source url] isFileURL] )
|
||||
{
|
||||
// Let's check for a SoundFont
|
||||
NSArray * extensions = [NSArray arrayWithObjects:@"sflist", @"sf2pack", @"sf2", nil];
|
||||
NSString * filePath = [[s url] path];
|
||||
NSString * filePath = [[source url] path];
|
||||
NSString * fileNameBase = [filePath lastPathComponent];
|
||||
filePath = [filePath stringByDeletingLastPathComponent];
|
||||
soundFontPath = [filePath stringByAppendingPathComponent:fileNameBase];
|
||||
|
@ -226,34 +252,21 @@ static OSType getOSType(const char * in_)
|
|||
if ( !player->Load( midi_file, track_num, loop_mode, clean_flags) )
|
||||
return NO;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
- (int)readAudio:(void *)buf frames:(UInt32)frames
|
||||
{
|
||||
BOOL repeatone = IsRepeatOneSet();
|
||||
long localFramesLength = framesLength;
|
||||
long localTotalFrames = totalFrames;
|
||||
|
||||
if (!player)
|
||||
{
|
||||
if (![self initDecoder])
|
||||
return -1;
|
||||
}
|
||||
|
||||
player->SetLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0);
|
||||
|
||||
if ( !repeatone && framesRead >= localTotalFrames )
|
||||
|
@ -320,6 +333,8 @@ static OSType getOSType(const char * in_)
|
|||
{
|
||||
delete player;
|
||||
player = NULL;
|
||||
[source close];
|
||||
source = nil;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
|
Loading…
Reference in a new issue