Added class priority levels to metadata readers, properties readers, and containers, all so sidplay can be downvoted for mishandling id MUS format when trying to read its own MUS format

CQTexperiment
Chris Moeller 2015-04-13 00:39:24 -07:00
parent ddab71158e
commit a6b6369a6d
23 changed files with 285 additions and 63 deletions

View File

@ -44,8 +44,8 @@
17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.m */; };
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
8384912718080FF100E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384912618080FF100E7332D /* Logging.h */; };
839366671815923C006DD712 /* CogDecoderMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogDecoderMulti.h */; };
839366681815923C006DD712 /* CogDecoderMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogDecoderMulti.m */; };
839366671815923C006DD712 /* CogPluginMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogPluginMulti.h */; };
839366681815923C006DD712 /* CogPluginMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogPluginMulti.m */; };
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; };
@ -109,8 +109,8 @@
17F94DDC0B8D101100A34E87 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; };
8384912618080FF100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
839366651815923C006DD712 /* CogDecoderMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogDecoderMulti.h; sourceTree = "<group>"; };
839366661815923C006DD712 /* CogDecoderMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogDecoderMulti.m; sourceTree = "<group>"; };
839366651815923C006DD712 /* CogPluginMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogPluginMulti.h; sourceTree = "<group>"; };
839366661815923C006DD712 /* CogPluginMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogPluginMulti.m; sourceTree = "<group>"; };
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = "<group>"; };
@ -193,8 +193,8 @@
17B6192F0B909BC300BC003F /* AudioPropertiesReader.m */,
17ADB13A0B97926D00257CA2 /* AudioSource.h */,
17ADB13B0B97926D00257CA2 /* AudioSource.m */,
839366651815923C006DD712 /* CogDecoderMulti.h */,
839366661815923C006DD712 /* CogDecoderMulti.m */,
839366651815923C006DD712 /* CogPluginMulti.h */,
839366661815923C006DD712 /* CogPluginMulti.m */,
17F94DD30B8D0F7000A34E87 /* PluginController.h */,
17F94DD40B8D0F7000A34E87 /* PluginController.m */,
17D21C750B8BE4BA00D1EBDE /* Chain */,
@ -323,7 +323,7 @@
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */,
17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */,
839366671815923C006DD712 /* CogDecoderMulti.h in Headers */,
839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
8384912718080FF100E7332D /* Logging.h in Headers */,
@ -409,7 +409,7 @@
17D21CE00B8BE5B400D1EBDE /* VirtualRingBuffer.m in Sources */,
17D21CF40B8BE5EF00D1EBDE /* Semaphore.m in Sources */,
17D21DC80B8BE79700D1EBDE /* CoreAudioUtils.m in Sources */,
839366681815923C006DD712 /* CogDecoderMulti.m in Sources */,
839366681815923C006DD712 /* CogPluginMulti.m in Sources */,
17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */,
17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */,
17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */,

View File

@ -1,20 +0,0 @@
//
// CogDecoderMulti.h
// CogAudio
//
// Created by Christopher Snowhill on 10/21/13.
//
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface CogDecoderMulti : NSObject <CogDecoder> {
NSArray *theDecoders;
id<CogDecoder> theDecoder;
NSMutableArray *cachedObservers;
}
-(id)initWithDecoders:(NSArray *)decoders;
@end

41
Audio/CogPluginMulti.h Normal file
View File

@ -0,0 +1,41 @@
//
// CogPluginMulti.h
// CogAudio
//
// Created by Christopher Snowhill on 10/21/13.
//
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface CogDecoderMulti : NSObject <CogDecoder> {
NSArray *theDecoders;
id<CogDecoder> theDecoder;
NSMutableArray *cachedObservers;
}
-(id)initWithDecoders:(NSArray *)decoders;
@end
@interface CogContainerMulti : NSObject {
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url containers:(NSArray *)containers;
@end
@interface CogMetadataReaderMulti : NSObject {
}
+ (NSDictionary *)metadataForURL:(NSURL *)url readers:(NSArray *)readers;
@end
@interface CogPropertiesReaderMulti : NSObject {
}
+ (NSDictionary *)propertiesForSource:(id<CogSource>)source readers:(NSArray *)readers;
@end

View File

@ -1,12 +1,34 @@
//
// CogDecoderMulti.m
// CogPluginMulti.m
// CogAudio
//
// Created by Christopher Snowhill on 10/21/13.
//
//
#import "CogDecoderMulti.h"
#import "CogPluginMulti.h"
NSArray * sortClassesByPriority(NSArray * theClasses)
{
NSMutableArray *sortedClasses = [NSMutableArray arrayWithArray:theClasses];
[sortedClasses sortUsingComparator:
^NSComparisonResult(id obj1, id obj2)
{
NSString *classString1 = (NSString *)obj1;
NSString *classString2 = (NSString *)obj2;
Class class1 = NSClassFromString(classString1);
Class class2 = NSClassFromString(classString2);
float priority1 = [class1 priority];
float priority2 = [class2 priority];
if (priority1 == priority2) return NSOrderedSame;
else if (priority1 > priority2) return NSOrderedAscending;
else return NSOrderedDescending;
}];
return sortedClasses;
}
@implementation CogDecoderMulti
@ -30,24 +52,7 @@
self = [super init];
if ( self )
{
NSMutableArray *sortedDecoders = [NSMutableArray arrayWithArray:decoders];
[sortedDecoders sortUsingComparator:
^NSComparisonResult(id obj1, id obj2)
{
NSString *classString1 = (NSString *)obj1;
NSString *classString2 = (NSString *)obj2;
Class decoder1 = NSClassFromString(classString1);
Class decoder2 = NSClassFromString(classString2);
float priority1 = [decoder1 priority];
float priority2 = [decoder2 priority];
if (priority1 == priority2) return NSOrderedSame;
else if (priority1 > priority2) return NSOrderedAscending;
else return NSOrderedDescending;
}];
theDecoders = sortedDecoders;
theDecoders = sortClassesByPriority(decoders);
theDecoder = nil;
cachedObservers = [[NSMutableArray alloc] init];
}
@ -136,3 +141,54 @@
}
@end
@implementation CogContainerMulti
+ (NSArray *)urlsForContainerURL:(NSURL *)url containers:(NSArray *)containers
{
NSArray * sortedContainers = sortClassesByPriority(containers);
for (NSString *classString in sortedContainers)
{
Class container = NSClassFromString(classString);
NSArray * urls = [container urlsForContainerURL:url];
if ([urls count])
return urls;
}
return nil;
}
@end
@implementation CogMetadataReaderMulti
+ (NSDictionary *)metadataForURL:(NSURL *)url readers:(NSArray *)readers
{
NSArray * sortedReaders = sortClassesByPriority(readers);
for (NSString *classString in sortedReaders)
{
Class reader = NSClassFromString(classString);
NSDictionary * data = [reader metadataForURL:url];
if ([data count])
return data;
}
return nil;
}
@end
@implementation CogPropertiesReaderMulti
+ (NSDictionary *)propertiesForSource:(id<CogSource>)source readers:(NSArray *)readers
{
NSArray * sortedReaders = sortClassesByPriority(readers);
for (NSString *classString in sortedReaders)
{
Class reader = NSClassFromString(classString);
NSDictionary * data = [reader propertiesForSource:source];
if ([data count])
return data;
}
return nil;
}
@end

View File

@ -17,6 +17,7 @@
@protocol CogContainer <NSObject>
+ (NSArray *)fileTypes; //mp3, ogg, etc
+ (NSArray *)mimeTypes;
+ (float)priority;
+ (NSArray *)urlsForContainerURL:(NSURL *)url;
@end
@ -48,6 +49,7 @@
@protocol CogMetadataReader <NSObject>
+ (NSArray *)fileTypes;
+ (NSArray *)mimeTypes;
+ (float)priority;
+ (NSDictionary *)metadataForURL:(NSURL *)url;
@end
@ -60,6 +62,7 @@
@protocol CogPropertiesReader <NSObject>
+ (NSArray *)fileTypes;
+ (NSArray *)mimeTypes;
+ (float)priority;
+ (NSDictionary *)propertiesForSource:(id<CogSource>)source;
@end

View File

@ -16,7 +16,7 @@
NSMutableDictionary *decodersByExtension;
NSMutableDictionary *decodersByMimeType;
BOOL configured;
}

View File

@ -1,6 +1,6 @@
#import "PluginController.h"
#import "Plugin.h"
#import "CogDecoderMulti.h"
#import "CogPluginMulti.h"
#import "Logging.h"
@ -45,7 +45,7 @@ static PluginController *sharedPluginController = nil;
self.decodersByExtension = [[[NSMutableDictionary alloc] init] autorelease];
self.decodersByMimeType = [[[NSMutableDictionary alloc] init] autorelease];
[self setup];
}
@ -119,7 +119,16 @@ static PluginController *sharedPluginController = nil;
if (container && [container respondsToSelector:@selector(fileTypes)]) {
for (id fileType in [container fileTypes])
{
[containers setObject:className forKey:[fileType lowercaseString]];
NSString *ext = [fileType lowercaseString];
NSMutableArray *containerSet;
if (![containers objectForKey:ext])
{
containerSet = [[[NSMutableArray alloc] init] autorelease];
[containers setObject:containerSet forKey:ext];
}
else
containerSet = [containers objectForKey:ext];
[containerSet addObject:className];
}
}
}
@ -157,7 +166,16 @@ static PluginController *sharedPluginController = nil;
if (metadataReader && [metadataReader respondsToSelector:@selector(fileTypes)]) {
for (id fileType in [metadataReader fileTypes])
{
[metadataReaders setObject:className forKey:[fileType lowercaseString]];
NSString *ext = [fileType lowercaseString];
NSMutableArray *readers;
if (![metadataReaders objectForKey:ext])
{
readers = [[[NSMutableArray alloc] init] autorelease];
[metadataReaders setObject:readers forKey:ext];
}
else
readers = [metadataReaders objectForKey:ext];
[readers addObject:className];
}
}
}
@ -168,14 +186,23 @@ static PluginController *sharedPluginController = nil;
if (propertiesReader && [propertiesReader respondsToSelector:@selector(fileTypes)]) {
for (id fileType in [propertiesReader fileTypes])
{
[propertiesReadersByExtension setObject:className forKey:[fileType lowercaseString]];
NSString *ext = [fileType lowercaseString];
NSMutableArray *readers;
if (![propertiesReadersByExtension objectForKey:ext])
{
readers = [[[NSMutableArray alloc] init] autorelease];
[propertiesReadersByExtension setObject:readers forKey:ext];
}
else
readers = [propertiesReadersByExtension objectForKey:ext];
[readers addObject:className];
}
}
if (propertiesReader && [propertiesReader respondsToSelector:@selector(mimeTypes)]) {
for (id mimeType in [propertiesReader mimeTypes])
{
[propertiesReadersByMimeType setObject:className forKey:[mimeType lowercaseString]];
[propertiesReadersByMimeType setObject:className forKey:[mimeType lowercaseString]];
}
}
}
@ -216,8 +243,21 @@ static PluginController *sharedPluginController = nil;
- (NSArray *) urlsForContainerURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
NSArray *containerSet = [containers objectForKey:[ext lowercaseString]];
NSString *classString;
if (containerSet) {
if ( [containerSet count] > 1 ) {
return [CogContainerMulti urlsForContainerURL:url containers:containerSet];
}
else {
classString = [containerSet objectAtIndex:0];
}
}
else {
return nil;
}
Class container = NSClassFromString([containers objectForKey:[ext lowercaseString]]);
Class container = NSClassFromString(classString);
return [container urlsForContainerURL:url];
}
@ -248,11 +288,23 @@ static PluginController *sharedPluginController = nil;
- (NSDictionary *)metadataForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
NSArray *readers = [metadataReaders objectForKey:[ext lowercaseString]];
NSString *classString;
if (readers) {
if ( [readers count] > 1 ) {
return [CogMetadataReaderMulti metadataForURL:url readers:readers];
}
else {
classString = [readers objectAtIndex:0];
}
}
else {
return nil;
}
Class metadataReader = NSClassFromString([metadataReaders objectForKey:[ext lowercaseString]]);
Class metadataReader = NSClassFromString(classString);
return [metadataReader metadataForURL:url];
}
@ -264,11 +316,21 @@ static PluginController *sharedPluginController = nil;
id<CogSource> source = [self audioSourceForURL:url];
if (![source open:url])
return nil;
NSString *classString = [propertiesReadersByExtension objectForKey:[ext lowercaseString]];
if (!classString) {
classString = [propertiesReadersByMimeType objectForKey:[[source mimeType] lowercaseString]];
}
NSArray *readers = [propertiesReadersByExtension objectForKey:[ext lowercaseString]];
NSString *classString;
if (readers)
{
if ( [readers count] > 1 ) {
return [CogPropertiesReaderMulti propertiesForSource:source readers:readers];
}
else {
classString = [readers objectAtIndex:0];
}
}
else {
classString = [propertiesReadersByMimeType objectForKey:[[source mimeType] lowercaseString]];
}
if (classString)
{

View File

@ -34,6 +34,11 @@ static NSString * g_make_unpack_path(NSString * archive, NSString * file, NSStri
return [NSArray arrayWithObjects:@"application/zip", @"application/x-gzip", @"application/x-rar-compressed", @"application/x-7z-compressed", nil];
}
+ (float)priority
{
return 1.0f;
}
+ (void)initialize
{
fex_init();

View File

@ -23,6 +23,11 @@
return [NSArray arrayWithObjects:@"application/x-cue", nil]; //This is basically useless
}
+ (float)priority
{
return 1.0f;
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{
if (![url isFileURL]) {

View File

@ -24,6 +24,11 @@
return [CueSheetDecoder mimeTypes];
}
+ (float)priority
{
return 1.0f;
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
if (![url isFileURL]) {

View File

@ -25,6 +25,11 @@
return nil;
}
+ (float)priority
{
return 1.0f;
}
struct callbackData
{
NSString * baseUrl;

View File

@ -25,6 +25,11 @@
return [DumbDecoder mimeTypes];
}
+ (float)priority
{
return 1.0f;
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
id audioSourceClass = NSClassFromString(@"AudioSource");

View File

@ -26,6 +26,11 @@
return nil;
}
+ (float)priority
{
return 1.0f;
}
//This really should be source...
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{

View File

@ -26,6 +26,11 @@
return [GameDecoder mimeTypes];
}
+ (float)priority
{
return 1.0f;
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
id audioSourceClass = NSClassFromString(@"AudioSource");

View File

@ -21,6 +21,11 @@
return nil;
}
+ (float)priority
{
return 1.0f;
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{
if ([url fragment]) {

View File

@ -21,6 +21,11 @@
return [HVLDecoder mimeTypes];
}
+ (float)priority
{
return 1.0f;
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
id audioSourceClass = NSClassFromString(@"AudioSource");

View File

@ -22,6 +22,11 @@
return [NSArray arrayWithObjects:@"audio/x-mpegurl", @"audio/mpegurl", nil];
}
+ (float)priority
{
return 1.0f;
}
+ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename
{
NSRange protocolRange = [path rangeOfString:@"://"];

View File

@ -23,6 +23,11 @@
return [MIDIDecoder mimeTypes];
}
+ (float) priority
{
return 1.0f;
}
//This really should be source...
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{

View File

@ -24,6 +24,11 @@
return [MIDIDecoder mimeTypes];
}
+ (float)priority
{
return 1.0f;
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
id audioSourceClass = NSClassFromString(@"AudioSource");

View File

@ -22,6 +22,11 @@
return [NSArray arrayWithObjects:@"audio/x-scpls", @"application/pls", nil];
}
+ (float)priority
{
return 1.0f;
}
+ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename
{
NSRange protocolRange = [path rangeOfString:@"://"];

View File

@ -193,4 +193,9 @@
return [NSArray arrayWithObjects:@"audio/x-ape", @"audio/x-ms-wma", @"application/ogg", @"application/x-ogg", @"audio/x-vorbis+ogg", @"audio/x-musepack", @"audio/x-flac", @"audio/x-m4a", @"audio/mpeg", @"audio/x-mp3", @"audio/x-tak", @"audio/x-ac3", @"audio/x-apl", @"audio/x-dts", @"audio/x-dtshd", @"audio/x-tta", @"audio/wav", @"audio/aiff", nil];
}
+ (float)priority
{
return 1.0f;
}
@end

View File

@ -23,6 +23,11 @@
return nil;
}
+ (float)priority
{
return 0.5f;
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{
if ([url fragment]) {

View File

@ -23,6 +23,11 @@
return [SidDecoder mimeTypes];
}
+ (float)priority
{
return 0.5f;
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
id audioSourceClass = NSClassFromString(@"AudioSource");