Added beginnings of cuesheet plugin.

CQTexperiment
vspader 2007-10-09 02:25:40 +00:00
parent 88aecc7de2
commit 4935c5ddfc
14 changed files with 687 additions and 0 deletions

View File

@ -0,0 +1,25 @@
//
// CueSheet.h
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class CueSheetTrack;
@interface CueSheet : NSObject {
NSArray *tracks;
}
+ (id)cueSheetWithFile: (NSString *)filename;
- (id)initWithFile:(NSString *)filename;
- (NSArray *)tracks;
- (CueSheetTrack *)track:(NSString *)fragment;
@end

View File

@ -0,0 +1,58 @@
//
// CueSheet.m
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "CueSheet.h"
#import "CueSheetTrack.h"
@implementation CueSheet
+ (id)cueSheetWithFile:(NSString *)filename
{
return [[[CueSheet alloc] initWithFile:filename] autorelease];
}
- (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.
}
return self;
}
- (NSArray *)tracks
{
return tracks;
}
- (CueSheetTrack *)track:(NSString *)fragment
{
CueSheetTrack *t;
NSEnumerator *e = [tracks objectEnumerator];
while (t = [e nextObject]) {
if ([[t track] isEqualToString:fragment]) {
return t;
}
}
return nil;
}
@end

View File

@ -0,0 +1,291 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXBuildFile section */
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 */; };
8E8D42260CBB0F5800135C1B /* CueSheetContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D42250CBB0F5800135C1B /* CueSheetContainer.m */; };
8E8D42370CBB0F9800135C1B /* CueSheetDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D42360CBB0F9800135C1B /* CueSheetDecoder.m */; };
8E8D424D0CBB11C600135C1B /* CueSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D424C0CBB11C600135C1B /* CueSheet.m */; };
8E8D43570CBB1AE900135C1B /* CueSheetTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D43560CBB1AE900135C1B /* CueSheetTrack.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
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>"; };
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>"; };
8E8D42170CBB0F3C00135C1B /* CueSheetPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheetPlugin.h; sourceTree = "<group>"; };
8E8D42180CBB0F3C00135C1B /* CueSheetPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheetPlugin.m; sourceTree = "<group>"; };
8E8D42240CBB0F5800135C1B /* CueSheetContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheetContainer.h; sourceTree = "<group>"; };
8E8D42250CBB0F5800135C1B /* CueSheetContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheetContainer.m; sourceTree = "<group>"; };
8E8D42350CBB0F9800135C1B /* CueSheetDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheetDecoder.h; sourceTree = "<group>"; };
8E8D42360CBB0F9800135C1B /* CueSheetDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheetDecoder.m; sourceTree = "<group>"; };
8E8D423C0CBB0FF600135C1B /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
8E8D424B0CBB11C600135C1B /* CueSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheet.h; sourceTree = "<group>"; };
8E8D424C0CBB11C600135C1B /* CueSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheet.m; sourceTree = "<group>"; };
8E8D43550CBB1AE900135C1B /* CueSheetTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheetTrack.h; sourceTree = "<group>"; };
8E8D43560CBB1AE900135C1B /* CueSheetTrack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheetTrack.m; sourceTree = "<group>"; };
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D5B49B3048680CD000E48DA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* CueSheet */ = {
isa = PBXGroup;
children = (
08FB77AFFE84173DC02AAC07 /* Classes */,
32C88E010371C26100C91783 /* Other Sources */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
19C28FB8FE9D52D311CA2CBB /* Products */,
);
name = CueSheet;
sourceTree = "<group>";
};
089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
);
name = "Frameworks and Libraries";
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
8D5B49B7048680CD000E48DA /* Info.plist */,
089C167DFE841241C02AAC07 /* InfoPlist.strings */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
8E8D423C0CBB0FF600135C1B /* Plugin.h */,
8E8D42170CBB0F3C00135C1B /* CueSheetPlugin.h */,
8E8D42180CBB0F3C00135C1B /* CueSheetPlugin.m */,
8E8D42240CBB0F5800135C1B /* CueSheetContainer.h */,
8E8D42250CBB0F5800135C1B /* CueSheetContainer.m */,
8E8D42350CBB0F9800135C1B /* CueSheetDecoder.h */,
8E8D42360CBB0F9800135C1B /* CueSheetDecoder.m */,
8E8D424B0CBB11C600135C1B /* CueSheet.h */,
8E8D424C0CBB11C600135C1B /* CueSheet.m */,
8E8D43550CBB1AE900135C1B /* CueSheetTrack.h */,
8E8D43560CBB1AE900135C1B /* CueSheetTrack.m */,
);
name = Classes;
sourceTree = "<group>";
};
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
089C167FFE841241C02AAC07 /* AppKit.framework */,
D2F7E65807B2D6F200F64583 /* CoreData.framework */,
089C1672FE841209C02AAC07 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FB8FE9D52D311CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D5B49B6048680CD000E48DA /* CueSheet.bundle */,
);
name = Products;
sourceTree = "<group>";
};
32C88E010371C26100C91783 /* Other Sources */ = {
isa = PBXGroup;
children = (
32DBCF630370AF2F00C91783 /* CueSheet_Prefix.pch */,
);
name = "Other Sources";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D5B49AC048680CD000E48DA /* CueSheet */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "CueSheet" */;
buildPhases = (
8D5B49AF048680CD000E48DA /* Resources */,
8D5B49B1048680CD000E48DA /* Sources */,
8D5B49B3048680CD000E48DA /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = CueSheet;
productInstallPath = "$(HOME)/Library/Bundles";
productName = CueSheet;
productReference = 8D5B49B6048680CD000E48DA /* CueSheet.bundle */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "CueSheet" */;
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* CueSheet */;
projectDirPath = "";
targets = (
8D5B49AC048680CD000E48DA /* CueSheet */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D5B49AF048680CD000E48DA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D5B49B1048680CD000E48DA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8E8D42190CBB0F3C00135C1B /* CueSheetPlugin.m in Sources */,
8E8D42260CBB0F5800135C1B /* CueSheetContainer.m in Sources */,
8E8D42370CBB0F9800135C1B /* CueSheetDecoder.m in Sources */,
8E8D424D0CBB11C600135C1B /* CueSheet.m in Sources */,
8E8D43570CBB1AE900135C1B /* CueSheetTrack.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1DEB913B08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = CueSheet_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
PRODUCT_NAME = CueSheet;
SYMROOT = ../../build;
WRAPPER_EXTENSION = bundle;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB913C08733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = CueSheet_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
PRODUCT_NAME = CueSheet;
SYMROOT = ../../build;
WRAPPER_EXTENSION = bundle;
};
name = Release;
};
1DEB913F08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Debug;
};
1DEB914008733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "CueSheet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB913B08733D840010E9CD /* Debug */,
1DEB913C08733D840010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "CueSheet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB913F08733D840010E9CD /* Debug */,
1DEB914008733D840010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

View File

@ -0,0 +1,17 @@
//
// CueSheetContainer.h
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface CueSheetContainer : NSObject <CogContainer> {
}
@end

View File

@ -0,0 +1,37 @@
//
// CueSheetContainer.m
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "CueSheetContainer.h"
#import "CueSheet.h"
#import "CueSheetTrack.h"
@implementation CueSheetContainer
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObject:@"cue"];
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url {
if (![url isFileURL]) {
return [NSArray array];
}
NSMutableArray *tracks = [NSMutableArray array];
CueSheet *cuesheet = [[CueSheet alloc] initWithFile:[url path]];
NSEnumerator *e = [[cuesheet tracks] objectEnumerator];
CueSheetTrack *track;
while (track = [e nextObject]) {
[tracks addObject:[NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:@"#%@", [track track]]]];
}
return tracks;
}
@end

View File

@ -0,0 +1,24 @@
//
// CueSheetDecoder.h
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@class CueSheetTrack;
@interface CueSheetDecoder : NSObject <CogDecoder> {
id<CogDecoder> decoder;
int bytesPerSecond;
int trackPosition;
CueSheetTrack *track;
}
@end

View File

@ -0,0 +1,94 @@
//
// CueSheetDecoder.m
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "CueSheetDecoder.h"
#import "CueSheet.h"
#import "CueSheetTrack.h"
@implementation CueSheetDecoder
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObject:@"cue"];
}
- (NSDictionary *)properties
{
return [decoder properties];
}
- (BOOL)open:(id<CogSource>)source
{
//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];
}
return r;
}
- (double)seekToTime:(double)time //milliseconds
{
double trackStartMs = [track start] * 1000.0;
double trackEndMs = [track end] * 1000.0;
if (time > trackEndMs - trackStartMs) {
//need a better way of returning fail.
return -1.0;
}
time += trackStartMs;
trackPosition = (time/1000.0) * bytesPerSecond;
return [decoder seekToTime:time];
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int n;
n = [decoder fillBuffer:buf ofSize:size];
trackPosition += n;
int trackEnd = [track end] * bytesPerSecond;
if (trackPosition + n > trackEnd) {
return trackEnd - trackPosition;
}
return n;
}
- (void)dealloc
{
[decoder release];
[super dealloc];
}
@end

View File

@ -0,0 +1,17 @@
//
// CueSheetPlugin.h
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface CueSheetPlugin : NSObject <CogPlugin> {
}
@end

View File

@ -0,0 +1,23 @@
//
// CueSheetPlugin.m
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "CueSheetPlugin.h"
#import "CueSheetContainer.h"
#import "CueSheetDecoder.h"
@implementation CueSheetPlugin
+ (NSDictionary *)pluginInfo
{
return [NSDictionary dictionaryWithObjectsAndKeys:
kCogContainer, [CueSheetContainer className],
kCogDecoder, [CueSheetDecoder className]];
}
@end

View File

@ -0,0 +1,26 @@
//
// CueSheetTrack.h
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface CueSheetTrack : NSObject {
NSString *track;
double start;
double end;
}
- (void)initWithTrack:(NSString *)t start:(double)s end:(double)e;
- (NSString *)track;
- (double)start;
- (double)end;
@end

View File

@ -0,0 +1,42 @@
//
// CueSheetTrack.m
// CueSheet
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "CueSheetTrack.h"
@implementation CueSheetTrack
- (void)initWithTrack:(NSString *)t start:(double)s end:(double)e
{
self = [super init];
if (self)
{
track = [t copy];
start = s;
end = e;
}
return self;
}
- (NSString *)track
{
return track;
}
- (double)start
{
return start;
}
- (double)end
{
return end;
}
@end

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'CueSheet' target in the 'CueSheet' project.
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

Binary file not shown.

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.yourcocoabundle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSPrincipalClass</key>
<string>CueSheetPlugin</string>
</dict>
</plist>