Basic cue sheet support working. Bug city.

CQTexperiment
vspader 2007-10-10 01:59:25 +00:00
parent 4935c5ddfc
commit 50395e6e72
12 changed files with 319 additions and 82 deletions

View File

@ -204,11 +204,11 @@ static PluginController *sharedPluginController = nil;
- (void)printPluginInfo
{
//NSLog(@"Sources: %@", sources);
//NSLog(@"Containers: %@", containers);
//NSLog(@"Decoders: %@", decoders);
//NSLog(@"Metadata Readers: %@", metadataReaders);
//NSLog(@"Properties Readers: %@", propertiesReaders);
NSLog(@"Sources: %@", sources);
NSLog(@"Containers: %@", containers);
NSLog(@"Decoders: %@", decoders);
NSLog(@"Metadata Readers: %@", metadataReaders);
NSLog(@"Properties Readers: %@", propertiesReaders);
}
- (NSDictionary *)sources

View File

@ -88,6 +88,7 @@
17C809E60C3BD487005707C4 /* CoreAudio.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17C809E30C3BD46D005707C4 /* CoreAudio.bundle */; };
17E41E070C130DFF00AC744D /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = 17E41E060C130DFF00AC744D /* Credits.html */; };
17E41E230C130EE200AC744D /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 17E41E220C130EE200AC744D /* Help */; };
17F3BB890CBC565900864489 /* CueSheet.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F3BB880CBC565100864489 /* CueSheet.bundle */; };
17F561400C3BD4F30019975C /* CogAudio.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F561330C3BD4DC0019975C /* CogAudio.framework */; };
17F562390C3BD91B0019975C /* General.preferencePane in Resources */ = {isa = PBXBuildFile; fileRef = 17F5622E0C3BD8FB0019975C /* General.preferencePane */; };
17F94CC20B8D08FB00A34E87 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17F94CC10B8D08FB00A34E87 /* Sparkle.framework */; };
@ -279,6 +280,20 @@
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
remoteInfo = CoreAudio;
};
17F3BB870CBC565100864489 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 17F3BB830CBC565100864489 /* CueSheet.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* CueSheet.bundle */;
remoteInfo = CueSheet;
};
17F3BB8A0CBC566200864489 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 17F3BB830CBC565100864489 /* CueSheet.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* CueSheet */;
remoteInfo = CueSheet;
};
17F561320C3BD4DC0019975C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */;
@ -311,28 +326,28 @@
isa = PBXContainerItemProxy;
containerPortal = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* M3u.bundle */;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA;
remoteInfo = M3u;
};
8E8D40920CBB03AF00135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* M3u */;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
remoteInfo = M3u;
};
8E8D41C60CBB0DA000135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* Pls.bundle */;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA;
remoteInfo = Pls;
};
8E8D41CB0CBB0DD200135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* Pls */;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
remoteInfo = Pls;
};
/* End PBXContainerItemProxy section */
@ -344,6 +359,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
17F3BB890CBC565900864489 /* CueSheet.bundle in CopyFiles */,
8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */,
8E8D40880CBB038E00135C1B /* M3u.bundle in CopyFiles */,
17C809E60C3BD487005707C4 /* CoreAudio.bundle in CopyFiles */,
@ -507,6 +523,7 @@
17E41C470C1304BB00AC744D /* Swedish */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = Swedish; path = Swedish.lproj/MainMenu.nib; sourceTree = "<group>"; };
17E41C480C1304C700AC744D /* Swedish */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = Swedish; path = Swedish.lproj/OpenURLPanel.nib; sourceTree = "<group>"; };
17E41C490C1304D200AC744D /* Swedish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Swedish; path = Swedish.lproj/Localizable.strings; sourceTree = "<group>"; };
17F3BB830CBC565100864489 /* CueSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CueSheet.xcodeproj; path = Plugins/CueSheet/CueSheet.xcodeproj; sourceTree = "<group>"; };
17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CogAudio.xcodeproj; path = Audio/CogAudio.xcodeproj; sourceTree = "<group>"; };
17F562260C3BD8FB0019975C /* General.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = General.xcodeproj; path = Preferences/General/General.xcodeproj; sourceTree = "<group>"; };
17F94CC10B8D08FB00A34E87 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ThirdParty/Frameworks/Sparkle.framework; sourceTree = "<group>"; };
@ -791,6 +808,7 @@
17B619FF0B909ED400BC003F /* PlugIns */ = {
isa = PBXGroup;
children = (
17F3BB830CBC565100864489 /* CueSheet.xcodeproj */,
8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */,
8E8D40820CBB036600135C1B /* M3u.xcodeproj */,
17C808C00C3BD1DD005707C4 /* WavPack.xcodeproj */,
@ -896,6 +914,14 @@
name = Products;
sourceTree = "<group>";
};
17F3BB840CBC565100864489 /* Products */ = {
isa = PBXGroup;
children = (
17F3BB880CBC565100864489 /* CueSheet.bundle */,
);
name = Products;
sourceTree = "<group>";
};
17F5612B0C3BD4DC0019975C /* Products */ = {
isa = PBXGroup;
children = (
@ -1117,6 +1143,7 @@
17F5623B0C3BD9280019975C /* PBXTargetDependency */,
8E8D40930CBB03AF00135C1B /* PBXTargetDependency */,
8E8D41CC0CBB0DD200135C1B /* PBXTargetDependency */,
17F3BB8B0CBC566200864489 /* PBXTargetDependency */,
);
name = Cog;
productInstallPath = "$(HOME)/Applications";
@ -1151,6 +1178,10 @@
ProductGroup = 17C809DF0C3BD46D005707C4 /* Products */;
ProjectRef = 17C808660C3BD0F8005707C4 /* CoreAudio.xcodeproj */;
},
{
ProductGroup = 17F3BB840CBC565100864489 /* Products */;
ProjectRef = 17F3BB830CBC565100864489 /* CueSheet.xcodeproj */;
},
{
ProductGroup = 17C808720C3BD167005707C4 /* Products */;
ProjectRef = 17C808710C3BD167005707C4 /* FileSource.xcodeproj */;
@ -1288,6 +1319,13 @@
remoteRef = 17C809E20C3BD46D005707C4 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
17F3BB880CBC565100864489 /* CueSheet.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = CueSheet.bundle;
remoteRef = 17F3BB870CBC565100864489 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
17F561330C3BD4DC0019975C /* CogAudio.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@ -1483,6 +1521,11 @@
name = CoreAudio;
targetProxy = 17C809E40C3BD47C005707C4 /* PBXContainerItemProxy */;
};
17F3BB8B0CBC566200864489 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = CueSheet;
targetProxy = 17F3BB8A0CBC566200864489 /* PBXContainerItemProxy */;
};
17F5613F0C3BD4E90019975C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = CogAudio;

View File

@ -18,6 +18,8 @@
- (id)initWithFile:(NSString *)filename;
- (void)parseFile:(NSString *)filename;
- (NSArray *)tracks;
- (CueSheetTrack *)track:(NSString *)fragment;

View File

@ -16,27 +16,146 @@
return [[[CueSheet alloc] initWithFile:filename] autorelease];
}
- (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename
{
if ([path hasPrefix:@"/"]) {
return [NSURL fileURLWithPath:path];
}
NSRange foundRange = [path rangeOfString:@"://"];
if (foundRange.location != NSNotFound)
{
return [NSURL URLWithString:path];
}
NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"];
NSMutableString *unixPath = [path mutableCopy];
//Only relative paths would have windows backslashes.
[unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])];
return [NSURL fileURLWithPath:[basePath stringByAppendingString:[unixPath autorelease]]];
}
- (void)parseFile:(NSString *)filename
{
NSError *error = nil;
NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error];
if (error || !contents) {
NSLog(@"Could not open file...%@ %@ %@", filename, contents, error);
return;
}
NSMutableArray *entries = [[NSMutableArray alloc] init];
NSString *track = nil;
NSString *path = nil;
BOOL trackAdded = NO;
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString *line;
NSScanner *scanner = nil;
NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator];
while (line = [e nextObject])
{
[scanner release];
scanner = [[NSScanner alloc] initWithString:line];
NSString *command;
if (![scanner scanUpToCharactersFromSet:whitespace intoString:&command]) {
continue;
}
//FILE "filename.shn" WAVE
if ([command isEqualToString:@"FILE"]) {
track = nil;
trackAdded = NO;
if (![scanner scanString:@"\"" intoString:&command]) {
continue;
}
//Read in the path
if (![scanner scanUpToString:@"\"" intoString:&path]) {
continue;
}
}
//TRACK 01 AUDIO
else if ([command isEqualToString:@"TRACK"]) {
trackAdded = NO;
if (![scanner scanUpToCharactersFromSet:whitespace intoString:&track]) {
continue;
}
NSString *type = nil;
if (![scanner scanUpToCharactersFromSet:whitespace intoString:&type]
|| ![type isEqualToString:@"AUDIO"]) {
continue;
}
}
//INDEX 01 00:00:10
//Note that time is written in Minutes:Seconds:Frames, where frames are 1/75 of a second
else if ([command isEqualToString:@"INDEX"]) {
if (trackAdded) {
continue;
}
if (!path) {
continue;
}
NSString *index = nil;
if (![scanner scanUpToCharactersFromSet:whitespace intoString:&index]) {
continue;
}
[scanner scanCharactersFromSet:whitespace intoString:nil];
NSString *time = nil;
if (![scanner scanUpToCharactersFromSet:whitespace intoString:&time]) {
continue;
}
NSArray *msf = [time componentsSeparatedByString:@":"];
if ([msf count] != 3) {
continue;
}
double seconds = (60*[[msf objectAtIndex:0] intValue]) + [[msf objectAtIndex:1] intValue] + ([[msf objectAtIndex:2] floatValue]/75);
if (track == nil) {
track = @"01";
}
//Need to add basePath, and convert to URL
[entries addObject:
[CueSheetTrack trackWithURL:[self urlForPath:path relativeTo:filename]
track: track
time: seconds]];
trackAdded = YES;
}
}
[scanner release];
tracks = [entries copy];
[entries release];
}
- (id)initWithFile:(NSString *)filename
{
self = [super init];
if (self) {
NSError *error = nil;
NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error];
if (error || !contents) {
NSLog(@"Could not open file...%@ %@", contents, error);
return nil;
}
tracks = [[NSMutableArray alloc] init];
//Actually parse file here.
[self parseFile:filename];
}
return self;
}
- (NSArray *)tracks
{
return tracks;

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
17F3BB680CBC560700864489 /* CueSheetPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F3BB670CBC560700864489 /* CueSheetPropertiesReader.m */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
8E8D42190CBB0F3C00135C1B /* CueSheetPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D42180CBB0F3C00135C1B /* CueSheetPlugin.m */; };
@ -21,6 +22,8 @@
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
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>"; };
17F3BB660CBC560700864489 /* CueSheetPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CueSheetPropertiesReader.h; sourceTree = "<group>"; };
17F3BB670CBC560700864489 /* CueSheetPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = CueSheetPropertiesReader.m; sourceTree = "<group>"; };
32DBCF630370AF2F00C91783 /* CueSheet_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheet_Prefix.pch; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* CueSheet.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CueSheet.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
@ -90,6 +93,8 @@
8E8D42250CBB0F5800135C1B /* CueSheetContainer.m */,
8E8D42350CBB0F9800135C1B /* CueSheetDecoder.h */,
8E8D42360CBB0F9800135C1B /* CueSheetDecoder.m */,
17F3BB660CBC560700864489 /* CueSheetPropertiesReader.h */,
17F3BB670CBC560700864489 /* CueSheetPropertiesReader.m */,
8E8D424B0CBB11C600135C1B /* CueSheet.h */,
8E8D424C0CBB11C600135C1B /* CueSheet.m */,
8E8D43550CBB1AE900135C1B /* CueSheetTrack.h */,
@ -189,6 +194,7 @@
8E8D42370CBB0F9800135C1B /* CueSheetDecoder.m in Sources */,
8E8D424D0CBB11C600135C1B /* CueSheet.m in Sources */,
8E8D43570CBB1AE900135C1B /* CueSheetTrack.m in Sources */,
17F3BB680CBC560700864489 /* CueSheetPropertiesReader.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -18,13 +18,16 @@
return [NSArray arrayWithObject:@"cue"];
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url {
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{
if (![url isFileURL]) {
return [NSArray array];
}
NSMutableArray *tracks = [NSMutableArray array];
CueSheet *cuesheet = [[CueSheet alloc] initWithFile:[url path]];
CueSheet *cuesheet = [CueSheet cueSheetWithFile:[url path]];
NSEnumerator *e = [[cuesheet tracks] objectEnumerator];
CueSheetTrack *track;
while (track = [e nextObject]) {

View File

@ -13,10 +13,12 @@
@class CueSheetTrack;
@interface CueSheetDecoder : NSObject <CogDecoder> {
id<CogSource> source;
id<CogDecoder> decoder;
int bytesPerSecond;
int trackPosition;
int bytePosition;
double trackEnd;
CueSheetTrack *track;
}

View File

@ -10,49 +10,105 @@
#import "CueSheet.h"
#import "CueSheetTrack.h"
#import "CueSheetContainer.h"
@implementation CueSheetDecoder
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObject:@"cue"];
return [CueSheetContainer fileTypes];
}
- (NSDictionary *)properties
{
return [decoder properties];
NSMutableDictionary *properties = [[decoder properties] mutableCopy];
//Need to alter length
[properties setObject:[NSNumber numberWithDouble:((trackEnd - [track time]) * 1000)] forKey:@"length"];
return [properties autorelease];
}
- (BOOL)open:(id<CogSource>)source
- (BOOL)open:(id<CogSource>)s
{
//Kind of a hackish way of accessing AudioDecoder
decoder = [NSClassFromString(@"AudioDecoder") audioDecoderForURL:[source url]];
[decoder retain];
BOOL r = [decoder open:source];
if (r)
{
CueSheet *cuesheet = [CueSheet cueSheetWithFile:[[source url] path]];
track = [cuesheet track:[[source url] fragment]];
NSDictionary *properties = [decoder properties];
int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue];
int channels = [[properties objectForKey:@"channels"] intValue];
float sampleRate = [[properties objectForKey:@"sampleRate"] floatValue];
bytesPerSecond = (int)((bitsPerSample/8) * channels * sampleRate);
[decoder seekToTime: [track start] * 1000.0];
if (![[s url] isFileURL]) {
return NO;
}
return r;
NSURL *url = [s url];
[s close];
CueSheet *cuesheet = [CueSheet cueSheetWithFile:[url path]];
NSArray *tracks = [cuesheet tracks];
int i;
for (i = 0; i < [tracks count]; i++)
{
if ([[[tracks objectAtIndex:i] track] isEqualToString:[url fragment]]){
track = [tracks objectAtIndex:i];
//Kind of a hackish way of accessing outside classes.
source = [NSClassFromString(@"AudioSource") audioSourceForURL:[track url]];
[source retain];
if (![source open:[track url]]) {
NSLog(@"Could not open cuesheet source");
return NO;
}
decoder = [NSClassFromString(@"AudioDecoder") audioDecoderForURL:[source url]];
[decoder retain];
if (![decoder open:source]) {
NSLog(@"Could not open cuesheet decoder");
return NO;
}
CueSheetTrack *nextTrack = nil;
if (i + 1 < [tracks count]) {
nextTrack = [tracks objectAtIndex:i + 1];
}
NSDictionary *properties = [decoder properties];
int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue];
int channels = [[properties objectForKey:@"channels"] intValue];
float sampleRate = [[properties objectForKey:@"sampleRate"] floatValue];
bytesPerSecond = (int)((bitsPerSample/8) * channels * sampleRate);
[decoder seekToTime: [track time] * 1000.0];
if (nextTrack && [[[nextTrack url] absoluteString] isEqualToString:[[track url] absoluteString]]) {
trackEnd = [nextTrack time];
}
else {
trackEnd = [[properties objectForKey:@"length"] doubleValue]/1000.0;
}
return YES;
}
}
return NO;
}
- (void)close {
if (decoder) {
[decoder close];
[decoder release];
decoder = nil;
}
if (source) {
[source release];
source = nil;
}
}
- (double)seekToTime:(double)time //milliseconds
{
double trackStartMs = [track start] * 1000.0;
double trackEndMs = [track end] * 1000.0;
double trackStartMs = [track time] * 1000.0;
double trackEndMs = trackEnd * 1000.0;
if (time > trackEndMs - trackStartMs) {
//need a better way of returning fail.
@ -61,34 +117,29 @@
time += trackStartMs;
trackPosition = (time/1000.0) * bytesPerSecond;
bytePosition = (time/1000.0) * bytesPerSecond;
return [decoder seekToTime:time];
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int n;
long trackByteEnd = trackEnd * bytesPerSecond;
n = [decoder fillBuffer:buf ofSize:size];
trackPosition += n;
int trackEnd = [track end] * bytesPerSecond;
if (trackPosition + n > trackEnd) {
return trackEnd - trackPosition;
if (bytePosition + size > trackByteEnd) {
size = trackByteEnd - bytePosition;
}
if (!size) {
return 0;
}
int n = [decoder fillBuffer:buf ofSize:size];
bytePosition += n;
return n;
}
- (void)dealloc
{
[decoder release];
[super dealloc];
}
@end

View File

@ -10,6 +10,7 @@
#import "CueSheetContainer.h"
#import "CueSheetDecoder.h"
#import "CueSheetPropertiesReader.h"
@implementation CueSheetPlugin
@ -17,7 +18,9 @@
{
return [NSDictionary dictionaryWithObjectsAndKeys:
kCogContainer, [CueSheetContainer className],
kCogDecoder, [CueSheetDecoder className]];
kCogDecoder, [CueSheetDecoder className],
kCogPropertiesReader, [CueSheetPropertiesReader className],
nil];
}
@end

View File

@ -11,16 +11,18 @@
@interface CueSheetTrack : NSObject {
NSString *track;
NSURL *url;
double start;
double end;
double time;
}
- (void)initWithTrack:(NSString *)t start:(double)s end:(double)e;
+ (id)trackWithURL:(NSURL *)u track:(NSString *)t time:(double)t;
- (id)initWithURL:(NSURL *)u track:(NSString *)t time:(double)t;
- (NSString *)track;
- (NSURL *)url;
- (double)start;
- (double)end;
- (double)time;
@end

View File

@ -11,14 +11,19 @@
@implementation CueSheetTrack
- (void)initWithTrack:(NSString *)t start:(double)s end:(double)e
+ (id)trackWithURL:(NSURL *)u track:(NSString *)t time:(double)s
{
return [[[CueSheetTrack alloc] initWithURL:u track:t time:s] autorelease];
}
- (id)initWithURL:(NSURL *)u track:(NSString *)t time:(double)s
{
self = [super init];
if (self)
{
track = [t copy];
start = s;
end = e;
url = [u copy];
time = s;
}
return self;
@ -29,14 +34,14 @@
return track;
}
- (double)start
- (NSURL *)url
{
return start;
return url;
}
- (double)end
- (double)time
{
return end;
return time;
}
@end

View File

@ -567,7 +567,8 @@ static inline signed int scale (mad_fixed_t sample)
new_position = ((double) seconds / (double) total_seconds) * _fileSize;
[_source seek:new_position whence:SEEK_SET];
mad_stream_sync(&_stream);
//mad_stream_sync(&_stream);
_stream.error = MAD_ERROR_BUFLEN;
_stream.sync = 0;
_outputAvailable = 0;