MIDI: Add exception handling

Both the midi_processing and the various players may
throw exceptions, so we should check for these too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-01-30 00:52:26 -08:00
parent d835c252fa
commit cd95cd68f8
3 changed files with 193 additions and 155 deletions

View file

@ -11,6 +11,8 @@
#import <midi_processing/midi_processor.h> #import <midi_processing/midi_processor.h>
#import "Logging.h"
@implementation MIDIContainer @implementation MIDIContainer
+ (NSArray *)fileTypes { + (NSArray *)fileTypes {
@ -45,14 +47,19 @@
long size = [source tell]; long size = [source tell];
[source seek:0 whence:SEEK_SET]; [source seek:0 whence:SEEK_SET];
size_t track_count = 0;
try {
std::vector<uint8_t> data; std::vector<uint8_t> data;
data.resize(size); data.resize(size);
[source read:&data[0] amount:size]; [source read:&data[0] amount:size];
size_t track_count = 0;
if(!midi_processor::process_track_count(data, [[url pathExtension] UTF8String], track_count)) if(!midi_processor::process_track_count(data, [[url pathExtension] UTF8String], track_count))
return @[]; return @[];
} catch (std::exception &e) {
ALog(@"Exception caught processing MIDI track count: %s", e.what());
return @[];
}
NSMutableArray *tracks = [NSMutableArray array]; NSMutableArray *tracks = [NSMutableArray array];

View file

@ -55,6 +55,10 @@ static OSType getOSType(const char *in_) {
source = s; source = s;
unsigned long loopStart = ~0;
unsigned long loopEnd = ~0;
try {
std::vector<uint8_t> file_data; std::vector<uint8_t> file_data;
[s seek:0 whence:SEEK_END]; [s seek:0 whence:SEEK_END];
@ -75,8 +79,12 @@ static OSType getOSType(const char *in_) {
framesLength = midi_file.get_timestamp_end(track_num, true); framesLength = midi_file.get_timestamp_end(track_num, true);
unsigned long loopStart = midi_file.get_timestamp_loop_start(track_num, true); loopStart = midi_file.get_timestamp_loop_start(track_num, true);
unsigned long loopEnd = midi_file.get_timestamp_loop_end(track_num, true); loopEnd = midi_file.get_timestamp_loop_end(track_num, true);
} catch (std::exception &e) {
ALog(@"Exception caught while reading MIDI file: %s", e.what());
return NO;
}
if(loopStart == ~0UL) loopStart = 0; if(loopStart == ~0UL) loopStart = 0;
if(loopEnd == ~0UL) loopEnd = framesLength; if(loopEnd == ~0UL) loopEnd = framesLength;
@ -206,6 +214,7 @@ static OSType getOSType(const char *in_) {
} }
} }
try {
if(!plugin || [plugin isEqualToString:@"BASSMIDI"]) { if(!plugin || [plugin isEqualToString:@"BASSMIDI"]) {
bmplayer = new BMPlayer; bmplayer = new BMPlayer;
@ -273,6 +282,10 @@ 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;
} catch (std::exception &e) {
ALog(@"Exception caught while loading MIDI file into player: %s", e.what());
return NO;
}
return YES; return YES;
} }
@ -287,6 +300,7 @@ static OSType getOSType(const char *in_) {
return nil; return nil;
} }
try {
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)
@ -347,6 +361,10 @@ static OSType getOSType(const char *in_) {
[chunk assignSamples:buffer frameCount:frames]; [chunk assignSamples:buffer frameCount:frames];
return chunk; return chunk;
} catch (std::exception &e) {
ALog(@"Exception caught while playing MIDI file: %s", e.what());
return nil;
}
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {
@ -355,7 +373,13 @@ static OSType getOSType(const char *in_) {
return -1; return -1;
} }
try {
player->Seek(frame); player->Seek(frame);
} catch (std::exception &e) {
ALog(@"Exception caught while seeking in MIDI file: %s", e.what());
framesRead = 0;
return -1;
}
framesRead = frame; framesRead = frame;

View file

@ -12,6 +12,8 @@
#import <midi_processing/midi_processor.h> #import <midi_processing/midi_processor.h>
#import "Logging.h"
@implementation MIDIMetadataReader @implementation MIDIMetadataReader
+ (NSArray *)fileTypes { + (NSArray *)fileTypes {
@ -49,6 +51,7 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
long size = [source tell]; long size = [source tell];
[source seek:0 whence:SEEK_SET]; [source seek:0 whence:SEEK_SET];
try {
std::vector<uint8_t> data; std::vector<uint8_t> data;
data.resize(size); data.resize(size);
[source read:&data[0] amount:size]; [source read:&data[0] amount:size];
@ -94,6 +97,10 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} }
return dict; return dict;
} catch (std::exception &e) {
ALog(@"Exception caught while reading MIDI metadata: %s", e.what());
return [NSDictionary dictionary];
}
} }
@end @end