Removed APE tag reader from APL plugin and enabled stub APE tag reading of APE tags from APL files in the TagLib plugin
parent
a9982e9c80
commit
4aab503658
|
@ -139,6 +139,7 @@ StringList FileRef::defaultFileExtensions()
|
|||
l.append("ape");
|
||||
l.append("opus");
|
||||
l.append("tak");
|
||||
l.append("apl");
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -234,7 +235,7 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
|
|||
return new ASF::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "APE")
|
||||
return new APE::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "TAK")
|
||||
if(ext == "TAK" || ext == "APL")
|
||||
return new APE::File(fileName, false, audioPropertiesStyle);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
99B98A1E0CC7E1CA00C256E9 /* ApeTag.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99B9865F0CC7A20800C256E9 /* ApeTag.mm */; };
|
||||
99B98A1F0CC7E1CD00C256E9 /* APLDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D42360CBB0F9800135C1B /* APLDecoder.m */; };
|
||||
99B98A200CC7E1CE00C256E9 /* APLFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 99B9863F0CC7A08600C256E9 /* APLFile.m */; };
|
||||
99B98A210CC7E1D100C256E9 /* APLMetadataReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DA346D0CC04FCD0003F6B2 /* APLMetadataReader.m */; };
|
||||
99B98A260CC7E22500C256E9 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
@ -18,8 +16,6 @@
|
|||
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
17DA346C0CC04FCD0003F6B2 /* APLMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APLMetadataReader.h; sourceTree = "<group>"; };
|
||||
17DA346D0CC04FCD0003F6B2 /* APLMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APLMetadataReader.m; sourceTree = "<group>"; };
|
||||
32DBCF630370AF2F00C91783 /* APL_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APL_Prefix.pch; sourceTree = "<group>"; };
|
||||
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
8E8D42350CBB0F9800135C1B /* APLDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APLDecoder.h; sourceTree = "<group>"; };
|
||||
|
@ -27,8 +23,6 @@
|
|||
8E8D423C0CBB0FF600135C1B /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
|
||||
99B9863E0CC7A08600C256E9 /* APLFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APLFile.h; sourceTree = "<group>"; };
|
||||
99B9863F0CC7A08600C256E9 /* APLFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APLFile.m; sourceTree = "<group>"; };
|
||||
99B9865E0CC7A20800C256E9 /* ApeTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApeTag.h; sourceTree = "<group>"; };
|
||||
99B9865F0CC7A20800C256E9 /* ApeTag.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ApeTag.mm; sourceTree = "<group>"; };
|
||||
99B989F40CC7E10400C256E9 /* APL.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APL.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
@ -80,12 +74,8 @@
|
|||
8E8D423C0CBB0FF600135C1B /* Plugin.h */,
|
||||
8E8D42350CBB0F9800135C1B /* APLDecoder.h */,
|
||||
8E8D42360CBB0F9800135C1B /* APLDecoder.m */,
|
||||
17DA346C0CC04FCD0003F6B2 /* APLMetadataReader.h */,
|
||||
17DA346D0CC04FCD0003F6B2 /* APLMetadataReader.m */,
|
||||
99B9863E0CC7A08600C256E9 /* APLFile.h */,
|
||||
99B9863F0CC7A08600C256E9 /* APLFile.m */,
|
||||
99B9865E0CC7A20800C256E9 /* ApeTag.h */,
|
||||
99B9865F0CC7A20800C256E9 /* ApeTag.mm */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
|
@ -183,10 +173,8 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
99B98A1E0CC7E1CA00C256E9 /* ApeTag.mm in Sources */,
|
||||
99B98A1F0CC7E1CD00C256E9 /* APLDecoder.m in Sources */,
|
||||
99B98A200CC7E1CE00C256E9 /* APLFile.m in Sources */,
|
||||
99B98A210CC7E1D100C256E9 /* APLMetadataReader.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class ApeTag;
|
||||
|
||||
@interface APLFile : NSObject {
|
||||
long startBlock;
|
||||
long endBlock;
|
||||
ApeTag* tag;
|
||||
NSURL* file;
|
||||
}
|
||||
+createWithFile:(NSString*)f;
|
||||
|
@ -14,7 +11,6 @@
|
|||
|
||||
-(long)startBlock; // always return 0 or greater!
|
||||
-(long)endBlock;
|
||||
-(ApeTag*) tag;
|
||||
-(NSURL*) file;
|
||||
|
||||
//writing support to be added in far future
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
|
||||
#import "APLFile.h"
|
||||
#import "ApeTag.h"
|
||||
|
||||
@implementation APLFile
|
||||
+createWithFile:(NSString*)f { return [[APLFile alloc] initWithFile:f]; }
|
||||
|
@ -98,7 +97,6 @@
|
|||
}
|
||||
[scanner release];
|
||||
//check here for EOF? cocoa does not have this functionality :(
|
||||
tag = [ApeTag createFromFileRead:f];
|
||||
[f closeFile];
|
||||
}
|
||||
return self;
|
||||
|
@ -106,7 +104,6 @@
|
|||
|
||||
-(long)startBlock { return startBlock; }
|
||||
-(long)endBlock { return endBlock; }
|
||||
-(ApeTag*) tag { return tag; }
|
||||
-(NSURL*) file { return file; }
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "Plugin.h"
|
||||
|
||||
@interface APLMetadataReader : NSObject <CogMetadataReader> {
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// APLMetadataReader.m
|
||||
|
||||
|
||||
#import "APLMetadataReader.h"
|
||||
#import "APLDecoder.h"
|
||||
|
||||
#import "APLFile.h"
|
||||
#import "ApeTag.h"
|
||||
|
||||
@implementation APLMetadataReader
|
||||
|
||||
+ (NSArray *)fileTypes { return [APLDecoder fileTypes]; }
|
||||
+ (NSArray *)mimeTypes { return [APLDecoder mimeTypes]; }
|
||||
|
||||
+ (NSDictionary *)metadataForURL:(NSURL *)url {
|
||||
if (![url isFileURL]) return nil;
|
||||
|
||||
APLFile *apl = [APLFile createWithFile:[url path]];
|
||||
|
||||
ApeTag* tag = [apl tag];
|
||||
NSDictionary* res =[tag convertToCogTag];
|
||||
return res;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,46 +0,0 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
//not full support!! and even may have not enougth checks to find a non-supported data!
|
||||
|
||||
|
||||
|
||||
@interface ApeTagItem: NSObject {
|
||||
UInt32 flags;
|
||||
NSString* tag;
|
||||
NSData* data;
|
||||
}
|
||||
|
||||
+createTag:(NSString*)t flags:(SInt32)f data:(NSData*)d;
|
||||
-initTag:(NSString*)t flags:(SInt32)f data:(NSData*)d;
|
||||
|
||||
//for writing:
|
||||
-(NSData*) pack;
|
||||
|
||||
//for reading:
|
||||
-(NSString*) tag;
|
||||
-(bool) isString; //returns whether data is UTF-8 string(or implicitly can be converted to)
|
||||
-(NSString*) getString; //returns string, if is not string - this is error, check isString before
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
@interface ApeTag : NSObject {
|
||||
NSMutableArray* fields;
|
||||
}
|
||||
|
||||
+(id)create;
|
||||
+(id)createFromFileRead:(NSFileHandle*)f;
|
||||
-(id)init;
|
||||
-(id)initFromFileRead:(NSFileHandle*)f;
|
||||
|
||||
-(NSArray*) fields; // returns fields array
|
||||
|
||||
-(void) addField:(NSString*)f text:(NSString*)t;
|
||||
-(NSData*) pack; //returns comoplete tag, ready for writing to file/transmitting smwhere
|
||||
|
||||
-(void) write:(NSFileHandle*)f; //writes to file output of -pack
|
||||
-(bool) read:(NSFileHandle*)f; //reads from file, returns true on success
|
||||
|
||||
-(NSDictionary*) convertToCogTag;
|
||||
@end
|
|
@ -1,237 +0,0 @@
|
|||
|
||||
// as simple as it can be - just write a readable tag, no options etc.
|
||||
|
||||
|
||||
#import "ApeTag.h"
|
||||
|
||||
#define CURRENT_APE_TAG_VERSION 2000
|
||||
/*****************************************************************************************
|
||||
"Standard" APE tag fields
|
||||
*****************************************************************************************/
|
||||
#define APE_TAG_FIELD_TITLE @"Title"
|
||||
#define APE_TAG_FIELD_ARTIST @"Artist"
|
||||
#define APE_TAG_FIELD_ALBUM @"Album"
|
||||
#define APE_TAG_FIELD_COMMENT @"Comment"
|
||||
#define APE_TAG_FIELD_YEAR @"Year"
|
||||
#define APE_TAG_FIELD_TRACK @"Track"
|
||||
#define APE_TAG_FIELD_GENRE @"Genre"
|
||||
#define APE_TAG_FIELD_COVER_ART_FRONT @"Cover Art (front)"
|
||||
#define APE_TAG_FIELD_NOTES @"Notes"
|
||||
#define APE_TAG_FIELD_LYRICS @"Lyrics"
|
||||
#define APE_TAG_FIELD_COPYRIGHT @"Copyright"
|
||||
#define APE_TAG_FIELD_BUY_URL @"Buy URL"
|
||||
#define APE_TAG_FIELD_ARTIST_URL @"Artist URL"
|
||||
#define APE_TAG_FIELD_PUBLISHER_URL @"Publisher URL"
|
||||
#define APE_TAG_FIELD_FILE_URL @"File URL"
|
||||
#define APE_TAG_FIELD_COPYRIGHT_URL @"Copyright URL"
|
||||
#define APE_TAG_FIELD_MJ_METADATA @"Media Jukebox Metadata"
|
||||
#define APE_TAG_FIELD_TOOL_NAME @"Tool Name"
|
||||
#define APE_TAG_FIELD_TOOL_VERSION @"Tool Version"
|
||||
#define APE_TAG_FIELD_PEAK_LEVEL @"Peak Level"
|
||||
#define APE_TAG_FIELD_REPLAY_GAIN_RADIO @"Replay Gain (radio)"
|
||||
#define APE_TAG_FIELD_REPLAY_GAIN_ALBUM @"Replay Gain (album)"
|
||||
#define APE_TAG_FIELD_COMPOSER @"Composer"
|
||||
#define APE_TAG_FIELD_KEYWORDS @"Keywords"
|
||||
|
||||
/*****************************************************************************************
|
||||
Standard APE tag field values
|
||||
*****************************************************************************************/
|
||||
#define APE_TAG_GENRE_UNDEFINED @"Undefined"
|
||||
/*****************************************************************************************
|
||||
Footer (and header) flags
|
||||
*****************************************************************************************/
|
||||
#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31)
|
||||
#define APE_TAG_FLAG_CONTAINS_FOOTER (1 << 30)
|
||||
#define APE_TAG_FLAG_IS_HEADER (1 << 29)
|
||||
|
||||
#define APE_TAG_FLAGS_DEFAULT (APE_TAG_FLAG_CONTAINS_FOOTER)
|
||||
|
||||
/*****************************************************************************************
|
||||
Tag field flags
|
||||
*****************************************************************************************/
|
||||
#define TAG_FIELD_FLAG_READ_ONLY (1 << 0)
|
||||
|
||||
#define TAG_FIELD_FLAG_DATA_TYPE_MASK (6)
|
||||
#define TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8 (0 << 1)
|
||||
#define TAG_FIELD_FLAG_DATA_TYPE_BINARY (1 << 1)
|
||||
#define TAG_FIELD_FLAG_DATA_TYPE_EXTERNAL_INFO (2 << 1)
|
||||
#define TAG_FIELD_FLAG_DATA_TYPE_RESERVED (3 << 1)
|
||||
|
||||
/*****************************************************************************************
|
||||
The footer at the end of APE tagged files (can also optionally be at the front of the tag)
|
||||
*****************************************************************************************/
|
||||
#define APE_TAG_FOOTER_BYTES 32
|
||||
|
||||
//------------------------
|
||||
|
||||
@implementation ApeTagItem
|
||||
+createTag:(NSString*)t flags:(SInt32)f data:(NSData*)d{
|
||||
return [[ApeTagItem alloc] initTag:t flags:f data:d];
|
||||
}
|
||||
|
||||
-initTag:(NSString*)t flags:(SInt32)f data:(NSData*)d{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
tag = [t copy];
|
||||
data = [d copy];
|
||||
flags = f;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSData*) pack {
|
||||
//item header:
|
||||
NSMutableData* d = [NSMutableData dataWithCapacity:8];
|
||||
UInt32 len = CFSwapInt32HostToLittle([data length]);
|
||||
UInt32 flags1 = CFSwapInt32HostToLittle(flags); // ApeTagv1 does not use this, 0 for v2 means only footer and all fields text in utf8 - just right what we want
|
||||
|
||||
[d appendBytes:&len length:4]; // lenth of value
|
||||
[d appendBytes:&flags1 length:4]; // 32 bits of flags
|
||||
[d appendData:[tag dataUsingEncoding: NSUTF8StringEncoding]]; // item tag
|
||||
char c = 0; [d appendBytes:&c length:1]; // 0x00 separator after tag
|
||||
[d appendData:data]; // item value
|
||||
return d;
|
||||
}
|
||||
|
||||
-(bool) isString { //returns whether data is UTF-8 string(or implicitly can be converted to)
|
||||
return (flags & TAG_FIELD_FLAG_DATA_TYPE_MASK) == TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8;
|
||||
}
|
||||
-(NSString*) getString { //returns string, if is not string - this is error, check isString before
|
||||
if ([self isString]) return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
return nil;
|
||||
}
|
||||
-(NSString*) tag { return tag; }
|
||||
@end
|
||||
|
||||
|
||||
@implementation ApeTag
|
||||
+(id)create { return [[ApeTag alloc] init];}
|
||||
+(id)createFromFileRead:(NSFileHandle*)f { return [[ApeTag alloc] initFromFileRead:f]; }
|
||||
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
fields = [NSMutableArray array];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initFromFileRead:(NSFileHandle*)f {
|
||||
self = [super init];
|
||||
if(self)
|
||||
{
|
||||
fields = [NSMutableArray array];
|
||||
if (![self read:f])
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) addField:(NSString*)f text:(NSString*)t {
|
||||
[fields addObject:[ApeTagItem createTag:f flags:(TAG_FIELD_FLAG_DATA_TYPE_TEXT_UTF8) data:[t dataUsingEncoding: NSUTF8StringEncoding]]];
|
||||
}
|
||||
|
||||
-(NSArray*) fields { return fields; }
|
||||
|
||||
-(NSDictionary*) convertToCogTag {
|
||||
//NSLog(@"Converting ape tag to cog tag");
|
||||
NSMutableDictionary* d = [NSMutableDictionary dictionaryWithCapacity:6];
|
||||
ApeTagItem* item;
|
||||
int n = 0;
|
||||
for (item in fields) {
|
||||
if (![[item tag] compare:APE_TAG_FIELD_ARTIST]) { [d setObject:[item getString] forKey:@"artist"]; n++;}
|
||||
if (![[item tag] compare:APE_TAG_FIELD_ALBUM]) {[d setObject:[item getString] forKey:@"album"]; n++;}
|
||||
if (![[item tag] compare:APE_TAG_FIELD_TITLE]) {[d setObject:[item getString] forKey:@"title"]; n++;}
|
||||
if (![[item tag] compare:APE_TAG_FIELD_TRACK]) {[d setObject:[NSNumber numberWithInt:[[item getString] intValue]] forKey:@"track"]; n++;}
|
||||
if (![[item tag] compare:APE_TAG_FIELD_GENRE]) {[d setObject:[item getString] forKey:@"genre"]; n++;}
|
||||
if (![[item tag] compare:APE_TAG_FIELD_YEAR]) {[d setObject:[item getString] forKey:@"year"]; n++;}
|
||||
}
|
||||
if (n)
|
||||
return d;
|
||||
[d release]; d = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(NSData*) pack {
|
||||
int len = 0, num = 0;
|
||||
NSMutableData* d = [NSMutableData dataWithCapacity:8];
|
||||
id item;
|
||||
for (item in fields)
|
||||
{
|
||||
NSData* i = [item pack];
|
||||
[d appendData:i];
|
||||
len += [i length];
|
||||
num++;
|
||||
}
|
||||
UInt32 version = CFSwapInt32HostToLittle(CURRENT_APE_TAG_VERSION);
|
||||
UInt32 size = CFSwapInt32HostToLittle(len + APE_TAG_FOOTER_BYTES);
|
||||
UInt32 count = CFSwapInt32HostToLittle(num);
|
||||
UInt32 flags = CFSwapInt32HostToLittle(APE_TAG_FLAGS_DEFAULT);
|
||||
[d appendBytes:"APETAGEX" length:8];
|
||||
[d appendBytes:&version length:4];
|
||||
[d appendBytes:&size length:4];
|
||||
[d appendBytes:&count length:4];
|
||||
[d appendBytes:&flags length:4];
|
||||
[d appendBytes:"\0\0\0\0\0\0\0\0" length:8]; //reserved
|
||||
return d;
|
||||
}
|
||||
|
||||
-(void) write:(NSFileHandle*)file {
|
||||
[file writeData:[self pack]];
|
||||
}
|
||||
|
||||
-(NSString*) readToNull:(NSFileHandle*)f { //!!!
|
||||
NSMutableData* d = [NSMutableData dataWithCapacity:100]; //it will grow, here should be most expected value (may gain few nanosecond from it =) )
|
||||
while(true) {
|
||||
NSData* byte = [f readDataOfLength:1];
|
||||
if (!byte)
|
||||
{
|
||||
[f seekToFileOffset:0-[d length]];
|
||||
return nil;
|
||||
}
|
||||
if (*((const char*)[byte bytes]) == 0) break;
|
||||
[d appendData:byte];
|
||||
}
|
||||
NSString* s = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding]; //!handle encoding error (in case binary data starts not from newline, impossible on real apl, but who knows...)
|
||||
return s;
|
||||
}
|
||||
|
||||
-(bool) read:(NSFileHandle*)f { //reads from file, returns true on success
|
||||
|
||||
//reading from file erases previous data:
|
||||
[fields removeAllObjects];
|
||||
|
||||
//!! prefix header may be present and we should read it but lazyness...
|
||||
NSString* header = @"APETAGEX";
|
||||
NSData* check = [f readDataOfLength:[header length]];
|
||||
[f seekToFileOffset:([f offsetInFile]-[check length])];
|
||||
if (check && [[[NSString alloc] initWithData:check encoding:NSASCIIStringEncoding] isEqualToString:header]) {
|
||||
NSLog(@"Reading of prefix header not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
//read fields and store 'em
|
||||
while(true) {
|
||||
NSData* check = [f readDataOfLength:[header length]];
|
||||
[f seekToFileOffset:([f offsetInFile]-[check length])];
|
||||
if (check && [[[NSString alloc] initWithData:check encoding:NSASCIIStringEncoding] isEqualToString:header]) break; // reached footer
|
||||
|
||||
NSData* f_len = [f readDataOfLength:4];
|
||||
NSData* f_flag = [f readDataOfLength:4];
|
||||
NSString* f_name = [self readToNull:f];
|
||||
UInt32 len = CFSwapInt32LittleToHost(*(uint32_t*)[f_len bytes]);
|
||||
UInt32 flags = CFSwapInt32LittleToHost(*(uint32_t*)[f_flag bytes]);
|
||||
NSData* data = [f readDataOfLength:len];
|
||||
ApeTagItem* item = [ApeTagItem createTag:f_name flags:flags data:data];
|
||||
//NSLog(@"Read tag '%@'='%@'", [item tag], [item getString]);
|
||||
[fields addObject:item];
|
||||
}
|
||||
//here we should read footer and check number of fields etc. - but who cares? =)
|
||||
// just clean up file pointer:
|
||||
[f readDataOfLength:APE_TAG_FOOTER_BYTES];
|
||||
return true;
|
||||
}
|
||||
|
||||
@end
|
|
@ -130,12 +130,12 @@
|
|||
+ (NSArray *)fileTypes
|
||||
{
|
||||
//May be a way to get a list of supported formats
|
||||
return [NSArray arrayWithObjects:@"ape", @"asf", @"wma", @"ogg", @"opus", @"mpc", @"flac", @"m4a", @"mp3", @"tak", nil];
|
||||
return [NSArray arrayWithObjects:@"ape", @"asf", @"wma", @"ogg", @"opus", @"mpc", @"flac", @"m4a", @"mp3", @"tak", @"apl", nil];
|
||||
}
|
||||
|
||||
+ (NSArray *)mimeTypes
|
||||
{
|
||||
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", nil];
|
||||
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-apl", nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue