Fix outstanding crashes and issues with CUE reader

CUE reader was crashing due to nil metadata pointers, which the new
inplace initializer I was using didn't like. Change it to use a mutable
regular dictionary, and only add items if they're not nil.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
CQTexperiment
Christopher Snowhill 2022-02-11 06:03:45 -08:00
parent d7becdf01a
commit d5aecaf6a2
3 changed files with 38 additions and 17 deletions

View File

@ -17,6 +17,8 @@
id<CogSource> source; id<CogSource> source;
id<CogDecoder> decoder; id<CogDecoder> decoder;
NSURL *sourceURL;
int bytesPerFrame; // Number of bytes per frame, ie channels * (bitsPerSample/8) int bytesPerFrame; // Number of bytes per frame, ie channels * (bitsPerSample/8)
long framePosition; // Current position in frames. long framePosition; // Current position in frames.

View File

@ -44,7 +44,10 @@
} }
- (NSDictionary *)metadata { - (NSDictionary *)metadata {
return @{}; if(decoder != nil)
return [decoder metadata];
else
return @{};
} }
- (BOOL)open:(id<CogSource>)s { - (BOOL)open:(id<CogSource>)s {
@ -54,6 +57,8 @@
NSURL *url = [s url]; NSURL *url = [s url];
sourceURL = url;
embedded = NO; embedded = NO;
cuesheet = nil; cuesheet = nil;
NSDictionary *fileMetadata; NSDictionary *fileMetadata;
@ -225,14 +230,25 @@
if(noFragment) if(noFragment)
return NO; return NO;
BOOL pathsAreFiles = NO;
if([url isFileURL] && [sourceURL isFileURL]) {
pathsAreFiles = YES;
}
// Same file, just next track...this may be unnecessary since frame-based decoding is done now... // Same file, just next track...this may be unnecessary since frame-based decoding is done now...
if(embedded || ([[[track url] path] isEqualToString:[url path]] && [[[track url] host] isEqualToString:[url host]] && [[url fragment] intValue] == [[track track] intValue] + 1)) { if(embedded || ([[sourceURL path] isEqualToString:[url path]] && (pathsAreFiles || [[sourceURL host] isEqualToString:[url host]]))) {
NSArray *tracks = [cuesheet tracks]; NSArray *tracks = [cuesheet tracks];
int i; int i;
for(i = 0; i < [tracks count]; i++) { for(i = 0; i < [tracks count]; i++) {
if([[[tracks objectAtIndex:i] track] isEqualToString:[url fragment]]) { if([[[tracks objectAtIndex:i] track] isEqualToString:[url fragment]]) {
track = [tracks objectAtIndex:i]; CueSheetTrack *_track = [tracks objectAtIndex:i];
if(![[_track url] isEqualTo:[track url]])
return NO;
track = _track;
float sampleRate = [[[decoder properties] objectForKey:@"sampleRate"] floatValue]; float sampleRate = [[[decoder properties] objectForKey:@"sampleRate"] floatValue];
@ -253,8 +269,7 @@
trackEnd = [[[decoder properties] objectForKey:@"totalFrames"] longValue]; trackEnd = [[[decoder properties] objectForKey:@"totalFrames"] longValue];
} }
if(embedded) [self seek:0];
[self seek:0];
DLog(@"CHANGING TRACK!"); DLog(@"CHANGING TRACK!");
return YES; return YES;

View File

@ -52,8 +52,9 @@
} else } else
cuesheet = [CueSheet cueSheetWithFile:[url path]]; cuesheet = [CueSheet cueSheetWithFile:[url path]];
if(!cuesheet) if(!cuesheet) {
return nil; return fileMetadata;
}
NSArray *tracks = [cuesheet tracks]; NSArray *tracks = [cuesheet tracks];
for(CueSheetTrack *track in tracks) { for(CueSheetTrack *track in tracks) {
@ -61,16 +62,19 @@
// Class supplied by CogAudio, which is guaranteed to be present // Class supplied by CogAudio, which is guaranteed to be present
if(!embedded) if(!embedded)
fileMetadata = [audioMetadataReader metadataForURL:[track url] skipCue:YES]; fileMetadata = [audioMetadataReader metadataForURL:[track url] skipCue:YES];
NSDictionary *cuesheetMetadata = @{@"artist": [track artist],
@"album": [track album], NSMutableDictionary *cuesheetMetadata = [[NSMutableDictionary alloc] init];
@"title": [track title],
@"track": [NSNumber numberWithInt:[[track track] intValue]], if([track artist]) [cuesheetMetadata setValue:[track artist] forKey:@"artist"];
@"genre": [track genre], if([track album]) [cuesheetMetadata setValue:[track album] forKey:@"album"];
@"year": [NSNumber numberWithInt:[[track year] intValue]], if([track title]) [cuesheetMetadata setValue:[track title] forKey:@"title"];
@"replayGainAlbumGain": [NSNumber numberWithFloat:[track albumGain]], if([[track track] intValue]) [cuesheetMetadata setValue:[NSNumber numberWithInt:[[track track] intValue]] forKey:@"track"];
@"replayGainAlbumPeak": [NSNumber numberWithFloat:[track albumPeak]], if([track genre]) [cuesheetMetadata setValue:[track genre] forKey:@"genre"];
@"replayGainTrackGain": [NSNumber numberWithFloat:[track trackGain]], if([[track year] intValue]) [cuesheetMetadata setValue:[NSNumber numberWithInt:[[track year] intValue]] forKey:@"year"];
@"replayGainTrackPeak": [NSNumber numberWithFloat:[track trackPeak]]}; if([track albumGain]) [cuesheetMetadata setValue:[NSNumber numberWithFloat:[track albumGain]] forKey:@"replayGainAlbumGain"];
if([track albumPeak]) [cuesheetMetadata setValue:[NSNumber numberWithFloat:[track albumPeak]] forKey:@"replayGainAlbumPeak"];
if([track trackGain]) [cuesheetMetadata setValue:[NSNumber numberWithFloat:[track trackGain]] forKey:@"replayGainTrackGain"];
if([track trackPeak]) [cuesheetMetadata setValue:[NSNumber numberWithFloat:[track trackPeak]] forKey:@"replayGainTrackPeak"];
return [fileMetadata dictionaryByMergingWith:cuesheetMetadata]; return [fileMetadata dictionaryByMergingWith:cuesheetMetadata];
} }