SID: Add exception handling

Exception handling was quite missing from this code
as well. Let's fix that too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-01-30 01:16:58 -08:00
parent 8eddb7bf40
commit 034b0d20b8
3 changed files with 177 additions and 117 deletions

View file

@ -35,18 +35,27 @@
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
if(![source open:url])
return 0;
return @[];
if(![source seekable])
return 0;
return @[];
[source seek:0 whence:SEEK_END];
long size = [source tell];
[source seek:0 whence:SEEK_SET];
if(!size)
return @[];
void *data = malloc(size);
if(!data)
return @[];
[source read:data amount:size];
unsigned int subsongs = 0;
try {
SidTune *tune = new SidTune((const uint_least8_t *)data, (uint_least32_t)size);
if(!tune->getStatus()) {
@ -56,9 +65,13 @@
const SidTuneInfo *info = tune->getInfo();
unsigned int subsongs = info->songs();
subsongs = info->songs();
delete tune;
} catch (std::exception &e) {
ALog(@"Exception caught processing SID file for song count: %s", e.what());
return @[];
}
NSMutableArray *tracks = [NSMutableArray array];

View file

@ -85,6 +85,8 @@ static const char *extListStr[] = { ".str", NULL };
[source seek:0 whence:SEEK_END];
size_t fileSize = [source tell];
if(!fileSize)
return;
void *dataBytes = malloc(fileSize);
if(!dataBytes)
@ -162,6 +164,7 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
// Need this static initializer to create the static global tables that sidplayfp doesn't really lock access to
+ (void)initialize {
try {
ReSIDfpBuilder *builder = new ReSIDfpBuilder("ReSIDfp");
if(builder) {
@ -174,6 +177,9 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
delete builder;
}
} catch (std::exception &e) {
ALog(@"Exception caught while doing one-time initialization of SID player: %s", e.what());
}
}
- (BOOL)open:(id<CogSource>)s {
@ -204,6 +210,7 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
const char **extList = [extension isEqualToString:@"mus"] ? extListStr : extListEmpty;
try {
tune = new SidTune(sidTuneLoader, [currentUrl UTF8String], extList, true);
if(!tune->getStatus())
@ -260,6 +267,10 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
if(conf.playback == SidConfig::STEREO) {
n_channels = 2;
}
} catch (std::exception &e) {
ALog(@"Exception caught loading SID file: %s", e.what());
return NO;
}
double defaultFade = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
if(defaultFade < 0.0) {
@ -299,7 +310,13 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
int16_t buffer[1024 * n_channels];
int framesToRender = 1024;
int rendered = engine->play(buffer, framesToRender * n_channels) / n_channels;
int rendered = 0;
try {
rendered = engine->play(buffer, framesToRender * n_channels) / n_channels;
} catch (std::exception &e) {
ALog(@"Exception caught while playing SID file: %s", e.what());
return nil;
}
if(rendered <= 0)
return nil;
@ -343,8 +360,13 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
- (long)seek:(long)frame {
if(frame < renderedTotal) {
engine->load(tune);
renderedTotal = 0;
try {
engine->load(tune);
} catch (std::exception &e) {
ALog(@"Exception caught reloading SID tune for seeking: %s", e.what());
return -1;
}
}
int16_t sampleBuffer[1024 * 2];
@ -352,6 +374,8 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
long remain = (frame - renderedTotal) % 32;
frame /= 32;
renderedTotal /= 32;
try {
engine->fastForward(100 * 32);
while(renderedTotal < frame) {
@ -376,11 +400,16 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
if(remain)
renderedTotal += engine->play(sampleBuffer, (uint_least32_t)(remain * n_channels)) / n_channels;
} catch (std::exception &e) {
ALog(@"Exception caught while brute force seeking SID file: %s", e.what());
return -1;
}
return renderedTotal;
}
- (void)cleanUp {
try {
if(builder) {
delete builder;
builder = NULL;
@ -395,6 +424,9 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
delete tune;
tune = NULL;
}
} catch (std::exception &e) {
ALog(@"Exception caught while deleting SID player instances: %s", e.what());
}
source = nil;
if(hintAdded) {

View file

@ -30,18 +30,29 @@
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
if(![source open:url])
return 0;
return @{};
if(![source seekable])
return 0;
return @{};
[source seek:0 whence:SEEK_END];
long size = [source tell];
[source seek:0 whence:SEEK_SET];
if(!size)
return @{};
void *data = malloc(size);
if(!data)
return @{};
[source read:data amount:size];
NSString *title = @"";
NSString *titletag = @"title";
NSString *artist = @"";
try {
SidTune *tune = new SidTune((const uint_least8_t *)data, (uint_least32_t)size);
if(!tune->getStatus()) {
@ -52,11 +63,15 @@
const SidTuneInfo *info = tune->getInfo();
unsigned int count = info->numberOfInfoStrings();
NSString *title = count >= 1 ? [guess_encoding_of_string(info->infoString(0)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
NSString *titletag = info->songs() > 1 ? @"album" : @"title";
NSString *artist = count >= 2 ? [guess_encoding_of_string(info->infoString(1)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
title = count >= 1 ? [guess_encoding_of_string(info->infoString(0)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
titletag = info->songs() > 1 ? @"album" : @"title";
artist = count >= 2 ? [guess_encoding_of_string(info->infoString(1)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
delete tune;
} catch (std::exception &e) {
ALog(@"Exception caught while reading SID tags: %s", e.what());
return @{};
}
return @{titletag: title, @"artist": artist};
}