OpenMPT: Update exception handling
Make exception handling more robust and thorough. Never know what may happen, make sure to handle most cases. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
fd3e9e2b24
commit
8eddb7bf40
3 changed files with 109 additions and 84 deletions
|
@ -37,20 +37,20 @@
|
||||||
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
|
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
|
||||||
|
|
||||||
if(![source open:url])
|
if(![source open:url])
|
||||||
return 0;
|
return @[];
|
||||||
|
|
||||||
if(![source seekable])
|
if(![source seekable])
|
||||||
return 0;
|
return @[];
|
||||||
|
|
||||||
[source seek:0 whence:SEEK_END];
|
[source seek:0 whence:SEEK_END];
|
||||||
long size = [source tell];
|
long size = [source tell];
|
||||||
[source seek:0 whence:SEEK_SET];
|
[source seek:0 whence:SEEK_SET];
|
||||||
|
|
||||||
std::vector<char> data(static_cast<std::size_t>(size));
|
|
||||||
|
|
||||||
[source read:data.data() amount:size];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
std::vector<char> data(static_cast<std::size_t>(size));
|
||||||
|
|
||||||
|
[source read:data.data() amount:size];
|
||||||
|
|
||||||
std::map<std::string, std::string> ctls;
|
std::map<std::string, std::string> ctls;
|
||||||
openmpt::module *mod = new openmpt::module(data, std::clog, ctls);
|
openmpt::module *mod = new openmpt::module(data, std::clog, ctls);
|
||||||
|
|
||||||
|
@ -66,8 +66,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracks;
|
return tracks;
|
||||||
} catch(std::exception & /*e*/) {
|
} catch(std::exception &e) {
|
||||||
return 0;
|
ALog(@"Exception caught while processing with OpenMPT: %s", e.what());
|
||||||
|
return @[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,16 @@
|
||||||
#import "PlaylistController.h"
|
#import "PlaylistController.h"
|
||||||
|
|
||||||
static void g_push_archive_extensions(std::vector<std::string> &list) {
|
static void g_push_archive_extensions(std::vector<std::string> &list) {
|
||||||
static std::string archive_extensions[] = {
|
try {
|
||||||
"mdz", "mdr", "s3z", "xmz", "itz", "mptmz"
|
static std::string archive_extensions[] = {
|
||||||
};
|
"mdz", "mdr", "s3z", "xmz", "itz", "mptmz"
|
||||||
for(unsigned i = 0, j = 6; i < j; ++i) {
|
};
|
||||||
if(list.empty() || std::find(list.begin(), list.end(), archive_extensions[i]) == list.end())
|
for(unsigned i = 0, j = 6; i < j; ++i) {
|
||||||
list.push_back(archive_extensions[i]);
|
if(list.empty() || std::find(list.begin(), list.end(), archive_extensions[i]) == list.end())
|
||||||
|
list.push_back(archive_extensions[i]);
|
||||||
|
}
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught pushing archive extensions for OpenMPT: %s", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,32 +50,31 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
|
||||||
sampleRate = 192000.0;
|
sampleRate = 192000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> data(static_cast<std::size_t>(size));
|
|
||||||
|
|
||||||
[source read:data.data() amount:size];
|
|
||||||
|
|
||||||
int track_num;
|
|
||||||
if([[source.url fragment] length] == 0)
|
|
||||||
track_num = 0;
|
|
||||||
else
|
|
||||||
track_num = [[source.url fragment] intValue];
|
|
||||||
|
|
||||||
int interp = 8;
|
|
||||||
NSString *resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"];
|
|
||||||
if([resampling isEqualToString:@"zoh"])
|
|
||||||
interp = 1;
|
|
||||||
else if([resampling isEqualToString:@"blep"])
|
|
||||||
interp = 1;
|
|
||||||
else if([resampling isEqualToString:@"linear"])
|
|
||||||
interp = 2;
|
|
||||||
else if([resampling isEqualToString:@"blam"])
|
|
||||||
interp = 2;
|
|
||||||
else if([resampling isEqualToString:@"cubic"])
|
|
||||||
interp = 4;
|
|
||||||
else if([resampling isEqualToString:@"sinc"])
|
|
||||||
interp = 8;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
std::vector<char> data(static_cast<std::size_t>(size));
|
||||||
|
|
||||||
|
[source read:data.data() amount:size];
|
||||||
|
|
||||||
|
int track_num;
|
||||||
|
if([[source.url fragment] length] == 0)
|
||||||
|
track_num = 0;
|
||||||
|
else
|
||||||
|
track_num = [[source.url fragment] intValue];
|
||||||
|
|
||||||
|
int interp = 8;
|
||||||
|
NSString *resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"];
|
||||||
|
if([resampling isEqualToString:@"zoh"])
|
||||||
|
interp = 1;
|
||||||
|
else if([resampling isEqualToString:@"blep"])
|
||||||
|
interp = 1;
|
||||||
|
else if([resampling isEqualToString:@"linear"])
|
||||||
|
interp = 2;
|
||||||
|
else if([resampling isEqualToString:@"blam"])
|
||||||
|
interp = 2;
|
||||||
|
else if([resampling isEqualToString:@"cubic"])
|
||||||
|
interp = 4;
|
||||||
|
else if([resampling isEqualToString:@"sinc"])
|
||||||
|
interp = 8;
|
||||||
std::map<std::string, std::string> ctls;
|
std::map<std::string, std::string> ctls;
|
||||||
ctls["seek.sync_samples"] = "1";
|
ctls["seek.sync_samples"] = "1";
|
||||||
mod = new openmpt::module(data, std::clog, ctls);
|
mod = new openmpt::module(data, std::clog, ctls);
|
||||||
|
@ -86,7 +89,8 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
|
||||||
mod->set_render_param(openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, interp);
|
mod->set_render_param(openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, interp);
|
||||||
mod->set_render_param(openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, -1);
|
mod->set_render_param(openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, -1);
|
||||||
mod->ctl_set_boolean("render.resampler.emulate_amiga", true);
|
mod->ctl_set_boolean("render.resampler.emulate_amiga", true);
|
||||||
} catch(std::exception & /*e*/) {
|
} catch(std::exception &e) {
|
||||||
|
ALog(@"Exception caught opening module with OpenMPT: %s", e.what());
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,43 +117,57 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)readAudio {
|
- (AudioChunk *)readAudio {
|
||||||
mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0);
|
try {
|
||||||
|
mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0);
|
||||||
|
|
||||||
int frames = 1024;
|
int frames = 1024;
|
||||||
float buffer[frames * 2];
|
float buffer[frames * 2];
|
||||||
void *buf = (void *)buffer;
|
void *buf = (void *)buffer;
|
||||||
|
|
||||||
int total = 0;
|
int total = 0;
|
||||||
while(total < frames) {
|
while(total < frames) {
|
||||||
int framesToRender = 1024;
|
int framesToRender = 1024;
|
||||||
if(framesToRender > frames)
|
if(framesToRender > frames)
|
||||||
framesToRender = frames;
|
framesToRender = frames;
|
||||||
|
|
||||||
std::size_t count = mod->read_interleaved_stereo(sampleRate, framesToRender, ((float *)buf) + total * 2);
|
std::size_t count = mod->read_interleaved_stereo(sampleRate, framesToRender, ((float *)buf) + total * 2);
|
||||||
if(count == 0)
|
if(count == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
total += count;
|
total += count;
|
||||||
|
|
||||||
if(count < framesToRender)
|
if(count < framesToRender)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
||||||
|
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
||||||
|
[chunk assignSamples:buffer frameCount:total];
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught while playing with OpenMPT: %s", e.what());
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
|
||||||
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
|
||||||
[chunk assignSamples:buffer frameCount:total];
|
|
||||||
|
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (long)seek:(long)frame {
|
- (long)seek:(long)frame {
|
||||||
mod->set_position_seconds(frame / sampleRate);
|
try {
|
||||||
|
mod->set_position_seconds(frame / sampleRate);
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught while seeking with OpenMPT: %s", e.what());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)cleanUp {
|
- (void)cleanUp {
|
||||||
delete mod;
|
try {
|
||||||
|
delete mod;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught while deleting instance of OpenMPT: %s", e.what());
|
||||||
|
}
|
||||||
mod = NULL;
|
mod = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,15 +188,20 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)fileTypes {
|
+ (NSArray *)fileTypes {
|
||||||
std::vector<std::string> extensions = openmpt::get_supported_extensions();
|
try {
|
||||||
g_push_archive_extensions(extensions);
|
std::vector<std::string> extensions = openmpt::get_supported_extensions();
|
||||||
NSMutableArray *array = [NSMutableArray array];
|
g_push_archive_extensions(extensions);
|
||||||
|
NSMutableArray *array = [NSMutableArray array];
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator ext = extensions.begin(); ext != extensions.end(); ++ext) {
|
for(std::vector<std::string>::iterator ext = extensions.begin(); ext != extensions.end(); ++ext) {
|
||||||
[array addObject:[NSString stringWithUTF8String:ext->c_str()]];
|
[array addObject:[NSString stringWithUTF8String:ext->c_str()]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [NSArray arrayWithArray:array];
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught while enumerating OpenMPT file extensions: %s", e.what());
|
||||||
|
return @[];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [NSArray arrayWithArray:array];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)mimeTypes {
|
+ (NSArray *)mimeTypes {
|
||||||
|
|
|
@ -41,26 +41,26 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
|
||||||
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
|
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
|
||||||
|
|
||||||
if(![source open:url])
|
if(![source open:url])
|
||||||
return 0;
|
return @{};
|
||||||
|
|
||||||
if(![source seekable])
|
if(![source seekable])
|
||||||
return 0;
|
return @{};
|
||||||
|
|
||||||
[source seek:0 whence:SEEK_END];
|
[source seek:0 whence:SEEK_END];
|
||||||
long size = [source tell];
|
long size = [source tell];
|
||||||
[source seek:0 whence:SEEK_SET];
|
[source seek:0 whence:SEEK_SET];
|
||||||
|
|
||||||
std::vector<char> data(static_cast<std::size_t>(size));
|
|
||||||
|
|
||||||
[source read:data.data() amount:size];
|
|
||||||
|
|
||||||
int track_num;
|
|
||||||
if([[url fragment] length] == 0)
|
|
||||||
track_num = 0;
|
|
||||||
else
|
|
||||||
track_num = [[url fragment] intValue];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
std::vector<char> data(static_cast<std::size_t>(size));
|
||||||
|
|
||||||
|
[source read:data.data() amount:size];
|
||||||
|
|
||||||
|
int track_num;
|
||||||
|
if([[url fragment] length] == 0)
|
||||||
|
track_num = 0;
|
||||||
|
else
|
||||||
|
track_num = [[url fragment] intValue];
|
||||||
|
|
||||||
std::map<std::string, std::string> ctls;
|
std::map<std::string, std::string> ctls;
|
||||||
openmpt::module *mod = new openmpt::module(data, std::clog, ctls);
|
openmpt::module *mod = new openmpt::module(data, std::clog, ctls);
|
||||||
|
|
||||||
|
@ -85,8 +85,9 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
|
||||||
delete mod;
|
delete mod;
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
} catch(std::exception & /*e*/) {
|
} catch(std::exception &e) {
|
||||||
return 0;
|
ALog(@"Exception caught while reading metadata with OpenMPT: %s", e.what());
|
||||||
|
return @{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue