From 934840ace55453a069f11da9bbae46e5f3a4e50e Mon Sep 17 00:00:00 2001 From: vspader Date: Fri, 2 Mar 2007 01:36:52 +0000 Subject: [PATCH] Added source plugin support. Things are incredibly broken. Besides Ogg Vorbis. That should still work. --- Application/AppController.h | 7 + Application/AppController.m | 31 ++ Application/PlaybackController.m | 6 +- Audio/AudioDecoder.h | 4 +- Audio/AudioDecoder.m | 3 +- Audio/AudioPlayer.m | 2 +- Audio/AudioPropertiesReader.m | 12 +- .../AudioSource.h | 11 +- Audio/AudioSource.m | 25 ++ Audio/Chain/BufferChain.h | 4 + Audio/Chain/BufferChain.m | 43 ++- Audio/Chain/InputNode.h | 2 +- Audio/Chain/InputNode.m | 9 +- Audio/Chain/SourceNode.h | 40 +++ Audio/Chain/SourceNode.m | 122 ++++++++ Audio/CogAudio.xcodeproj/project.pbxproj | 64 ++--- Audio/Plugin.h | 52 ++-- Audio/PluginController.h | 16 +- Audio/PluginController.m | 149 ++++++---- AudioScrobbler/AudioScrobbler.m | 2 +- Cog.xcodeproj/project.pbxproj | 8 + English.lproj/MainMenu.nib/classes.nib | 5 + English.lproj/MainMenu.nib/info.nib | 5 +- English.lproj/MainMenu.nib/keyedobjects.nib | Bin 60212 -> 61849 bytes Playlist/PlaylistController.m | 10 +- Playlist/PlaylistEntry.h | 6 +- Playlist/PlaylistEntry.m | 24 +- .../CoreAudio.xcodeproj/project.pbxproj | 12 +- Plugins/CoreAudio/CoreAudioCodec.m | 39 --- .../{CoreAudioCodec.h => CoreAudioPlugin.h} | 2 +- Plugins/CoreAudio/CoreAudioPlugin.m | 24 ++ Plugins/CoreAudio/Info.plist | 2 +- Plugins/FileSource/FileSource.h | 18 ++ Plugins/FileSource/FileSource.m | 61 ++++ .../FileSource.xcodeproj/project.pbxproj | 256 +++++++++++++++++ Plugins/FileSource/FileSourcePlugin.h | 18 ++ Plugins/FileSource/FileSourcePlugin.m | 23 ++ Plugins/FileSource/FileSource_Prefix.pch | 7 + Plugins/FileSource/Info.plist | 26 ++ Plugins/Flac/Flac.xcodeproj/project.pbxproj | 14 +- Plugins/Flac/FlacCodec.m | 38 --- Plugins/{MAD/MADCodec.h => Flac/FlacPlugin.h} | 2 +- Plugins/Flac/FlacPlugin.m | 25 ++ Plugins/Flac/Info.plist | 2 +- Plugins/HTTPSource/HTTPSource.h | 21 ++ Plugins/HTTPSource/HTTPSource.m | 75 +++++ .../HTTPSource.xcodeproj/project.pbxproj | 270 ++++++++++++++++++ Plugins/HTTPSource/HTTPSourcePlugin.h | 18 ++ Plugins/HTTPSource/HTTPSourcePlugin.m | 23 ++ Plugins/HTTPSource/HTTPSource_Prefix.pch | 7 + Plugins/HTTPSource/Info.plist | 26 ++ Plugins/HTTPSource/Utils/Socket.h | 23 ++ Plugins/HTTPSource/Utils/Socket.m | 77 +++++ Plugins/MAD/Info.plist | 2 +- Plugins/MAD/MAD.xcodeproj/project.pbxproj | 14 +- Plugins/MAD/MADCodec.m | 38 --- Plugins/{Flac/FlacCodec.h => MAD/MADPlugin.h} | 2 +- Plugins/MAD/MADPlugin.m | 24 ++ Plugins/MonkeysAudio/Info.plist | 6 +- .../MonkeysAudio.xcodeproj/project.pbxproj | 14 +- Plugins/MonkeysAudio/MonkeysAudioCodec.mm | 38 --- .../MonkeysAudioPlugin.h} | 2 +- Plugins/MonkeysAudio/MonkeysAudioPlugin.mm | 25 ++ Plugins/Musepack/Info.plist | 2 +- .../Musepack.xcodeproj/project.pbxproj | 14 +- Plugins/Musepack/MusepackCodec.m | 38 --- .../MusepackPlugin.h} | 2 +- Plugins/Musepack/MusepackPlugin.m | 24 ++ Plugins/Shorten/Info.plist | 2 +- .../Shorten/Shorten.xcodeproj/project.pbxproj | 14 +- Plugins/Shorten/ShortenCodec.mm | 38 --- .../{ShortenCodec.h => ShortenPlugin.h} | 2 +- Plugins/Shorten/ShortenPlugin.mm | 24 ++ Plugins/TagLib/TagLibPlugin.h | 2 +- Plugins/TagLib/TagLibPlugin.m | 25 +- Plugins/Vorbis/Info.plist | 2 +- .../Vorbis/Vorbis.xcodeproj/project.pbxproj | 14 +- Plugins/Vorbis/VorbisCodec.m | 38 --- Plugins/Vorbis/VorbisDecoder.h | 6 +- Plugins/Vorbis/VorbisDecoder.m | 78 ++++- Plugins/Vorbis/VorbisPlugin.h | 17 ++ Plugins/Vorbis/VorbisPlugin.m | 24 ++ Plugins/Vorbis/VorbisPropertiesReader.m | 5 +- .../WavPack/WavPack.xcodeproj/project.pbxproj | 14 +- Plugins/WavPack/WavPackCodec.h | 17 -- Plugins/WavPack/WavPackCodec.m | 38 --- Plugins/WavPack/WavPackPlugin.h | 17 ++ Plugins/WavPack/WavPackPlugin.m | 24 ++ Scripts/build_plugins.sh | 2 +- TODO | 2 + 90 files changed, 1827 insertions(+), 594 deletions(-) rename Plugins/MonkeysAudio/MonkeysAudioCodec.h => Audio/AudioSource.h (52%) create mode 100644 Audio/AudioSource.m create mode 100644 Audio/Chain/SourceNode.h create mode 100644 Audio/Chain/SourceNode.m delete mode 100644 Plugins/CoreAudio/CoreAudioCodec.m rename Plugins/CoreAudio/{CoreAudioCodec.h => CoreAudioPlugin.h} (78%) create mode 100644 Plugins/CoreAudio/CoreAudioPlugin.m create mode 100644 Plugins/FileSource/FileSource.h create mode 100644 Plugins/FileSource/FileSource.m create mode 100644 Plugins/FileSource/FileSource.xcodeproj/project.pbxproj create mode 100644 Plugins/FileSource/FileSourcePlugin.h create mode 100644 Plugins/FileSource/FileSourcePlugin.m create mode 100644 Plugins/FileSource/FileSource_Prefix.pch create mode 100644 Plugins/FileSource/Info.plist delete mode 100644 Plugins/Flac/FlacCodec.m rename Plugins/{MAD/MADCodec.h => Flac/FlacPlugin.h} (80%) create mode 100644 Plugins/Flac/FlacPlugin.m create mode 100644 Plugins/HTTPSource/HTTPSource.h create mode 100644 Plugins/HTTPSource/HTTPSource.m create mode 100644 Plugins/HTTPSource/HTTPSource.xcodeproj/project.pbxproj create mode 100644 Plugins/HTTPSource/HTTPSourcePlugin.h create mode 100644 Plugins/HTTPSource/HTTPSourcePlugin.m create mode 100644 Plugins/HTTPSource/HTTPSource_Prefix.pch create mode 100644 Plugins/HTTPSource/Info.plist create mode 100644 Plugins/HTTPSource/Utils/Socket.h create mode 100644 Plugins/HTTPSource/Utils/Socket.m delete mode 100644 Plugins/MAD/MADCodec.m rename Plugins/{Flac/FlacCodec.h => MAD/MADPlugin.h} (80%) create mode 100644 Plugins/MAD/MADPlugin.m delete mode 100644 Plugins/MonkeysAudio/MonkeysAudioCodec.mm rename Plugins/{Musepack/MusepackCodec.h => MonkeysAudio/MonkeysAudioPlugin.h} (78%) create mode 100644 Plugins/MonkeysAudio/MonkeysAudioPlugin.mm delete mode 100644 Plugins/Musepack/MusepackCodec.m rename Plugins/{Vorbis/VorbisCodec.h => Musepack/MusepackPlugin.h} (79%) create mode 100644 Plugins/Musepack/MusepackPlugin.m delete mode 100644 Plugins/Shorten/ShortenCodec.mm rename Plugins/Shorten/{ShortenCodec.h => ShortenPlugin.h} (79%) create mode 100644 Plugins/Shorten/ShortenPlugin.mm delete mode 100644 Plugins/Vorbis/VorbisCodec.m create mode 100644 Plugins/Vorbis/VorbisPlugin.h create mode 100644 Plugins/Vorbis/VorbisPlugin.m delete mode 100644 Plugins/WavPack/WavPackCodec.h delete mode 100644 Plugins/WavPack/WavPackCodec.m create mode 100644 Plugins/WavPack/WavPackPlugin.h create mode 100644 Plugins/WavPack/WavPackPlugin.m create mode 100644 TODO diff --git a/Application/AppController.h b/Application/AppController.h index 01dff6879..ba135705c 100644 --- a/Application/AppController.h +++ b/Application/AppController.h @@ -21,6 +21,9 @@ IBOutlet NSPanel *mainWindow; + IBOutlet NSPanel *addURLPanel; + IBOutlet NSTextField *urlField; + IBOutlet NSButton *playButton; IBOutlet NSButton *prevButton; IBOutlet NSButton *nextButton; @@ -54,6 +57,10 @@ BOOL remoteButtonHeld; /* true as long as the user holds the left,right,plus or minus on the remote control */ } +- (IBAction)addURL:(id)sender; +- (IBAction)addURLSheetOK:(id)sender; +- (IBAction)addURLSheetCancel:(id)sender; + - (IBAction)openFiles:(id)sender; - (IBAction)delEntries:(id)sender; - (IBAction)savePlaylist:(id)sender; diff --git a/Application/AppController.m b/Application/AppController.m index 91177bc4a..3add400e0 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -144,6 +144,37 @@ increase/decrease as long as the user holds the left/right, plus/minus button */ // [panel release]; } +- (IBAction)addURL:(id)sender +{ + [NSApp beginSheet:addURLPanel modalForWindow:mainWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; +} + +- (IBAction)addURLSheetOK:(id)sender +{ + NSURL *url = [NSURL URLWithString:[urlField stringValue]]; + + PlaylistEntry *pe = [[PlaylistEntry alloc] init]; + + [pe setURL:url]; + [pe setIndex:[[playlistController arrangedObjects] count]]; + [pe setTitle:[urlField stringValue]]; + + [playlistController addObject:pe]; + + [pe release]; + + [NSApp endSheet:addURLPanel]; + [addURLPanel orderOut:self]; +} + +- (IBAction)addURLSheetCancel:(id)sender +{ + NSLog(@"GONE!"); + [NSApp endSheet:addURLPanel]; + [addURLPanel orderOut:self]; +} + + - (IBAction)delEntries:(id)sender { [playlistController remove:self]; diff --git a/Application/PlaybackController.m b/Application/PlaybackController.m index 62c25c27d..6a2883b26 100644 --- a/Application/PlaybackController.m +++ b/Application/PlaybackController.m @@ -132,7 +132,7 @@ [self updateTimeField:0.0f]; - [audioPlayer play:[NSURL fileURLWithPath:[pe filename]] withUserInfo:pe]; + [audioPlayer play:[pe url] withUserInfo:pe]; [audioPlayer setVolume:currentVolume]; if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { @@ -300,8 +300,8 @@ [player setNextStream:nil]; else { - DBLog(@"NEXT SONG: %@", [pe filename]); - [player setNextStream:[NSURL fileURLWithPath:[pe filename]] withUserInfo:pe]; + DBLog(@"NEXT SONG: %@", [pe url]); + [player setNextStream:[pe url] withUserInfo:pe]; } } diff --git a/Audio/AudioDecoder.h b/Audio/AudioDecoder.h index db6c65595..366233702 100644 --- a/Audio/AudioDecoder.h +++ b/Audio/AudioDecoder.h @@ -8,11 +8,11 @@ #import -#import "PluginController.h" +#import "Plugin.h" @interface AudioDecoder : NSObject { } -+ audioDecoderForURL:(NSURL *)url; ++ (id)audioDecoderForURL:(NSURL *)url; @end diff --git a/Audio/AudioDecoder.m b/Audio/AudioDecoder.m index 7b653b67f..5b106eb1b 100644 --- a/Audio/AudioDecoder.m +++ b/Audio/AudioDecoder.m @@ -8,10 +8,11 @@ #import "AudioDecoder.h" +#import "PluginController.h" @implementation AudioDecoder -+ audioDecoderForURL:(NSURL *)url ++ (id) audioDecoderForURL:(NSURL *)url { NSString *ext = [[url path] pathExtension]; diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 66a41954b..a799c5360 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -10,7 +10,7 @@ #import "BufferChain.h" #import "OutputNode.h" #import "Status.h" - +#import "PluginController.h" @implementation AudioPlayer diff --git a/Audio/AudioPropertiesReader.m b/Audio/AudioPropertiesReader.m index 056a37c1f..604815fb9 100644 --- a/Audio/AudioPropertiesReader.m +++ b/Audio/AudioPropertiesReader.m @@ -7,6 +7,8 @@ // #import "AudioPropertiesReader.h" +#import "AudioSource.h" +#import "Plugin.h" #import "PluginController.h" @implementation AudioPropertiesReader @@ -15,11 +17,19 @@ { NSString *ext = [[url path] pathExtension]; + id source = [AudioSource audioSourceForURL:url]; + if (![source open:url]) + return nil; + NSDictionary *propertiesReaders = [[PluginController sharedPluginController] propertiesReaders]; Class propertiesReader = NSClassFromString([propertiesReaders objectForKey:ext]); - return [[[[propertiesReader alloc] init] autorelease] propertiesForURL:url]; + NSDictionary *properties = [propertiesReader propertiesForSource:source]; + + [source close]; + + return properties; } diff --git a/Plugins/MonkeysAudio/MonkeysAudioCodec.h b/Audio/AudioSource.h similarity index 52% rename from Plugins/MonkeysAudio/MonkeysAudioCodec.h rename to Audio/AudioSource.h index e223130f8..aeb1758ec 100644 --- a/Plugins/MonkeysAudio/MonkeysAudioCodec.h +++ b/Audio/AudioSource.h @@ -1,17 +1,18 @@ // -// MusepackCodec.h -// Musepack +// AudioDecoder.h +// CogAudio // // Created by Vincent Spader on 2/21/07. // Copyright 2007 __MyCompanyName__. All rights reserved. // #import -#import "Plugin.h" -@interface MonkeysAudioCodec : NSObject -{ +#import "PluginController.h" +@interface AudioSource : NSObject { } ++ audioSourceForURL:(NSURL *)url; + @end diff --git a/Audio/AudioSource.m b/Audio/AudioSource.m new file mode 100644 index 000000000..b6db2edc5 --- /dev/null +++ b/Audio/AudioSource.m @@ -0,0 +1,25 @@ +// +// AudioDecoder.m +// CogAudio +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "AudioSource.h" + + +@implementation AudioSource + ++ audioSourceForURL:(NSURL *)url +{ + NSString *scheme = [url scheme]; + + NSDictionary *sources = [[PluginController sharedPluginController] sources]; + + Class source = NSClassFromString([sources objectForKey:scheme]); + + return [[[source alloc] init] autorelease]; +} + +@end diff --git a/Audio/Chain/BufferChain.h b/Audio/Chain/BufferChain.h index 318651f8f..86b23646e 100644 --- a/Audio/Chain/BufferChain.h +++ b/Audio/Chain/BufferChain.h @@ -10,9 +10,12 @@ #import "InputNode.h" #import "ConverterNode.h" +#import "sourceNode.h" + #import "AudioPlayer.h" @interface BufferChain : NSObject { + SourceNode *sourceNode; InputNode *inputNode; ConverterNode *converterNode; @@ -37,6 +40,7 @@ - (void)setUserInfo:(id)i; - (NSURL *)streamURL; +- (void)setStreamURL:(NSURL *)url; - (void)setShouldContinue:(BOOL)s; diff --git a/Audio/Chain/BufferChain.m b/Audio/Chain/BufferChain.m index 28c64bc3c..70a009adb 100644 --- a/Audio/Chain/BufferChain.m +++ b/Audio/Chain/BufferChain.m @@ -8,6 +8,8 @@ #import "BufferChain.h" #import "OutputNode.h" +#import "SourceNode.h" +#import "AudioSource.h" #import "CoreAudioUtils.h" @implementation BufferChain @@ -20,6 +22,8 @@ controller = c; streamURL = nil; userInfo = nil; + + sourceNode = nil; inputNode = nil; converterNode = nil; } @@ -29,6 +33,7 @@ - (void)buildChain { + [sourceNode release]; //Source node is allocated on open.. [inputNode release]; [converterNode release]; @@ -40,12 +45,32 @@ - (BOOL)open:(NSURL *)url withOutputFormat:(AudioStreamBasicDescription)outputFormat { - [url retain]; - [streamURL release]; - streamURL = url; - + [self setStreamURL:url]; + [self buildChain]; - if (![inputNode open:url]) + + id source = [AudioSource audioSourceForURL:url]; + if ([source buffered]) { + sourceNode = [[SourceNode alloc] initWithSource:source]; + source = sourceNode; + } + else { + sourceNode = nil; + } + + if (![source open:url]) + { + NSLog(@"Couldn't open source..."); + return NO; + } + + if (sourceNode) { //If the source is buffered.. + DBLog(@"LAUNCHING THREAD FOR SOURCE"); + [sourceNode launchThread]; + } + + + if (![inputNode openURL:url withSource:source]) return NO; AudioStreamBasicDescription inputFormat; @@ -128,6 +153,14 @@ return streamURL; } +- (void)setStreamURL:(NSURL *)url +{ + [url retain]; + [streamURL release]; + + streamURL = url; +} + - (void)setShouldContinue:(BOOL)s { [inputNode setShouldContinue:s]; diff --git a/Audio/Chain/InputNode.h b/Audio/Chain/InputNode.h index f0d728961..1fd76690e 100644 --- a/Audio/Chain/InputNode.h +++ b/Audio/Chain/InputNode.h @@ -23,7 +23,7 @@ double seekTime; } -- (BOOL)open:(NSURL *)url; +- (BOOL)openURL:(NSURL *)url withSource:(id)source; - (void)process; - (NSDictionary *) properties; - (void)seek:(double)time; diff --git a/Audio/Chain/InputNode.m b/Audio/Chain/InputNode.m index 8a6dd05a4..1f753d06d 100644 --- a/Audio/Chain/InputNode.m +++ b/Audio/Chain/InputNode.m @@ -8,10 +8,11 @@ #import "InputNode.h" #import "BufferChain.h" +#import "Plugin.h" @implementation InputNode -- (BOOL)open:(NSURL *)url +- (BOOL)openURL:(NSURL *)url withSource:(id)source { NSLog(@"Opening: %@", url); decoder = [AudioDecoder audioDecoderForURL:url]; @@ -21,8 +22,11 @@ if (decoder == nil) return NO; - if (![decoder open:url]) + if (![decoder open:source]) + { + NSLog(@"Couldn't open decoder..."); return NO; + } /* while (decoder == nil) { @@ -37,6 +41,7 @@ shouldContinue = YES; shouldSeek = NO; + NSLog(@"OPENED"); return YES; } diff --git a/Audio/Chain/SourceNode.h b/Audio/Chain/SourceNode.h new file mode 100644 index 000000000..4dcb053e7 --- /dev/null +++ b/Audio/Chain/SourceNode.h @@ -0,0 +1,40 @@ +// +// InputNode.h +// Cog +// +// Created by Vincent Spader on 8/2/05. +// Copyright 2005 Vincent Spader. All rights reserved. +// + +#import + +#import "Node.h" +#import "Plugin.h" + +@interface SourceNode : Node +{ + id source; + + long byteCount; +} + +- (id)initWithSource:(id)source; + +- (void)process; + + +//Same interface as the CogSource protocol +- (BOOL)open:(NSURL *)url; + +- (int)read:(void *)buf amount:(int)amount; + +- (BOOL)seekable; +- (BOOL)seek:(long)offset whence:(int)whence; + +- (long)tell; + +- (void)close; + +- (NSDictionary *) properties; +//End of protocol interface +@end diff --git a/Audio/Chain/SourceNode.m b/Audio/Chain/SourceNode.m new file mode 100644 index 000000000..f7f4fc0f3 --- /dev/null +++ b/Audio/Chain/SourceNode.m @@ -0,0 +1,122 @@ +// +// InputNode.m +// Cog +// +// Created by Vincent Spader on 8/2/05. +// Copyright 2005 Vincent Spader. All rights reserved. +// + +#import "SourceNode.h" + +@implementation SourceNode + +- (id)initWithSource:(id)s +{ + self = [super initWithController:nil previous:self]; + if (self) + { + source = [s retain]; + } + return self; +} + +- (void)process +{ + const int chunk_size = CHUNK_SIZE; + char *buf; + int amountRead; + + buf = malloc(chunk_size); + + while ([self shouldContinue] == YES) + { + NSLog(@"PROCESSING!!!"); + amountRead = [source read:buf amount: chunk_size]; + if (amountRead <= 0) + { + endOfStream = YES; + NSLog(@"END OF SOURCE WAS REACHED"); + break; //eof + } + [self writeData:buf amount:amountRead]; + } + + free(buf); + [source close]; + + NSLog(@"CLOSED: %i", self); +} + +- (BOOL)open:(NSURL *)url +{ + shouldContinue = YES; + endOfStream = NO; + + byteCount = 0; + + return [source open:url]; +} + + +- (int)read:(void *)buf amount:(int)amount +{ + int l; + do { + l = [self readData:buf amount:amount]; + if (l > 0) + byteCount += l; + } while (l == 0 && endOfStream == NO); + + NSLog(@"READ: %i", l); + return l; +} + +//Buffered streams are never seekable. +- (BOOL)seekable +{ + return NO; +} + +- (BOOL)seek:(long)offset whence:(int)whence +{ + return NO; +} + +- (long)tell +{ + return byteCount; +} + +- (void)close +{ + NSLog(@"CLOSING"); + shouldContinue = NO; + + [source close]; +} + +- (void)dealloc +{ + [source release]; + + [super dealloc]; +} + +- (NSDictionary *) properties +{ + return [source properties]; +} + +//Shouldnt be used. Required for protocol +- (BOOL)buffered +{ + return YES; +} + ++ (NSArray *) schemes +{ + return nil; +} +//end of shouldnt be used + +@end diff --git a/Audio/CogAudio.xcodeproj/project.pbxproj b/Audio/CogAudio.xcodeproj/project.pbxproj index ec6306dbc..926529467 100644 --- a/Audio/CogAudio.xcodeproj/project.pbxproj +++ b/Audio/CogAudio.xcodeproj/project.pbxproj @@ -9,6 +9,10 @@ /* Begin PBXBuildFile section */ 17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 17A2D3C30B8D1D37000778C4 /* AudioDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 17A2D3C40B8D1D37000778C4 /* AudioDecoder.m */; }; + 17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 17ADB13A0B97926D00257CA2 /* AudioSource.h */; }; + 17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB13B0B97926D00257CA2 /* AudioSource.m */; }; + 17ADB1410B97927C00257CA2 /* SourceNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 17ADB13F0B97927C00257CA2 /* SourceNode.h */; }; + 17ADB1420B97927C00257CA2 /* SourceNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB1400B97927C00257CA2 /* SourceNode.m */; }; 17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 17B6192E0B909BC300BC003F /* AudioPropertiesReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B6192F0B909BC300BC003F /* AudioPropertiesReader.m */; }; 17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 17C940210B900909008627D6 /* AudioMetadataReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -64,6 +68,10 @@ 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 17A2D3C30B8D1D37000778C4 /* AudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDecoder.h; sourceTree = ""; }; 17A2D3C40B8D1D37000778C4 /* AudioDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioDecoder.m; sourceTree = ""; }; + 17ADB13A0B97926D00257CA2 /* AudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AudioSource.h; sourceTree = ""; }; + 17ADB13B0B97926D00257CA2 /* AudioSource.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AudioSource.m; sourceTree = ""; }; + 17ADB13F0B97927C00257CA2 /* SourceNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SourceNode.h; sourceTree = ""; }; + 17ADB1400B97927C00257CA2 /* SourceNode.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = SourceNode.m; sourceTree = ""; }; 17B6192E0B909BC300BC003F /* AudioPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AudioPropertiesReader.h; sourceTree = ""; }; 17B6192F0B909BC300BC003F /* AudioPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AudioPropertiesReader.m; sourceTree = ""; }; 17C940210B900909008627D6 /* AudioMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioMetadataReader.h; sourceTree = ""; }; @@ -169,6 +177,8 @@ 17C940220B900909008627D6 /* AudioMetadataReader.m */, 17B6192E0B909BC300BC003F /* AudioPropertiesReader.h */, 17B6192F0B909BC300BC003F /* AudioPropertiesReader.m */, + 17ADB13A0B97926D00257CA2 /* AudioSource.h */, + 17ADB13B0B97926D00257CA2 /* AudioSource.m */, 17F94DD30B8D0F7000A34E87 /* PluginController.h */, 17F94DD40B8D0F7000A34E87 /* PluginController.m */, 17D21C750B8BE4BA00D1EBDE /* Chain */, @@ -205,6 +215,8 @@ 17D21C750B8BE4BA00D1EBDE /* Chain */ = { isa = PBXGroup; children = ( + 17ADB13F0B97927C00257CA2 /* SourceNode.h */, + 17ADB1400B97927C00257CA2 /* SourceNode.m */, 17D21C760B8BE4BA00D1EBDE /* BufferChain.h */, 17D21C770B8BE4BA00D1EBDE /* BufferChain.m */, 17D21C780B8BE4BA00D1EBDE /* ConverterNode.h */, @@ -298,6 +310,8 @@ 17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */, 17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */, 17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */, + 17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */, + 17ADB1410B97927C00257CA2 /* SourceNode.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -370,6 +384,8 @@ 17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */, 17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */, 17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */, + 17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */, + 17ADB1420B97927C00257CA2 /* SourceNode.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -382,29 +398,7 @@ COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_4)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_5)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_6)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_7)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_8)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_9)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_10)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../FLAC/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_10 = "\"$(SRCROOT)/../WavPack/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../ID3Tag/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../MAC/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/../MAD/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_5 = "\"$(SRCROOT)/../MPCDec/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_6 = "\"$(SRCROOT)/../Ogg/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_7 = "\"$(SRCROOT)/../Shorten/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_8 = "\"$(SRCROOT)/../TagLib/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_9 = "\"$(SRCROOT)/../Vorbis/build/Release\""; + FRAMEWORK_SEARCH_PATHS = ""; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -431,29 +425,7 @@ ); DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_4)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_5)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_6)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_7)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_8)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_9)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_10)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../FLAC/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_10 = "\"$(SRCROOT)/../WavPack/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../ID3Tag/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../MAC/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/../MAD/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_5 = "\"$(SRCROOT)/../MPCDec/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_6 = "\"$(SRCROOT)/../Ogg/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_7 = "\"$(SRCROOT)/../Shorten/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_8 = "\"$(SRCROOT)/../TagLib/build/Release\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_9 = "\"$(SRCROOT)/../Vorbis/build/Release\""; + FRAMEWORK_SEARCH_PATHS = ""; FRAMEWORK_VERSION = A; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; diff --git a/Audio/Plugin.h b/Audio/Plugin.h index 32d770f05..a92bf5fbc 100644 --- a/Audio/Plugin.h +++ b/Audio/Plugin.h @@ -1,35 +1,53 @@ -typedef enum -{ - kCogPluginCodec = 1, - kCogPluginGeneral -} PluginType; +/* + Are defines really appropriate for this? + We want something easily insertable into a dictionary. + Maybe should extern these, and shove the instances in PluginController.m, but will that cause linking problems? +*/ -@protocol CogPlugin -- (PluginType)pluginType; +#define kCogSource @"CogSource" +#define kCogDecoder @"CogDecoder" +#define kCogMetadataReader @"CogMetadataReader" +#define kCogPropertiesReader @"CogPropertiesReader" + +@protocol CogPlugin +//Dictionary containing classname/plugintype pairs. ex: @"VorbisDecoder": kCogDecoder, @"VorbisPropertiesRaeder": kCogPropertiesReader ++ (NSDictionary *)pluginInfo; @end -@protocol CogCodecPlugin -- (Class)decoder; -- (Class)metadataReader; -- (Class)propertiesReader; -@end +@protocol CogSource ++ (NSArray *)schemes; //http, file, etc -@protocol CogDecoder -+ (NSArray *)fileTypes; +- (BOOL)buffered; //Return YES if the input should be buffered, NO if it shouldn't. Used for remote connections (HTTP), not local stuff (file). - (BOOL)open:(NSURL *)url; +- (NSDictionary *)properties; //Perhaps contains header info for HTTP stream, or path for a regular file. +- (BOOL)seekable; +- (BOOL)seek:(long)position whence:(int)whence; +- (long)tell; +- (int)read:(void *)buffer amount:(int)amount; //reads UP TO amount, returns amount read. +- (void)close; +@end + +@protocol CogDecoder ++ (NSArray *)fileTypes; //mp3, ogg, etc + +- (BOOL)open:(id)source; - (NSDictionary *)properties; -- (double)seekToTime:(double)time; +- (BOOL)seekable; +- (double)seekToTime:(double)time; //time is in milleseconds, should return the time actually seeked to. - (int)fillBuffer:(void *)buf ofSize:(UInt32)size; - (void)close; @end -@protocol CogMetadataReader +@protocol CogMetadataReader + (NSArray *)fileTypes; ++ (NSDictionary *)metadataForURL; @end -@protocol CogPropertiesReader +@protocol CogPropertiesReader + (NSArray *)fileTypes; ++ (NSDictionary *)propertiesForSource:(id)source; @end + diff --git a/Audio/PluginController.h b/Audio/PluginController.h index 5f6982fd6..456484347 100644 --- a/Audio/PluginController.h +++ b/Audio/PluginController.h @@ -5,8 +5,7 @@ //Singleton @interface PluginController : NSObject { - NSMutableArray *codecPlugins; - + NSMutableDictionary *sources; NSMutableDictionary *decoders; NSMutableDictionary *metadataReaders; NSMutableDictionary *propertiesReaders; @@ -15,12 +14,17 @@ + (PluginController *)sharedPluginController; //Use this to get the instance. - (void)setup; - -- (void)loadPlugins; -- (void)setupPlugins; - - (void)printPluginInfo; +- (void)loadPlugins; +- (void)loadPluginsAtPath:(NSString *)path; + +- (void)setupSource:(NSString *)className; +- (void)setupDecoder:(NSString *)className; +- (void)setupMetadataReader:(NSString *)className; +- (void)setupPropertiesReader:(NSString *)className; + +- (NSDictionary *)sources; - (NSDictionary *)decoders; - (NSDictionary *)metadataReaders; - (NSDictionary *)propertiesReaders; diff --git a/Audio/PluginController.m b/Audio/PluginController.m index 23166003c..0ff34f86a 100644 --- a/Audio/PluginController.m +++ b/Audio/PluginController.m @@ -58,8 +58,7 @@ static PluginController *sharedPluginController = nil; - (id)init { self = [super init]; if (self) { - codecPlugins = [[NSMutableArray alloc] init]; - + sources = [[NSMutableDictionary alloc] init]; decoders = [[NSMutableDictionary alloc] init]; metadataReaders = [[NSMutableDictionary alloc] init]; propertiesReaders = [[NSMutableDictionary alloc] init]; @@ -73,7 +72,6 @@ static PluginController *sharedPluginController = nil; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [self loadPlugins]; - [self setupPlugins]; [self printPluginInfo]; [pool release]; @@ -99,20 +97,36 @@ static PluginController *sharedPluginController = nil; if (b) { NSLog(@"Loaded bundle: %@", b); - id plugin = [[[b principalClass] alloc] init]; + Class plugin = [b principalClass]; NSLog(@"Candidate: %@", plugin); - if ([plugin respondsToSelector:@selector(pluginType)]) + if ([plugin respondsToSelector:@selector(pluginInfo)]) { - NSLog(@"Responds to selector"); - switch([plugin pluginType]) - { - case kCogPluginCodec: //Only type currently - NSLog(@"Its a codec"); - [codecPlugins addObject:plugin]; - break; - default: - NSLog(@"Unknown plugin type"); - break; + NSLog(@"Responds to selector..."); + //PluginInfo is a dictionary that contains keys/values like pluginClass,classType...ex: VorbisDecoder, Decoder + NSDictionary *pluginInfo = [plugin pluginInfo]; + NSEnumerator *e = [pluginInfo keyEnumerator]; + id className; + while (className = [e nextObject]) { + id pluginType = [pluginInfo objectForKey:className]; + if ([pluginType isEqualToString:kCogDecoder]) { + NSLog(@"DECODER"); + [self setupDecoder:className]; + } + else if ([pluginType isEqualToString:kCogMetadataReader]) { + NSLog(@"Metadata"); + [self setupMetadataReader:className]; + } + else if ([pluginType isEqualToString:kCogPropertiesReader]) { + NSLog(@"Properties"); + [self setupPropertiesReader:className]; + } + else if ([pluginType isEqualToString:kCogSource]) { + NSLog(@"Source"); + [self setupSource:className]; + } + else { + NSLog(@"Unknown plugin type!!"); + } } } } @@ -126,55 +140,69 @@ static PluginController *sharedPluginController = nil; [self loadPluginsAtPath:[@"~/Library/Application Support/Cog/Plugins" stringByExpandingTildeInPath]]; } -- (void)setupInputPlugins +- (void)setupDecoder:(NSString *)className { - NSEnumerator *pluginsEnum = [codecPlugins objectEnumerator]; - id plugin; - while (plugin = [pluginsEnum nextObject]) - { - Class decoder = [plugin decoder]; - Class metadataReader = [plugin metadataReader]; - Class propertiesReader = [plugin propertiesReader]; - - if (decoder) { - NSEnumerator *fileTypesEnum = [[decoder fileTypes] objectEnumerator]; - id fileType; - NSString *classString = NSStringFromClass(decoder); - while (fileType = [fileTypesEnum nextObject]) - { - [decoders setObject:classString forKey:fileType]; - } - } - - if (metadataReader) { - NSEnumerator *fileTypesEnum = [[metadataReader fileTypes] objectEnumerator]; - id fileType; - NSString *classString = NSStringFromClass(metadataReader); - while (fileType = [fileTypesEnum nextObject]) - { - [metadataReaders setObject:classString forKey:fileType]; - } - } - - if (propertiesReader) { - NSEnumerator *fileTypesEnum = [[propertiesReader fileTypes] objectEnumerator]; - id fileType; - NSString *classString = NSStringFromClass(propertiesReader); - while (fileType = [fileTypesEnum nextObject]) - { - [propertiesReaders setObject:classString forKey:fileType]; - } + Class decoder = NSClassFromString(className); + if (decoder && [decoder respondsToSelector:@selector(fileTypes)]) { + NSEnumerator *fileTypesEnum = [[decoder fileTypes] objectEnumerator]; + id fileType; + while (fileType = [fileTypesEnum nextObject]) + { + [decoders setObject:className forKey:fileType]; } } } -- (void)setupPlugins { - [self setupInputPlugins]; +- (void)setupMetadataReader:(NSString *)className +{ + Class metadataReader = NSClassFromString(className); + if (metadataReader && [metadataReader respondsToSelector:@selector(fileTypes)]) { + NSEnumerator *fileTypesEnum = [[metadataReader fileTypes] objectEnumerator]; + id fileType; + while (fileType = [fileTypesEnum nextObject]) + { + [metadataReaders setObject:className forKey:fileType]; + } + } +} + +- (void)setupPropertiesReader:(NSString *)className +{ + Class propertiesReader = NSClassFromString(className); + if (propertiesReader && [propertiesReader respondsToSelector:@selector(fileTypes)]) { + NSEnumerator *fileTypesEnum = [[propertiesReader fileTypes] objectEnumerator]; + id fileType; + while (fileType = [fileTypesEnum nextObject]) + { + [propertiesReaders setObject:className forKey:fileType]; + } + } +} + +- (void)setupSource:(NSString *)className +{ + Class source = NSClassFromString(className); + if (source && [source respondsToSelector:@selector(schemes)]) { + NSEnumerator *schemeEnum = [[source schemes] objectEnumerator]; + id scheme; + while (scheme = [schemeEnum nextObject]) + { + [sources setObject:className forKey:scheme]; + } + } } - (void)printPluginInfo { - NSLog(@"Codecs: %@\n\n", codecPlugins); + NSLog(@"Sources: %@", sources); + NSLog(@"Decoders: %@", decoders); + NSLog(@"Metadata Readers: %@", metadataReaders); + NSLog(@"Properties Readers: %@", propertiesReaders); +} + +- (NSDictionary *)sources +{ + return sources; } - (NSDictionary *)decoders @@ -182,15 +210,18 @@ static PluginController *sharedPluginController = nil; return decoders; } +- (NSDictionary *)propertiesReaders +{ + return propertiesReaders; +} + - (NSDictionary *)metadataReaders { return metadataReaders; } -- (NSDictionary *)propertiesReaders -{ - return propertiesReaders; -} + + @end diff --git a/AudioScrobbler/AudioScrobbler.m b/AudioScrobbler/AudioScrobbler.m index a3c4e52ea..a76a0e7ce 100644 --- a/AudioScrobbler/AudioScrobbler.m +++ b/AudioScrobbler/AudioScrobbler.m @@ -105,7 +105,7 @@ escapeForLastFM(NSString *string) escapeForLastFM([pe album]), @"", // TODO: MusicBrainz support (int)([pe length]/1000.0), - escapeForLastFM([pe filename]) + escapeForLastFM([[pe url] path]) ]]; } diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 874b9118e..92eba302e 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -62,6 +62,8 @@ 177FD1090B90CB5F0011C3B5 /* MAD.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FD01B0B90CAC60011C3B5 /* MAD.bundle */; }; 177FD10A0B90CB5F0011C3B5 /* Flac.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FD0170B90CABF0011C3B5 /* Flac.bundle */; }; 177FD10B0B90CB5F0011C3B5 /* CoreAudio.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FD0130B90CAB50011C3B5 /* CoreAudio.bundle */; }; + 17ADB4580B979C7C00257CA2 /* FileSource.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB4450B979C5700257CA2 /* FileSource.bundle */; }; + 17ADB6650B97A97100257CA2 /* HTTPSource.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB65C0B97A96400257CA2 /* HTTPSource.bundle */; }; 17B61B5E0B90A27F00BC003F /* CogAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17B61B5D0B90A27F00BC003F /* CogAudio.framework */; }; 17B61B630B90A28100BC003F /* CogAudio.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17B61B5D0B90A27F00BC003F /* CogAudio.framework */; }; 17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17BB5CEC0B8A86010009ACB1 /* AudioToolbox.framework */; }; @@ -113,6 +115,8 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + 17ADB6650B97A97100257CA2 /* HTTPSource.bundle in CopyFiles */, + 17ADB4580B979C7C00257CA2 /* FileSource.bundle in CopyFiles */, 177FD1030B90CB5F0011C3B5 /* WavPack.bundle in CopyFiles */, 177FD1040B90CB5F0011C3B5 /* Vorbis.bundle in CopyFiles */, 177FD1050B90CB5F0011C3B5 /* TagLib.bundle in CopyFiles */, @@ -219,6 +223,8 @@ 177FD02B0B90CAE50011C3B5 /* TagLib.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = TagLib.bundle; path = Plugins/TagLib/build/Release/TagLib.bundle; sourceTree = ""; }; 177FD02F0B90CAEC0011C3B5 /* Vorbis.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Vorbis.bundle; path = Plugins/Vorbis/build/Release/Vorbis.bundle; sourceTree = ""; }; 177FD0330B90CAF40011C3B5 /* WavPack.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = WavPack.bundle; path = Plugins/WavPack/build/Release/WavPack.bundle; sourceTree = ""; }; + 17ADB4450B979C5700257CA2 /* FileSource.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = FileSource.bundle; path = Plugins/FileSource/build/Release/FileSource.bundle; sourceTree = ""; }; + 17ADB65C0B97A96400257CA2 /* HTTPSource.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = HTTPSource.bundle; path = Plugins/HTTPSource/build/Release/HTTPSource.bundle; sourceTree = ""; }; 17B61B5D0B90A27F00BC003F /* CogAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CogAudio.framework; path = Audio/build/Release/CogAudio.framework; sourceTree = ""; }; 17BB5CEC0B8A86010009ACB1 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 17BB5CF60B8A86350009ACB1 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = ""; }; @@ -495,6 +501,8 @@ 17B619FF0B909ED400BC003F /* PlugIns */ = { isa = PBXGroup; children = ( + 17ADB65C0B97A96400257CA2 /* HTTPSource.bundle */, + 17ADB4450B979C5700257CA2 /* FileSource.bundle */, 177FD0330B90CAF40011C3B5 /* WavPack.bundle */, 177FD02F0B90CAEC0011C3B5 /* Vorbis.bundle */, 177FD02B0B90CAE50011C3B5 /* TagLib.bundle */, diff --git a/English.lproj/MainMenu.nib/classes.nib b/English.lproj/MainMenu.nib/classes.nib index d576a7eba..2da70b08c 100644 --- a/English.lproj/MainMenu.nib/classes.nib +++ b/English.lproj/MainMenu.nib/classes.nib @@ -14,6 +14,9 @@ }, { ACTIONS = { + addURL = id; + addURLSheetCancel = id; + addURLSheetOK = id; delEntries = id; donate = id; loadPlaylist = id; @@ -26,6 +29,7 @@ CLASS = AppController; LANGUAGE = ObjC; OUTLETS = { + addURLPanel = NSPanel; fileButton = NSButton; fileDrawer = NSDrawer; fileOutlineView = FileOutlineView; @@ -49,6 +53,7 @@ showTrackColumn = NSMenuItem; showYearColumn = NSMenuItem; shuffleButton = NSButton; + urlField = NSTextField; }; SUPERCLASS = NSObject; }, diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib index 6ebc0d048..5f7d182dd 100644 --- a/English.lproj/MainMenu.nib/info.nib +++ b/English.lproj/MainMenu.nib/info.nib @@ -32,11 +32,12 @@ 4 IBOpenObjects - 513 463 1156 - 29 + 1307 + 513 21 + 29 IBSystem Version 8L2127 diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib index 2a3f6a98138bcb4835ea8c0c6b0db3a8b0223de4..3f1ae5788c90d41c659c9d6d0647092b75c3ca70 100644 GIT binary patch delta 37989 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 delta 36292 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 diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index 4119e7d3e..27c993ffc 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -122,7 +122,7 @@ { PlaylistEntry *pe = [[PlaylistEntry alloc] init]; - [pe setFilename:[sortedFiles objectAtIndex:i]]; + [pe setURL:[NSURL fileURLWithPath:[sortedFiles objectAtIndex:i]]]; [pe setIndex:index+i]; [pe setTitle:[[sortedFiles objectAtIndex:i] lastPathComponent]]; // [pe performSelectorOnMainThread:@selector(readTags) withObject:nil waitUntilDone:NO]; @@ -365,7 +365,7 @@ - (IBAction)sortByPath:(id)sender { - NSSortDescriptor *s = [[NSSortDescriptor alloc] initWithKey:@"filename" ascending:YES selector:@selector(compare:)]; + NSSortDescriptor *s = [[NSSortDescriptor alloc] initWithKey:@"url" ascending:YES selector:@selector(compare:)]; [self setSortDescriptors:[NSArray arrayWithObject:s]]; [self rearrangeObjects]; @@ -621,7 +621,7 @@ BOOL found = NO; for (i = 1; i < [shuffleList count]; i++) { - if (found == NO && [[shuffleList objectAtIndex:i] filename] == [currentEntry filename]) + if (found == NO && [[shuffleList objectAtIndex:i] url] == [currentEntry url]) { found = YES; [shuffleList removeObjectAtIndex:i]; @@ -696,7 +696,7 @@ enumerator = [[self content] objectEnumerator]; while (entry = [enumerator nextObject]) { - [filenames addObject:[entry filename]]; + [filenames addObject:[[entry url] path]]; } fileContents = [filenames componentsJoinedByString:@"\n"]; @@ -741,7 +741,7 @@ return; PlaylistEntry* curr = [self entryAtIndex:[self selectionIndex]]; - [ws selectFile:[curr filename] inFileViewerRootedAtPath:[curr filename]]; + [ws selectFile:[[curr url] path] inFileViewerRootedAtPath:[[curr url] path]]; } - (void)handlePlaylistViewHeaderNotification:(NSNotification*)notif diff --git a/Playlist/PlaylistEntry.h b/Playlist/PlaylistEntry.h index 5c5556dba..c16bd8983 100644 --- a/Playlist/PlaylistEntry.h +++ b/Playlist/PlaylistEntry.h @@ -9,7 +9,7 @@ #import @interface PlaylistEntry : NSObject { - NSString *filename; + NSURL *url; NSString *artist; NSString *album; @@ -40,8 +40,8 @@ -(void)setShuffleIndex:(int)si; -(int)shuffleIndex; --(void)setFilename:(NSString *)f; --(NSString *)filename; +-(void)setURL:(NSURL *)u; +-(NSURL *)url; -(void)setCurrent:(BOOL) b; -(BOOL)current; diff --git a/Playlist/PlaylistEntry.m b/Playlist/PlaylistEntry.m index 1d0413b42..fc889c600 100644 --- a/Playlist/PlaylistEntry.m +++ b/Playlist/PlaylistEntry.m @@ -18,7 +18,7 @@ if (self) { [self setIndex:0]; - [self setFilename:@""]; + [self setURL:nil]; } return self; @@ -26,7 +26,7 @@ - (void)dealloc { - [filename release]; + [url release]; [super dealloc]; } @@ -62,16 +62,16 @@ return displayIdx; } --(void)setFilename:(NSString *)f +-(void)setURL:(NSURL *)u { - f = [f copy]; - [filename release]; - filename = f; + [u retain]; + [url release]; + url = u; } --(NSString *)filename +-(NSURL *)url { - return filename; + return url; } -(void)setCurrent:(BOOL) b @@ -177,7 +177,7 @@ - (void)readInfoThreaded { - NSDictionary *properties = [AudioPropertiesReader propertiesForURL:[NSURL fileURLWithPath:filename]]; + NSDictionary *properties = [AudioPropertiesReader propertiesForURL:url]; [self performSelectorOnMainThread:@selector(readInfoThreadedSetVariables:) withObject:properties waitUntilDone:YES]; } @@ -245,7 +245,7 @@ NSString *ti = [m objectForKey:@"title"]; if ([ti isEqualToString:@""]) { - [self setTitle:[filename lastPathComponent]]; + [self setTitle:[[url path] lastPathComponent]]; } else { [self setTitle:[m objectForKey:@"title"]]; @@ -260,7 +260,7 @@ - (void)readTagsThreaded { - NSDictionary *metadata = [AudioMetadataReader metadataForURL:[NSURL fileURLWithPath:filename]]; + NSDictionary *metadata = [AudioMetadataReader metadataForURL:url]; [self performSelectorOnMainThread:@selector(readTagsThreadedSetVariables:) withObject:metadata waitUntilDone:YES]; @@ -268,7 +268,7 @@ - (NSString *)description { - return [NSString stringWithFormat:@"PlaylistEntry %i:(%@)",idx, filename]; + return [NSString stringWithFormat:@"PlaylistEntry %i:(%@)",idx, url]; } @end diff --git a/Plugins/CoreAudio/CoreAudio.xcodeproj/project.pbxproj b/Plugins/CoreAudio/CoreAudio.xcodeproj/project.pbxproj index 5833d3914..f9c1c15b7 100644 --- a/Plugins/CoreAudio/CoreAudio.xcodeproj/project.pbxproj +++ b/Plugins/CoreAudio/CoreAudio.xcodeproj/project.pbxproj @@ -8,10 +8,10 @@ /* Begin PBXBuildFile section */ 1745C21A0B90B7F800A6768C /* CoreAudioPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1745C2190B90B7F800A6768C /* CoreAudioPropertiesReader.m */; }; + 17ADB19A0B97937600257CA2 /* CoreAudioPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB1990B97937600257CA2 /* CoreAudioPlugin.m */; }; 17C93E740B8FF192008627D6 /* CoreAudioDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C93E730B8FF192008627D6 /* CoreAudioDecoder.m */; }; 17C93EAC0B8FF3CE008627D6 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C93EAB0B8FF3CE008627D6 /* CoreAudio.framework */; }; 17C93EB30B8FF3E1008627D6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C93EB20B8FF3E1008627D6 /* AudioToolbox.framework */; }; - 17F94E1D0B8D128500A34E87 /* CoreAudioCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F94E1C0B8D128500A34E87 /* CoreAudioCodec.m */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -22,12 +22,12 @@ 1745C2180B90B7F800A6768C /* CoreAudioPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CoreAudioPropertiesReader.h; sourceTree = ""; }; 1745C2190B90B7F800A6768C /* CoreAudioPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = CoreAudioPropertiesReader.m; sourceTree = ""; }; 177FCFCA0B90C9A10011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + 17ADB1980B97937600257CA2 /* CoreAudioPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CoreAudioPlugin.h; sourceTree = ""; }; + 17ADB1990B97937600257CA2 /* CoreAudioPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = CoreAudioPlugin.m; sourceTree = ""; }; 17C93E720B8FF192008627D6 /* CoreAudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CoreAudioDecoder.h; sourceTree = ""; }; 17C93E730B8FF192008627D6 /* CoreAudioDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = CoreAudioDecoder.m; sourceTree = ""; }; 17C93EAB0B8FF3CE008627D6 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; 17C93EB20B8FF3E1008627D6 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; - 17F94E1B0B8D128500A34E87 /* CoreAudioCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudioCodec.h; sourceTree = ""; }; - 17F94E1C0B8D128500A34E87 /* CoreAudioCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreAudioCodec.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* CoreAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudio_Prefix.pch; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* CoreAudio.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreAudio.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; @@ -81,8 +81,8 @@ isa = PBXGroup; children = ( 177FCFCA0B90C9A10011C3B5 /* Plugin.h */, - 17F94E1B0B8D128500A34E87 /* CoreAudioCodec.h */, - 17F94E1C0B8D128500A34E87 /* CoreAudioCodec.m */, + 17ADB1980B97937600257CA2 /* CoreAudioPlugin.h */, + 17ADB1990B97937600257CA2 /* CoreAudioPlugin.m */, 17C93E720B8FF192008627D6 /* CoreAudioDecoder.h */, 17C93E730B8FF192008627D6 /* CoreAudioDecoder.m */, 1745C2180B90B7F800A6768C /* CoreAudioPropertiesReader.h */, @@ -178,9 +178,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 17F94E1D0B8D128500A34E87 /* CoreAudioCodec.m in Sources */, 17C93E740B8FF192008627D6 /* CoreAudioDecoder.m in Sources */, 1745C21A0B90B7F800A6768C /* CoreAudioPropertiesReader.m in Sources */, + 17ADB19A0B97937600257CA2 /* CoreAudioPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/CoreAudio/CoreAudioCodec.m b/Plugins/CoreAudio/CoreAudioCodec.m deleted file mode 100644 index 71a0762f4..000000000 --- a/Plugins/CoreAudio/CoreAudioCodec.m +++ /dev/null @@ -1,39 +0,0 @@ -// -// CoreAudio.m -// CoreAudio -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "CoreAudioCodec.h" -#import "CoreAudioDecoder.h" -#import "CoreAudioPropertiesReader.h" - -@implementation CoreAudioCodec - -- (int)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [CoreAudioDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [CoreAudioPropertiesReader class]; -} - - - - - -@end diff --git a/Plugins/CoreAudio/CoreAudioCodec.h b/Plugins/CoreAudio/CoreAudioPlugin.h similarity index 78% rename from Plugins/CoreAudio/CoreAudioCodec.h rename to Plugins/CoreAudio/CoreAudioPlugin.h index c61baa3ac..324b378b8 100644 --- a/Plugins/CoreAudio/CoreAudioCodec.h +++ b/Plugins/CoreAudio/CoreAudioPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface CoreAudioCodec : NSObject +@interface CoreAudioPlugin : NSObject { } diff --git a/Plugins/CoreAudio/CoreAudioPlugin.m b/Plugins/CoreAudio/CoreAudioPlugin.m new file mode 100644 index 000000000..e4690270d --- /dev/null +++ b/Plugins/CoreAudio/CoreAudioPlugin.m @@ -0,0 +1,24 @@ +// +// CoreAudio.m +// CoreAudio +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "CoreAudioPlugin.h" +#import "CoreAudioDecoder.h" +#import "CoreAudioPropertiesReader.h" + +@implementation CoreAudioPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [CoreAudioDecoder className], + kCogPropertiesReader, [CoreAudioPropertiesReader className], + nil + ]; +} + +@end diff --git a/Plugins/CoreAudio/Info.plist b/Plugins/CoreAudio/Info.plist index 43bc09cf9..7997fbfa9 100644 --- a/Plugins/CoreAudio/Info.plist +++ b/Plugins/CoreAudio/Info.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - CoreAudioCodec + CoreAudioPlugin diff --git a/Plugins/FileSource/FileSource.h b/Plugins/FileSource/FileSource.h new file mode 100644 index 000000000..9ae4baa7f --- /dev/null +++ b/Plugins/FileSource/FileSource.h @@ -0,0 +1,18 @@ +// +// FileSource.h +// FileSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface FileSource : NSObject +{ + FILE *_fd; +} + +@end diff --git a/Plugins/FileSource/FileSource.m b/Plugins/FileSource/FileSource.m new file mode 100644 index 000000000..6343a5c09 --- /dev/null +++ b/Plugins/FileSource/FileSource.m @@ -0,0 +1,61 @@ +// +// FileSource.m +// FileSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "FileSource.h" + + +@implementation FileSource + +- (BOOL)buffered +{ + return NO; +} + +- (BOOL)open:(NSURL *)url +{ + _fd = fopen([[url path] UTF8String], "r"); + + return (_fd != NULL); +} + +- (NSDictionary *)properties +{ + return nil; +} + +- (BOOL)seekable +{ + return YES; +} + +- (BOOL)seek:(long)position whence:(int)whence +{ + return (fseek(_fd, position, whence) == 0); +} + +- (long)tell +{ + return ftell(_fd); +} + +- (int)read:(void *)buffer amount:(int)amount +{ + return fread(buffer, 1, amount, _fd); +} + +- (void)close +{ + fclose(_fd); +} + ++ (NSArray *)schemes +{ + return [NSArray arrayWithObject:@"file"]; +} + +@end diff --git a/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj b/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj new file mode 100644 index 000000000..2ed4b1545 --- /dev/null +++ b/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj @@ -0,0 +1,256 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 17ADB3FF0B979A4600257CA2 /* FileSourcePlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB3FE0B979A4600257CA2 /* FileSourcePlugin.m */; }; + 17ADB41A0B979AEB00257CA2 /* FileSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB4190B979AEB00257CA2 /* FileSource.m */; }; + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 17ADB3FD0B979A4600257CA2 /* FileSourcePlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSourcePlugin.h; sourceTree = ""; }; + 17ADB3FE0B979A4600257CA2 /* FileSourcePlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileSourcePlugin.m; sourceTree = ""; }; + 17ADB4080B979A8A00257CA2 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + 17ADB4180B979AEB00257CA2 /* FileSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource.h; sourceTree = ""; }; + 17ADB4190B979AEB00257CA2 /* FileSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileSource.m; sourceTree = ""; }; + 32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource_Prefix.pch; sourceTree = ""; }; + 8D5B49B6048680CD000E48DA /* FileSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* 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 /* FileSource */ = { + isa = PBXGroup; + children = ( + 08FB77AFFE84173DC02AAC07 /* Classes */, + 32C88E010371C26100C91783 /* Other Sources */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, + 19C28FB8FE9D52D311CA2CBB /* Products */, + ); + name = FileSource; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, + ); + name = "Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D5B49B7048680CD000E48DA /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + 17ADB4080B979A8A00257CA2 /* Plugin.h */, + 17ADB3FD0B979A4600257CA2 /* FileSourcePlugin.h */, + 17ADB3FE0B979A4600257CA2 /* FileSourcePlugin.m */, + 17ADB4180B979AEB00257CA2 /* FileSource.h */, + 17ADB4190B979AEB00257CA2 /* FileSource.m */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 089C167FFE841241C02AAC07 /* AppKit.framework */, + D2F7E65807B2D6F200F64583 /* CoreData.framework */, + 089C1672FE841209C02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FB8FE9D52D311CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D5B49B6048680CD000E48DA /* FileSource.bundle */, + ); + name = Products; + sourceTree = ""; + }; + 32C88E010371C26100C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D5B49AC048680CD000E48DA /* FileSource */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "FileSource" */; + buildPhases = ( + 8D5B49AF048680CD000E48DA /* Resources */, + 8D5B49B1048680CD000E48DA /* Sources */, + 8D5B49B3048680CD000E48DA /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FileSource; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = FileSource; + productReference = 8D5B49B6048680CD000E48DA /* FileSource.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 "FileSource" */; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* FileSource */; + projectDirPath = ""; + targets = ( + 8D5B49AC048680CD000E48DA /* FileSource */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D5B49AF048680CD000E48DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D5B49B1048680CD000E48DA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 17ADB3FF0B979A4600257CA2 /* FileSourcePlugin.m in Sources */, + 17ADB41A0B979AEB00257CA2 /* FileSource.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase 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 = FileSource_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = FileSource; + 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 = FileSource_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = FileSource; + 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 "FileSource" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913B08733D840010E9CD /* Debug */, + 1DEB913C08733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "FileSource" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913F08733D840010E9CD /* Debug */, + 1DEB914008733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/Plugins/FileSource/FileSourcePlugin.h b/Plugins/FileSource/FileSourcePlugin.h new file mode 100644 index 000000000..e5f2210ea --- /dev/null +++ b/Plugins/FileSource/FileSourcePlugin.h @@ -0,0 +1,18 @@ +// +// FileSourcePlugin.h +// FileSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface FileSourcePlugin : NSObject +{ + +} + +@end diff --git a/Plugins/FileSource/FileSourcePlugin.m b/Plugins/FileSource/FileSourcePlugin.m new file mode 100644 index 000000000..a3f0c1a6b --- /dev/null +++ b/Plugins/FileSource/FileSourcePlugin.m @@ -0,0 +1,23 @@ +// +// FileSourcePlugin.m +// FileSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "FileSourcePlugin.h" +#import "FileSource.h" + +@implementation FileSourcePlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogSource, [FileSource className], + nil + ]; +} + + +@end diff --git a/Plugins/FileSource/FileSource_Prefix.pch b/Plugins/FileSource/FileSource_Prefix.pch new file mode 100644 index 000000000..5b4792b4e --- /dev/null +++ b/Plugins/FileSource/FileSource_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'FileSource' target in the 'FileSource' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Plugins/FileSource/Info.plist b/Plugins/FileSource/Info.plist new file mode 100644 index 000000000..ad674b62f --- /dev/null +++ b/Plugins/FileSource/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.yourcocoabundle + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + FileSourcePlugin + + diff --git a/Plugins/Flac/Flac.xcodeproj/project.pbxproj b/Plugins/Flac/Flac.xcodeproj/project.pbxproj index f72978eac..cf20ef0b8 100644 --- a/Plugins/Flac/Flac.xcodeproj/project.pbxproj +++ b/Plugins/Flac/Flac.xcodeproj/project.pbxproj @@ -11,8 +11,9 @@ 177FCFC20B90C9960011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCFC10B90C9960011C3B5 /* Plugin.h */; }; 179CFDB20B90C73400C8C4DB /* FLAC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 179CFDB10B90C73400C8C4DB /* FLAC.framework */; }; 179CFDB50B90C73900C8C4DB /* FLAC.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 179CFDB10B90C73400C8C4DB /* FLAC.framework */; }; + 17ADB1B40B9793A600257CA2 /* FlacPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB1B20B9793A600257CA2 /* FlacPlugin.h */; }; + 17ADB1B50B9793A600257CA2 /* FlacPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB1B30B9793A600257CA2 /* FlacPlugin.m */; }; 17C93F080B8FF67A008627D6 /* FlacDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C93F040B8FF67A008627D6 /* FlacDecoder.m */; }; - 17C93F090B8FF67A008627D6 /* FlacCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C93F070B8FF67A008627D6 /* FlacCodec.m */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -25,6 +26,7 @@ files = ( 179CFDB50B90C73900C8C4DB /* FLAC.framework in CopyFiles */, 177FCFC20B90C9960011C3B5 /* Plugin.h in CopyFiles */, + 17ADB1B40B9793A600257CA2 /* FlacPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -38,10 +40,10 @@ 1745C2C30B90BAC700A6768C /* FlacPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FlacPropertiesReader.m; sourceTree = ""; }; 177FCFC10B90C9960011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 179CFDB10B90C73400C8C4DB /* FLAC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FLAC.framework; path = ../../Frameworks/FLAC/build/Release/FLAC.framework; sourceTree = SOURCE_ROOT; }; + 17ADB1B20B9793A600257CA2 /* FlacPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FlacPlugin.h; sourceTree = ""; }; + 17ADB1B30B9793A600257CA2 /* FlacPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FlacPlugin.m; sourceTree = ""; }; 17C93F030B8FF67A008627D6 /* FlacDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FlacDecoder.h; sourceTree = ""; }; 17C93F040B8FF67A008627D6 /* FlacDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FlacDecoder.m; sourceTree = ""; }; - 17C93F060B8FF67A008627D6 /* FlacCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FlacCodec.h; sourceTree = ""; }; - 17C93F070B8FF67A008627D6 /* FlacCodec.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = FlacCodec.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* Flac_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flac_Prefix.pch; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* Flac.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Flac.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; @@ -94,8 +96,8 @@ isa = PBXGroup; children = ( 177FCFC10B90C9960011C3B5 /* Plugin.h */, - 17C93F060B8FF67A008627D6 /* FlacCodec.h */, - 17C93F070B8FF67A008627D6 /* FlacCodec.m */, + 17ADB1B20B9793A600257CA2 /* FlacPlugin.h */, + 17ADB1B30B9793A600257CA2 /* FlacPlugin.m */, 17C93F030B8FF67A008627D6 /* FlacDecoder.h */, 17C93F040B8FF67A008627D6 /* FlacDecoder.m */, 1745C2C20B90BAC700A6768C /* FlacPropertiesReader.h */, @@ -192,8 +194,8 @@ buildActionMask = 2147483647; files = ( 17C93F080B8FF67A008627D6 /* FlacDecoder.m in Sources */, - 17C93F090B8FF67A008627D6 /* FlacCodec.m in Sources */, 1745C2C50B90BAC700A6768C /* FlacPropertiesReader.m in Sources */, + 17ADB1B50B9793A600257CA2 /* FlacPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/Flac/FlacCodec.m b/Plugins/Flac/FlacCodec.m deleted file mode 100644 index dcf0f374d..000000000 --- a/Plugins/Flac/FlacCodec.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "FlacCodec.h" -#import "FlacDecoder.h" -#import "FlacPropertiesReader.h" - -@implementation FlacCodec - -- (int)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [FlacDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [FlacPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/MAD/MADCodec.h b/Plugins/Flac/FlacPlugin.h similarity index 80% rename from Plugins/MAD/MADCodec.h rename to Plugins/Flac/FlacPlugin.h index 43c2a1ea7..3d9461536 100644 --- a/Plugins/MAD/MADCodec.h +++ b/Plugins/Flac/FlacPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface MADCodec : NSObject +@interface FlacPlugin : NSObject { } diff --git a/Plugins/Flac/FlacPlugin.m b/Plugins/Flac/FlacPlugin.m new file mode 100644 index 000000000..74e956098 --- /dev/null +++ b/Plugins/Flac/FlacPlugin.m @@ -0,0 +1,25 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "FlacPlugin.h" +#import "FlacDecoder.h" +#import "FlacPropertiesReader.h" + +@implementation FlacPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [FlacDecoder className], + kCogPropertiesReader, [FlacPropertiesReader className], + nil + ]; +} + + +@end diff --git a/Plugins/Flac/Info.plist b/Plugins/Flac/Info.plist index 2ae4c2612..59c5deaaf 100644 --- a/Plugins/Flac/Info.plist +++ b/Plugins/Flac/Info.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - FlacCodec + FlacPlugin diff --git a/Plugins/HTTPSource/HTTPSource.h b/Plugins/HTTPSource/HTTPSource.h new file mode 100644 index 000000000..eb5310531 --- /dev/null +++ b/Plugins/HTTPSource/HTTPSource.h @@ -0,0 +1,21 @@ +// +// HTTPSource.h +// HTTPSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Socket.h" +#import "Plugin.h" + +@interface HTTPSource : NSObject +{ + Socket *_socket; + + long byteCount; +} + +@end diff --git a/Plugins/HTTPSource/HTTPSource.m b/Plugins/HTTPSource/HTTPSource.m new file mode 100644 index 000000000..1fc9e2931 --- /dev/null +++ b/Plugins/HTTPSource/HTTPSource.m @@ -0,0 +1,75 @@ +// +// HTTPSource.m +// HTTPSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "HTTPSource.h" + + +@implementation HTTPSource + +- (BOOL)buffered +{ + return NO; +} + +- (BOOL)open:(NSURL *)url +{ + + unsigned int port = [[url port] unsignedIntValue]; + if (!port) + port = 80; + + _socket = [[Socket alloc] initWithHost:[url host] port:port]; + + if (_socket) { + NSData *request = [[NSString stringWithFormat:@"GET %@ HTTP/1.0\nHOST: %@\n\n",[url path],[url host]] dataUsingEncoding:NSUTF8StringEncoding]; + [_socket send:(void *)[request bytes] amount:[request length]]; + } + + return (_socket != nil); +} + +- (NSDictionary *)properties +{ + return nil; +} + +- (BOOL)seekable +{ + return NO; +} + +- (BOOL)seek:(long)position whence:(int)whence +{ + return NO; +} + +- (long)tell +{ + return byteCount; +} + +- (int)read:(void *)buffer amount:(int)amount +{ + int l = [_socket receive:buffer amount:amount]; + if (l > 0) + byteCount += l; + + return l; +} + +- (void)close +{ + [_socket close]; +} + ++ (NSArray *)schemes +{ + return [NSArray arrayWithObject:@"http"]; +} + +@end diff --git a/Plugins/HTTPSource/HTTPSource.xcodeproj/project.pbxproj b/Plugins/HTTPSource/HTTPSource.xcodeproj/project.pbxproj new file mode 100644 index 000000000..a9cf2d478 --- /dev/null +++ b/Plugins/HTTPSource/HTTPSource.xcodeproj/project.pbxproj @@ -0,0 +1,270 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 17ADB60B0B97A73B00257CA2 /* Socket.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB60A0B97A73B00257CA2 /* Socket.m */; }; + 17ADB6100B97A74800257CA2 /* HTTPSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB60D0B97A74800257CA2 /* HTTPSource.m */; }; + 17ADB6110B97A74800257CA2 /* HTTPSourcePlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB60F0B97A74800257CA2 /* HTTPSourcePlugin.m */; }; + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 17ADB6090B97A73B00257CA2 /* Socket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Socket.h; sourceTree = ""; }; + 17ADB60A0B97A73B00257CA2 /* Socket.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = Socket.m; sourceTree = ""; }; + 17ADB60C0B97A74800257CA2 /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTTPSource.h; sourceTree = ""; }; + 17ADB60D0B97A74800257CA2 /* HTTPSource.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = HTTPSource.m; sourceTree = ""; }; + 17ADB60E0B97A74800257CA2 /* HTTPSourcePlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTTPSourcePlugin.h; sourceTree = ""; }; + 17ADB60F0B97A74800257CA2 /* HTTPSourcePlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = HTTPSourcePlugin.m; sourceTree = ""; }; + 17ADB6340B97A8B400257CA2 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + 32DBCF630370AF2F00C91783 /* HTTPSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPSource_Prefix.pch; sourceTree = ""; }; + 8D5B49B6048680CD000E48DA /* HTTPSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTTPSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* 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 /* HTTPSource */ = { + isa = PBXGroup; + children = ( + 08FB77AFFE84173DC02AAC07 /* Classes */, + 32C88E010371C26100C91783 /* Other Sources */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, + 19C28FB8FE9D52D311CA2CBB /* Products */, + ); + name = HTTPSource; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, + ); + name = "Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D5B49B7048680CD000E48DA /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + 17ADB6340B97A8B400257CA2 /* Plugin.h */, + 17ADB60C0B97A74800257CA2 /* HTTPSource.h */, + 17ADB60D0B97A74800257CA2 /* HTTPSource.m */, + 17ADB60E0B97A74800257CA2 /* HTTPSourcePlugin.h */, + 17ADB60F0B97A74800257CA2 /* HTTPSourcePlugin.m */, + 17ADB6080B97A73B00257CA2 /* Utils */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 089C167FFE841241C02AAC07 /* AppKit.framework */, + D2F7E65807B2D6F200F64583 /* CoreData.framework */, + 089C1672FE841209C02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 17ADB6080B97A73B00257CA2 /* Utils */ = { + isa = PBXGroup; + children = ( + 17ADB6090B97A73B00257CA2 /* Socket.h */, + 17ADB60A0B97A73B00257CA2 /* Socket.m */, + ); + path = Utils; + sourceTree = ""; + }; + 19C28FB8FE9D52D311CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D5B49B6048680CD000E48DA /* HTTPSource.bundle */, + ); + name = Products; + sourceTree = ""; + }; + 32C88E010371C26100C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF630370AF2F00C91783 /* HTTPSource_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D5B49AC048680CD000E48DA /* HTTPSource */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "HTTPSource" */; + buildPhases = ( + 8D5B49AF048680CD000E48DA /* Resources */, + 8D5B49B1048680CD000E48DA /* Sources */, + 8D5B49B3048680CD000E48DA /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HTTPSource; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = HTTPSource; + productReference = 8D5B49B6048680CD000E48DA /* HTTPSource.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 "HTTPSource" */; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* HTTPSource */; + projectDirPath = ""; + targets = ( + 8D5B49AC048680CD000E48DA /* HTTPSource */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D5B49AF048680CD000E48DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D5B49B1048680CD000E48DA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 17ADB60B0B97A73B00257CA2 /* Socket.m in Sources */, + 17ADB6100B97A74800257CA2 /* HTTPSource.m in Sources */, + 17ADB6110B97A74800257CA2 /* HTTPSourcePlugin.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase 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 = HTTPSource_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = HTTPSource; + 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 = HTTPSource_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = HTTPSource; + 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 "HTTPSource" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913B08733D840010E9CD /* Debug */, + 1DEB913C08733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "HTTPSource" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913F08733D840010E9CD /* Debug */, + 1DEB914008733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/Plugins/HTTPSource/HTTPSourcePlugin.h b/Plugins/HTTPSource/HTTPSourcePlugin.h new file mode 100644 index 000000000..57703fd70 --- /dev/null +++ b/Plugins/HTTPSource/HTTPSourcePlugin.h @@ -0,0 +1,18 @@ +// +// HTTPSourcePlugin.h +// HTTPSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface HTTPSourcePlugin : NSObject +{ + +} + +@end diff --git a/Plugins/HTTPSource/HTTPSourcePlugin.m b/Plugins/HTTPSource/HTTPSourcePlugin.m new file mode 100644 index 000000000..82f760d29 --- /dev/null +++ b/Plugins/HTTPSource/HTTPSourcePlugin.m @@ -0,0 +1,23 @@ +// +// HTTPSourcePlugin.m +// FileSource +// +// Created by Vincent Spader on 3/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "HTTPSourcePlugin.h" +#import "HTTPSource.h" + +@implementation HTTPSourcePlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogSource, [HTTPSource className], + nil + ]; +} + + +@end diff --git a/Plugins/HTTPSource/HTTPSource_Prefix.pch b/Plugins/HTTPSource/HTTPSource_Prefix.pch new file mode 100644 index 000000000..9314a6e7b --- /dev/null +++ b/Plugins/HTTPSource/HTTPSource_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'HTTPSource' target in the 'HTTPSource' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Plugins/HTTPSource/Info.plist b/Plugins/HTTPSource/Info.plist new file mode 100644 index 000000000..a6170715e --- /dev/null +++ b/Plugins/HTTPSource/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.yourcocoabundle + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + HTTPSourcePlugin + + diff --git a/Plugins/HTTPSource/Utils/Socket.h b/Plugins/HTTPSource/Utils/Socket.h new file mode 100644 index 000000000..d77c70a05 --- /dev/null +++ b/Plugins/HTTPSource/Utils/Socket.h @@ -0,0 +1,23 @@ +// +// Socket.h +// Cog +// +// Created by Vincent Spader on 2/28/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +//Rediculously simple socket wrapper +@interface Socket : NSObject { + int _fd; +} + ++ (id)socketWithHost:(NSString *)host port:(unsigned int) port; +- (id)initWithHost:(NSString *)host port:(unsigned int)port; + +- (int)send:(const void *)data amount:(unsigned int)amount; +- (int)receive:(void *)data amount:(unsigned int)amount; +- (void)close; + +@end diff --git a/Plugins/HTTPSource/Utils/Socket.m b/Plugins/HTTPSource/Utils/Socket.m new file mode 100644 index 000000000..4979e78cf --- /dev/null +++ b/Plugins/HTTPSource/Utils/Socket.m @@ -0,0 +1,77 @@ +// +// Socket.m +// Cog +// +// Created by Vincent Spader on 2/28/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "Socket.h" +#import + +@implementation Socket + ++ (id)socketWithHost:(NSString *)host port:(unsigned int)port +{ + return [[[Socket alloc] initWithHost:host port:port] autorelease]; +} + +- (id)initWithHost:(NSString *)host port:(unsigned int) port +{ + self = [super init]; + if (self) + { + _fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + struct sockaddr_in sin; + struct hostent *he; + + if (_fd < 0) { + NSLog(@"%s\n", strerror(errno)); + return nil; + } + + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + + he = gethostbyname([host UTF8String]); + if (!he) { + NSLog(@"Socket error."); + close(_fd); + return nil; + } + memcpy(&sin.sin_addr, he->h_addr, 4); + + if (connect(_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + NSLog(@"%s\n", strerror(errno)); + close(_fd); + return nil; + } + } + + return self; +} + + +- (int)send:(const void *)data amount:(unsigned int)amount +{ + return send(_fd, data, amount, 0); +} + +- (int)receive:(void *)data amount:(unsigned int)amount +{ + return recv(_fd, data, amount, 0); +} + +- (void)close +{ + close(_fd); +} + +- (void)dealloc +{ + [self close]; + + [super dealloc]; +} + +@end diff --git a/Plugins/MAD/Info.plist b/Plugins/MAD/Info.plist index 520f61603..9666d4342 100644 --- a/Plugins/MAD/Info.plist +++ b/Plugins/MAD/Info.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - MADCodec + MADPlugin diff --git a/Plugins/MAD/MAD.xcodeproj/project.pbxproj b/Plugins/MAD/MAD.xcodeproj/project.pbxproj index 725ac44d4..07f3455c2 100644 --- a/Plugins/MAD/MAD.xcodeproj/project.pbxproj +++ b/Plugins/MAD/MAD.xcodeproj/project.pbxproj @@ -8,12 +8,13 @@ /* Begin PBXBuildFile section */ 170335470B8FC4EE00327265 /* MADDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 170335430B8FC4EE00327265 /* MADDecoder.m */; }; - 170335480B8FC4EE00327265 /* MADCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 170335450B8FC4EE00327265 /* MADCodec.m */; }; 177FCEF40B90C8910011C3B5 /* MAD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 177FCEF30B90C8910011C3B5 /* MAD.framework */; }; 177FCEF80B90C8990011C3B5 /* ID3Tag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 177FCEF70B90C8990011C3B5 /* ID3Tag.framework */; }; 177FCF000B90C8A20011C3B5 /* ID3Tag.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCEF70B90C8990011C3B5 /* ID3Tag.framework */; }; 177FCF010B90C8A20011C3B5 /* MAD.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCEF30B90C8910011C3B5 /* MAD.framework */; }; 177FCFBC0B90C98A0011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCFBB0B90C98A0011C3B5 /* Plugin.h */; }; + 17ADB1D20B9793C500257CA2 /* MADPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB1D00B9793C500257CA2 /* MADPlugin.h */; }; + 17ADB1D30B9793C500257CA2 /* MADPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB1D10B9793C500257CA2 /* MADPlugin.m */; }; 17B618AF0B90997E00BC003F /* MADPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B618AD0B90997E00BC003F /* MADPropertiesReader.m */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -28,6 +29,7 @@ 177FCF000B90C8A20011C3B5 /* ID3Tag.framework in CopyFiles */, 177FCF010B90C8A20011C3B5 /* MAD.framework in CopyFiles */, 177FCFBC0B90C98A0011C3B5 /* Plugin.h in CopyFiles */, + 17ADB1D20B9793C500257CA2 /* MADPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -39,11 +41,11 @@ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 170335420B8FC4EE00327265 /* MADDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MADDecoder.h; sourceTree = ""; }; 170335430B8FC4EE00327265 /* MADDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MADDecoder.m; sourceTree = ""; }; - 170335440B8FC4EE00327265 /* MADCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MADCodec.h; sourceTree = ""; }; - 170335450B8FC4EE00327265 /* MADCodec.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MADCodec.m; sourceTree = ""; }; 177FCEF30B90C8910011C3B5 /* MAD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MAD.framework; path = ../../Frameworks/MAD/build/Release/MAD.framework; sourceTree = SOURCE_ROOT; }; 177FCEF70B90C8990011C3B5 /* ID3Tag.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ID3Tag.framework; path = ../../Frameworks/ID3Tag/build/Release/ID3Tag.framework; sourceTree = SOURCE_ROOT; }; 177FCFBB0B90C98A0011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + 17ADB1D00B9793C500257CA2 /* MADPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MADPlugin.h; sourceTree = ""; }; + 17ADB1D10B9793C500257CA2 /* MADPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MADPlugin.m; sourceTree = ""; }; 17B618AC0B90997E00BC003F /* MADPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MADPropertiesReader.h; sourceTree = ""; }; 17B618AD0B90997E00BC003F /* MADPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MADPropertiesReader.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* MAD_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAD_Prefix.pch; sourceTree = ""; }; @@ -99,8 +101,8 @@ isa = PBXGroup; children = ( 177FCFBB0B90C98A0011C3B5 /* Plugin.h */, - 170335440B8FC4EE00327265 /* MADCodec.h */, - 170335450B8FC4EE00327265 /* MADCodec.m */, + 17ADB1D00B9793C500257CA2 /* MADPlugin.h */, + 17ADB1D10B9793C500257CA2 /* MADPlugin.m */, 170335420B8FC4EE00327265 /* MADDecoder.h */, 170335430B8FC4EE00327265 /* MADDecoder.m */, 17B618AC0B90997E00BC003F /* MADPropertiesReader.h */, @@ -198,8 +200,8 @@ buildActionMask = 2147483647; files = ( 170335470B8FC4EE00327265 /* MADDecoder.m in Sources */, - 170335480B8FC4EE00327265 /* MADCodec.m in Sources */, 17B618AF0B90997E00BC003F /* MADPropertiesReader.m in Sources */, + 17ADB1D30B9793C500257CA2 /* MADPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/MAD/MADCodec.m b/Plugins/MAD/MADCodec.m deleted file mode 100644 index 25f38581e..000000000 --- a/Plugins/MAD/MADCodec.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "MADCodec.h" -#import "MADDecoder.h" -#import "MADPropertiesReader.h" - -@implementation MADCodec - -- (int)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [MADDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [MADPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/Flac/FlacCodec.h b/Plugins/MAD/MADPlugin.h similarity index 80% rename from Plugins/Flac/FlacCodec.h rename to Plugins/MAD/MADPlugin.h index 02fbdd330..b0f410f66 100644 --- a/Plugins/Flac/FlacCodec.h +++ b/Plugins/MAD/MADPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface FlacCodec : NSObject +@interface MADPlugin : NSObject { } diff --git a/Plugins/MAD/MADPlugin.m b/Plugins/MAD/MADPlugin.m new file mode 100644 index 000000000..40cd626a0 --- /dev/null +++ b/Plugins/MAD/MADPlugin.m @@ -0,0 +1,24 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "MADPlugin.h" +#import "MADDecoder.h" +#import "MADPropertiesReader.h" + +@implementation MADPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [MADDecoder className], + kCogPropertiesReader, [MADPropertiesReader className], + nil + ]; +} + +@end diff --git a/Plugins/MonkeysAudio/Info.plist b/Plugins/MonkeysAudio/Info.plist index c6ac94e2a..5b1281943 100644 --- a/Plugins/MonkeysAudio/Info.plist +++ b/Plugins/MonkeysAudio/Info.plist @@ -6,14 +6,14 @@ English CFBundleExecutable ${EXECUTABLE_NAME} - CFBundleName - ${PRODUCT_NAME} CFBundleIconFile CFBundleIdentifier com.yourcompany.yourcocoabundle CFBundleInfoDictionaryVersion 6.0 + CFBundleName + ${PRODUCT_NAME} CFBundlePackageType BNDL CFBundleSignature @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - MonkeysAudioCodec + MonkeysAudioPlugin diff --git a/Plugins/MonkeysAudio/MonkeysAudio.xcodeproj/project.pbxproj b/Plugins/MonkeysAudio/MonkeysAudio.xcodeproj/project.pbxproj index 0840a95d9..e526f78c4 100644 --- a/Plugins/MonkeysAudio/MonkeysAudio.xcodeproj/project.pbxproj +++ b/Plugins/MonkeysAudio/MonkeysAudio.xcodeproj/project.pbxproj @@ -7,12 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 1745C2EC0B90BDD100A6768C /* MonkeysAudioCodec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1745C2E60B90BDD100A6768C /* MonkeysAudioCodec.mm */; }; 1745C2ED0B90BDD100A6768C /* MonkeysAudioDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1745C2E80B90BDD100A6768C /* MonkeysAudioDecoder.mm */; }; 1745C2EE0B90BDD100A6768C /* MonkeysAudioPropertiesReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1745C2EA0B90BDD100A6768C /* MonkeysAudioPropertiesReader.mm */; }; 177FCFB50B90C97E0011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCFB40B90C97E0011C3B5 /* Plugin.h */; }; 179CFD770B90C70B00C8C4DB /* MAC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 179CFD760B90C70B00C8C4DB /* MAC.framework */; }; 179CFD7A0B90C70E00C8C4DB /* MAC.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 179CFD760B90C70B00C8C4DB /* MAC.framework */; }; + 17ADB1E80B9793E300257CA2 /* MonkeysAudioPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB1E60B9793E300257CA2 /* MonkeysAudioPlugin.h */; }; + 17ADB1E90B9793E300257CA2 /* MonkeysAudioPlugin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB1E70B9793E300257CA2 /* MonkeysAudioPlugin.mm */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -25,6 +26,7 @@ files = ( 179CFD7A0B90C70E00C8C4DB /* MAC.framework in CopyFiles */, 177FCFB50B90C97E0011C3B5 /* Plugin.h in CopyFiles */, + 17ADB1E80B9793E300257CA2 /* MonkeysAudioPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -34,14 +36,14 @@ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 1745C2E60B90BDD100A6768C /* MonkeysAudioCodec.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MonkeysAudioCodec.mm; sourceTree = ""; }; 1745C2E70B90BDD100A6768C /* MonkeysAudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MonkeysAudioDecoder.h; sourceTree = ""; }; 1745C2E80B90BDD100A6768C /* MonkeysAudioDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MonkeysAudioDecoder.mm; sourceTree = ""; }; 1745C2E90B90BDD100A6768C /* MonkeysAudioPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MonkeysAudioPropertiesReader.h; sourceTree = ""; }; 1745C2EA0B90BDD100A6768C /* MonkeysAudioPropertiesReader.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MonkeysAudioPropertiesReader.mm; sourceTree = ""; }; - 1745C2F80B90BDF200A6768C /* MonkeysAudioCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MonkeysAudioCodec.h; sourceTree = ""; }; 177FCFB40B90C97E0011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 179CFD760B90C70B00C8C4DB /* MAC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MAC.framework; path = ../../Frameworks/MAC/build/Release/MAC.framework; sourceTree = SOURCE_ROOT; }; + 17ADB1E60B9793E300257CA2 /* MonkeysAudioPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MonkeysAudioPlugin.h; sourceTree = ""; }; + 17ADB1E70B9793E300257CA2 /* MonkeysAudioPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MonkeysAudioPlugin.mm; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* MonkeysAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MonkeysAudio_Prefix.pch; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* MonkeysAudio.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MonkeysAudio.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; @@ -93,9 +95,9 @@ 08FB77AFFE84173DC02AAC07 /* Classes */ = { isa = PBXGroup; children = ( + 17ADB1E60B9793E300257CA2 /* MonkeysAudioPlugin.h */, + 17ADB1E70B9793E300257CA2 /* MonkeysAudioPlugin.mm */, 177FCFB40B90C97E0011C3B5 /* Plugin.h */, - 1745C2F80B90BDF200A6768C /* MonkeysAudioCodec.h */, - 1745C2E60B90BDD100A6768C /* MonkeysAudioCodec.mm */, 1745C2E70B90BDD100A6768C /* MonkeysAudioDecoder.h */, 1745C2E80B90BDD100A6768C /* MonkeysAudioDecoder.mm */, 1745C2E90B90BDD100A6768C /* MonkeysAudioPropertiesReader.h */, @@ -191,9 +193,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1745C2EC0B90BDD100A6768C /* MonkeysAudioCodec.mm in Sources */, 1745C2ED0B90BDD100A6768C /* MonkeysAudioDecoder.mm in Sources */, 1745C2EE0B90BDD100A6768C /* MonkeysAudioPropertiesReader.mm in Sources */, + 17ADB1E90B9793E300257CA2 /* MonkeysAudioPlugin.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/MonkeysAudio/MonkeysAudioCodec.mm b/Plugins/MonkeysAudio/MonkeysAudioCodec.mm deleted file mode 100644 index 0ced87f9d..000000000 --- a/Plugins/MonkeysAudio/MonkeysAudioCodec.mm +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "MonkeysAudioCodec.h" -#import "MonkeysAudioDecoder.h" -#import "MonkeysAudioPropertiesReader.h" - -@implementation MonkeysAudioCodec - -- (PluginType)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [MonkeysAudioDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [MonkeysAudioPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/Musepack/MusepackCodec.h b/Plugins/MonkeysAudio/MonkeysAudioPlugin.h similarity index 78% rename from Plugins/Musepack/MusepackCodec.h rename to Plugins/MonkeysAudio/MonkeysAudioPlugin.h index df227b58c..eec5fe216 100644 --- a/Plugins/Musepack/MusepackCodec.h +++ b/Plugins/MonkeysAudio/MonkeysAudioPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface MusepackCodec : NSObject +@interface MonkeysAudioPlugin : NSObject { } diff --git a/Plugins/MonkeysAudio/MonkeysAudioPlugin.mm b/Plugins/MonkeysAudio/MonkeysAudioPlugin.mm new file mode 100644 index 000000000..4455e9d1b --- /dev/null +++ b/Plugins/MonkeysAudio/MonkeysAudioPlugin.mm @@ -0,0 +1,25 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "MonkeysAudioPlugin.h" +#import "MonkeysAudioDecoder.h" +#import "MonkeysAudioPropertiesReader.h" + +@implementation MonkeysAudioPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [MonkeysAudioDecoder className], + kCogPropertiesReader, [MonkeysAudioPropertiesReader className], + nil + ]; +} + + +@end diff --git a/Plugins/Musepack/Info.plist b/Plugins/Musepack/Info.plist index a65b3e8fa..0cb8efad1 100644 --- a/Plugins/Musepack/Info.plist +++ b/Plugins/Musepack/Info.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - MusepackCodec + MusepackPlugin diff --git a/Plugins/Musepack/Musepack.xcodeproj/project.pbxproj b/Plugins/Musepack/Musepack.xcodeproj/project.pbxproj index d65dc72e3..0e5382cf8 100644 --- a/Plugins/Musepack/Musepack.xcodeproj/project.pbxproj +++ b/Plugins/Musepack/Musepack.xcodeproj/project.pbxproj @@ -7,12 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 1703330C0B8FB64500327265 /* MusepackCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 170333080B8FB64500327265 /* MusepackCodec.m */; }; 1703330D0B8FB64500327265 /* MusepackDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1703330A0B8FB64500327265 /* MusepackDecoder.m */; }; 1745C1A40B90B57400A6768C /* MusepackPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1745C1A20B90B57400A6768C /* MusepackPropertiesReader.m */; }; 177FCF280B90C8D00011C3B5 /* MPCDec.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 177FCF270B90C8D00011C3B5 /* MPCDec.framework */; }; 177FCF2B0B90C8D20011C3B5 /* MPCDec.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCF270B90C8D00011C3B5 /* MPCDec.framework */; }; 177FCF390B90C8F10011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCF380B90C8F10011C3B5 /* Plugin.h */; }; + 17ADB2020B9793FF00257CA2 /* MusepackPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB2000B9793FF00257CA2 /* MusepackPlugin.h */; }; + 17ADB2030B9793FF00257CA2 /* MusepackPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB2010B9793FF00257CA2 /* MusepackPlugin.m */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -25,6 +26,7 @@ files = ( 177FCF2B0B90C8D20011C3B5 /* MPCDec.framework in CopyFiles */, 177FCF390B90C8F10011C3B5 /* Plugin.h in CopyFiles */, + 17ADB2020B9793FF00257CA2 /* MusepackPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -34,14 +36,14 @@ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 170333070B8FB64500327265 /* MusepackCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MusepackCodec.h; sourceTree = ""; }; - 170333080B8FB64500327265 /* MusepackCodec.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackCodec.m; sourceTree = ""; }; 170333090B8FB64500327265 /* MusepackDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MusepackDecoder.h; sourceTree = ""; }; 1703330A0B8FB64500327265 /* MusepackDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackDecoder.m; sourceTree = ""; }; 1745C1A10B90B57400A6768C /* MusepackPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MusepackPropertiesReader.h; sourceTree = ""; }; 1745C1A20B90B57400A6768C /* MusepackPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackPropertiesReader.m; sourceTree = ""; }; 177FCF270B90C8D00011C3B5 /* MPCDec.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MPCDec.framework; path = ../../Frameworks/MPCDec/build/Release/MPCDec.framework; sourceTree = SOURCE_ROOT; }; 177FCF380B90C8F10011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + 17ADB2000B9793FF00257CA2 /* MusepackPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MusepackPlugin.h; sourceTree = ""; }; + 17ADB2010B9793FF00257CA2 /* MusepackPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackPlugin.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* Musepack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Musepack_Prefix.pch; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* Musepack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Musepack.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; @@ -94,8 +96,8 @@ isa = PBXGroup; children = ( 177FCF380B90C8F10011C3B5 /* Plugin.h */, - 170333070B8FB64500327265 /* MusepackCodec.h */, - 170333080B8FB64500327265 /* MusepackCodec.m */, + 17ADB2000B9793FF00257CA2 /* MusepackPlugin.h */, + 17ADB2010B9793FF00257CA2 /* MusepackPlugin.m */, 170333090B8FB64500327265 /* MusepackDecoder.h */, 1703330A0B8FB64500327265 /* MusepackDecoder.m */, 1745C1A10B90B57400A6768C /* MusepackPropertiesReader.h */, @@ -191,9 +193,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1703330C0B8FB64500327265 /* MusepackCodec.m in Sources */, 1703330D0B8FB64500327265 /* MusepackDecoder.m in Sources */, 1745C1A40B90B57400A6768C /* MusepackPropertiesReader.m in Sources */, + 17ADB2030B9793FF00257CA2 /* MusepackPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/Musepack/MusepackCodec.m b/Plugins/Musepack/MusepackCodec.m deleted file mode 100644 index 2114b59d2..000000000 --- a/Plugins/Musepack/MusepackCodec.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "MusepackCodec.h" -#import "MusepackDecoder.h" -#import "MusepackPropertiesReader.h" - -@implementation MusepackCodec - -- (int)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [MusepackDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [MusepackPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/Vorbis/VorbisCodec.h b/Plugins/Musepack/MusepackPlugin.h similarity index 79% rename from Plugins/Vorbis/VorbisCodec.h rename to Plugins/Musepack/MusepackPlugin.h index 35dbcbe4e..979fca1fa 100644 --- a/Plugins/Vorbis/VorbisCodec.h +++ b/Plugins/Musepack/MusepackPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface VorbisCodec : NSObject +@interface MusepackPlugin : NSObject { } diff --git a/Plugins/Musepack/MusepackPlugin.m b/Plugins/Musepack/MusepackPlugin.m new file mode 100644 index 000000000..25cab2dd0 --- /dev/null +++ b/Plugins/Musepack/MusepackPlugin.m @@ -0,0 +1,24 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "MusepackPlugin.h" +#import "MusepackDecoder.h" +#import "MusepackPropertiesReader.h" + +@implementation MusepackPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [MusepackDecoder className], + kCogPropertiesReader, [MusepackPropertiesReader className], + nil + ]; +} + +@end diff --git a/Plugins/Shorten/Info.plist b/Plugins/Shorten/Info.plist index 192518cd2..878fffb72 100644 --- a/Plugins/Shorten/Info.plist +++ b/Plugins/Shorten/Info.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - ShortenCodec + ShortenPlugin diff --git a/Plugins/Shorten/Shorten.xcodeproj/project.pbxproj b/Plugins/Shorten/Shorten.xcodeproj/project.pbxproj index 3ec476980..e1959b5da 100644 --- a/Plugins/Shorten/Shorten.xcodeproj/project.pbxproj +++ b/Plugins/Shorten/Shorten.xcodeproj/project.pbxproj @@ -7,12 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 1745C42F0B90C1DC00A6768C /* ShortenCodec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1745C42A0B90C1DC00A6768C /* ShortenCodec.mm */; }; 1745C4300B90C1DC00A6768C /* ShortenDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1745C42C0B90C1DC00A6768C /* ShortenDecoder.mm */; }; 1745C4310B90C1DC00A6768C /* ShortenPropertiesReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1745C42E0B90C1DC00A6768C /* ShortenPropertiesReader.mm */; }; 177FCFAD0B90C96B0011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCFAC0B90C96B0011C3B5 /* Plugin.h */; }; 179CFD600B90C6F600C8C4DB /* Shorten.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 179CFD5F0B90C6F600C8C4DB /* Shorten.framework */; }; 179CFD630B90C6F800C8C4DB /* Shorten.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 179CFD5F0B90C6F600C8C4DB /* Shorten.framework */; }; + 17ADB2240B97942800257CA2 /* ShortenPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB2220B97942800257CA2 /* ShortenPlugin.h */; }; + 17ADB2250B97942800257CA2 /* ShortenPlugin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB2230B97942800257CA2 /* ShortenPlugin.mm */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -25,6 +26,7 @@ files = ( 179CFD630B90C6F800C8C4DB /* Shorten.framework in CopyFiles */, 177FCFAD0B90C96B0011C3B5 /* Plugin.h in CopyFiles */, + 17ADB2240B97942800257CA2 /* ShortenPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -34,14 +36,14 @@ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 1745C4290B90C1DC00A6768C /* ShortenCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShortenCodec.h; sourceTree = ""; }; - 1745C42A0B90C1DC00A6768C /* ShortenCodec.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ShortenCodec.mm; sourceTree = ""; }; 1745C42B0B90C1DC00A6768C /* ShortenDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShortenDecoder.h; sourceTree = ""; }; 1745C42C0B90C1DC00A6768C /* ShortenDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ShortenDecoder.mm; sourceTree = ""; }; 1745C42D0B90C1DC00A6768C /* ShortenPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShortenPropertiesReader.h; sourceTree = ""; }; 1745C42E0B90C1DC00A6768C /* ShortenPropertiesReader.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ShortenPropertiesReader.mm; sourceTree = ""; }; 177FCFAC0B90C96B0011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 179CFD5F0B90C6F600C8C4DB /* Shorten.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Shorten.framework; path = ../../Frameworks/Shorten/build/Release/Shorten.framework; sourceTree = SOURCE_ROOT; }; + 17ADB2220B97942800257CA2 /* ShortenPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShortenPlugin.h; sourceTree = ""; }; + 17ADB2230B97942800257CA2 /* ShortenPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ShortenPlugin.mm; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* Shorten_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shorten_Prefix.pch; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* Shorten.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Shorten.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; @@ -94,8 +96,8 @@ isa = PBXGroup; children = ( 177FCFAC0B90C96B0011C3B5 /* Plugin.h */, - 1745C4290B90C1DC00A6768C /* ShortenCodec.h */, - 1745C42A0B90C1DC00A6768C /* ShortenCodec.mm */, + 17ADB2220B97942800257CA2 /* ShortenPlugin.h */, + 17ADB2230B97942800257CA2 /* ShortenPlugin.mm */, 1745C42B0B90C1DC00A6768C /* ShortenDecoder.h */, 1745C42C0B90C1DC00A6768C /* ShortenDecoder.mm */, 1745C42D0B90C1DC00A6768C /* ShortenPropertiesReader.h */, @@ -191,9 +193,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1745C42F0B90C1DC00A6768C /* ShortenCodec.mm in Sources */, 1745C4300B90C1DC00A6768C /* ShortenDecoder.mm in Sources */, 1745C4310B90C1DC00A6768C /* ShortenPropertiesReader.mm in Sources */, + 17ADB2250B97942800257CA2 /* ShortenPlugin.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/Shorten/ShortenCodec.mm b/Plugins/Shorten/ShortenCodec.mm deleted file mode 100644 index 3011cbb23..000000000 --- a/Plugins/Shorten/ShortenCodec.mm +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "ShortenCodec.h" -#import "ShortenDecoder.h" -#import "ShortenPropertiesReader.h" - -@implementation ShortenCodec - -- (PluginType)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [ShortenDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [ShortenPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/Shorten/ShortenCodec.h b/Plugins/Shorten/ShortenPlugin.h similarity index 79% rename from Plugins/Shorten/ShortenCodec.h rename to Plugins/Shorten/ShortenPlugin.h index a17cc67d0..5364f5f78 100644 --- a/Plugins/Shorten/ShortenCodec.h +++ b/Plugins/Shorten/ShortenPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface ShortenCodec : NSObject +@interface ShortenPlugin : NSObject { } diff --git a/Plugins/Shorten/ShortenPlugin.mm b/Plugins/Shorten/ShortenPlugin.mm new file mode 100644 index 000000000..9f960edc3 --- /dev/null +++ b/Plugins/Shorten/ShortenPlugin.mm @@ -0,0 +1,24 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "ShortenPlugin.h" +#import "ShortenDecoder.h" +#import "ShortenPropertiesReader.h" + +@implementation ShortenPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [ShortenDecoder className], + kCogPropertiesReader, [ShortenPropertiesReader className], + nil + ]; +} + +@end diff --git a/Plugins/TagLib/TagLibPlugin.h b/Plugins/TagLib/TagLibPlugin.h index a8599b6c4..6b2ec5cc6 100644 --- a/Plugins/TagLib/TagLibPlugin.h +++ b/Plugins/TagLib/TagLibPlugin.h @@ -9,7 +9,7 @@ #import #import "Plugin.h" -@interface TagLibPlugin : NSObject +@interface TagLibPlugin : NSObject { } diff --git a/Plugins/TagLib/TagLibPlugin.m b/Plugins/TagLib/TagLibPlugin.m index 245fdbeb6..56901e36d 100644 --- a/Plugins/TagLib/TagLibPlugin.m +++ b/Plugins/TagLib/TagLibPlugin.m @@ -11,27 +11,12 @@ @implementation TagLibPlugin -- (int)pluginType ++ (NSDictionary *)pluginInfo { - return kCogPluginCodec; + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogMetadataReader, [TagLibMetadataReader className], + nil + ]; } -- (Class)decoder -{ - return nil; -} - -- (Class)metadataReader -{ - return [TagLibMetadataReader class]; -} - -- (Class)propertiesReader -{ - return nil; -} - - - - @end diff --git a/Plugins/Vorbis/Info.plist b/Plugins/Vorbis/Info.plist index 0c6db9857..173d7ac06 100644 --- a/Plugins/Vorbis/Info.plist +++ b/Plugins/Vorbis/Info.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 NSPrincipalClass - VorbisCodec + VorbisPlugin diff --git a/Plugins/Vorbis/Vorbis.xcodeproj/project.pbxproj b/Plugins/Vorbis/Vorbis.xcodeproj/project.pbxproj index 605f653a6..abb6985af 100644 --- a/Plugins/Vorbis/Vorbis.xcodeproj/project.pbxproj +++ b/Plugins/Vorbis/Vorbis.xcodeproj/project.pbxproj @@ -11,7 +11,8 @@ 177FCF9E0B90C9530011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCF9D0B90C9530011C3B5 /* Plugin.h */; }; 179CFDEE0B90C79800C8C4DB /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 179CFDED0B90C79800C8C4DB /* Vorbis.framework */; }; 179CFDF20B90C79A00C8C4DB /* Vorbis.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 179CFDED0B90C79800C8C4DB /* Vorbis.framework */; }; - 17C93D350B8FDA66008627D6 /* VorbisCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C93D320B8FDA66008627D6 /* VorbisCodec.m */; }; + 17ADB2480B97944D00257CA2 /* VorbisPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB2460B97944D00257CA2 /* VorbisPlugin.h */; }; + 17ADB2490B97944D00257CA2 /* VorbisPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB2470B97944D00257CA2 /* VorbisPlugin.m */; }; 17C93D360B8FDA66008627D6 /* VorbisDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C93D340B8FDA66008627D6 /* VorbisDecoder.m */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -25,6 +26,7 @@ files = ( 179CFDF20B90C79A00C8C4DB /* Vorbis.framework in CopyFiles */, 177FCF9E0B90C9530011C3B5 /* Plugin.h in CopyFiles */, + 17ADB2480B97944D00257CA2 /* VorbisPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -38,8 +40,8 @@ 1745C2820B90B9F200A6768C /* VorbisPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VorbisPropertiesReader.m; sourceTree = ""; }; 177FCF9D0B90C9530011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 179CFDED0B90C79800C8C4DB /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = ../../Frameworks/Vorbis/build/Release/Vorbis.framework; sourceTree = SOURCE_ROOT; }; - 17C93D310B8FDA66008627D6 /* VorbisCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VorbisCodec.h; sourceTree = ""; }; - 17C93D320B8FDA66008627D6 /* VorbisCodec.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VorbisCodec.m; sourceTree = ""; }; + 17ADB2460B97944D00257CA2 /* VorbisPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VorbisPlugin.h; sourceTree = ""; }; + 17ADB2470B97944D00257CA2 /* VorbisPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VorbisPlugin.m; sourceTree = ""; }; 17C93D330B8FDA66008627D6 /* VorbisDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VorbisDecoder.h; sourceTree = ""; }; 17C93D340B8FDA66008627D6 /* VorbisDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VorbisDecoder.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* Vorbis_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vorbis_Prefix.pch; sourceTree = ""; }; @@ -94,8 +96,8 @@ isa = PBXGroup; children = ( 177FCF9D0B90C9530011C3B5 /* Plugin.h */, - 17C93D310B8FDA66008627D6 /* VorbisCodec.h */, - 17C93D320B8FDA66008627D6 /* VorbisCodec.m */, + 17ADB2460B97944D00257CA2 /* VorbisPlugin.h */, + 17ADB2470B97944D00257CA2 /* VorbisPlugin.m */, 17C93D330B8FDA66008627D6 /* VorbisDecoder.h */, 17C93D340B8FDA66008627D6 /* VorbisDecoder.m */, 1745C2810B90B9F200A6768C /* VorbisPropertiesReader.h */, @@ -191,9 +193,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 17C93D350B8FDA66008627D6 /* VorbisCodec.m in Sources */, 17C93D360B8FDA66008627D6 /* VorbisDecoder.m in Sources */, 1745C2840B90B9F200A6768C /* VorbisPropertiesReader.m in Sources */, + 17ADB2490B97944D00257CA2 /* VorbisPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/Vorbis/VorbisCodec.m b/Plugins/Vorbis/VorbisCodec.m deleted file mode 100644 index 09d6249a7..000000000 --- a/Plugins/Vorbis/VorbisCodec.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "VorbisCodec.h" -#import "VorbisDecoder.h" -#import "VorbisPropertiesReader.h" - -@implementation VorbisCodec - -- (int)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [VorbisDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [VorbisPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/Vorbis/VorbisDecoder.h b/Plugins/Vorbis/VorbisDecoder.h index 8f3c2f10e..3d7c45c8b 100644 --- a/Plugins/Vorbis/VorbisDecoder.h +++ b/Plugins/Vorbis/VorbisDecoder.h @@ -21,10 +21,12 @@ @interface VorbisDecoder : NSObject { - FILE *inFd; + id source; + OggVorbis_File vorbisRef; int currentSection; + BOOL seekable; int bitsPerSample; int bitrate; int channels; @@ -32,4 +34,6 @@ double length; } + + @end diff --git a/Plugins/Vorbis/VorbisDecoder.m b/Plugins/Vorbis/VorbisDecoder.m index a55f52ddd..4226d6533 100644 --- a/Plugins/Vorbis/VorbisDecoder.m +++ b/Plugins/Vorbis/VorbisDecoder.m @@ -11,14 +11,50 @@ @implementation VorbisDecoder -- (BOOL)open:(NSURL *)url +size_t sourceRead(void *buf, size_t size, size_t nmemb, void *datasource) { - inFd = fopen([[url path] UTF8String], "rb"); - if (inFd == 0) - return NO; + id source = (id)datasource; + + return [source read:buf amount:(size*nmemb)]; +} + +int sourceSeek(void *datasource, ogg_int64_t offset, int whence) +{ + id source = (id)datasource; + return ([source seek:offset whence:whence] ? 0 : -1); +} + +int sourceClose(void *datasource) +{ + id source = (id)datasource; + [source close]; + + return 0; +} + +long sourceTell(void *datasource) +{ + id source = (id)datasource; + + return [source tell]; +} + +- (BOOL)open:(id)s +{ + source = [s retain]; - if (ov_open(inFd, &vorbisRef, NULL, 0) != 0) + ov_callbacks callbacks = { + read_func: sourceRead, + seek_func: sourceSeek, + close_func: sourceClose, + tell_func: sourceTell + }; + + if (ov_open_callbacks(source, &vorbisRef, NULL, 0, callbacks) != 0) + { + NSLog(@"FAILED TO OPEN VORBIS FILE"); return NO; + } vorbis_info *vi; @@ -30,9 +66,11 @@ frequency = vi->rate; NSLog(@"INFO: %i", bitsPerSample); - length = ((double)ov_pcm_total(&vorbisRef, -1) * 1000.0)/frequency; + seekable = ov_seekable(&vorbisRef); + + length = 0.0;//((double)ov_pcm_total(&vorbisRef, -1) * 1000.0)/frequency; - NSLog(@"Ok to go WITH OGG."); + NSLog(@"Ok to go WITH OGG. %i", seekable); return YES; } @@ -42,22 +80,34 @@ int numread; int total = 0; - numread = ov_read(&vorbisRef, &((char *)buf)[total], size - total, 0, bitsPerSample/8, 1, ¤tSection); - while (total != size && numread != 0) - { + do { + numread = ov_read(&vorbisRef, &((char *)buf)[total], size - total, 0, bitsPerSample/8, 1, ¤tSection); if (numread > 0) { total += numread; } - numread = ov_read(&vorbisRef, &((char *)buf)[total], size - total, 0, bitsPerSample/8, 1, ¤tSection); - } + } while (total != size && numread != 0); + if (numread == 0) { + char **ptr=ov_comment(&vorbisRef,-1)->user_comments; + vorbis_info *vi=ov_info(&vorbisRef,-1); + while(*ptr){ + NSLog(@"%s\n",*ptr); + ++ptr; + } + NSLog(@"Bitstream is %d channel, %ldHz\n",vi->channels,vi->rate); + NSLog(@"Decoded length: %ld samples\n", + (long)ov_pcm_total(&vorbisRef,-1)); + NSLog(@"Encoded by: %s\n\n", ov_comment(&vorbisRef,-1)->vendor); + NSLog(@"Spewed out crap..."); + } return total; } - (void)close { ov_clear(&vorbisRef); + [source release]; } - (double)seekToTime:(double)milliseconds @@ -67,6 +117,10 @@ return milliseconds; } +- (BOOL) seekable +{ + return [source seekable]; +} - (NSDictionary *)properties { diff --git a/Plugins/Vorbis/VorbisPlugin.h b/Plugins/Vorbis/VorbisPlugin.h new file mode 100644 index 000000000..2b69a9236 --- /dev/null +++ b/Plugins/Vorbis/VorbisPlugin.h @@ -0,0 +1,17 @@ +// +// MusepackCodec.h +// Musepack +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import +#import "Plugin.h" + +@interface VorbisPlugin : NSObject +{ + +} + +@end diff --git a/Plugins/Vorbis/VorbisPlugin.m b/Plugins/Vorbis/VorbisPlugin.m new file mode 100644 index 000000000..2cd25833b --- /dev/null +++ b/Plugins/Vorbis/VorbisPlugin.m @@ -0,0 +1,24 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "VorbisPlugin.h" +#import "VorbisDecoder.h" +#import "VorbisPropertiesReader.h" + +@implementation VorbisPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [VorbisDecoder className], + kCogPropertiesReader, [VorbisPropertiesReader className], + nil + ]; +} + +@end diff --git a/Plugins/Vorbis/VorbisPropertiesReader.m b/Plugins/Vorbis/VorbisPropertiesReader.m index cb2f3012f..ef7e7939a 100644 --- a/Plugins/Vorbis/VorbisPropertiesReader.m +++ b/Plugins/Vorbis/VorbisPropertiesReader.m @@ -11,13 +11,13 @@ @implementation VorbisPropertiesReader -- (NSDictionary *)propertiesForURL:(NSURL *)url ++ (NSDictionary *)propertiesForSource:(id)source { NSDictionary *properties; VorbisDecoder *decoder; decoder = [[VorbisDecoder alloc] init]; - if (![decoder open:url]) + if (![decoder open:source]) { return nil; } @@ -25,6 +25,7 @@ properties = [decoder properties]; [decoder close]; + [decoder release]; return properties; } diff --git a/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj b/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj index dadd49b8a..da6d2f2f0 100644 --- a/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj +++ b/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj @@ -7,12 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 1745C4D90B90C42500A6768C /* WavPackCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1745C4D40B90C42500A6768C /* WavPackCodec.m */; }; 1745C4DA0B90C42500A6768C /* WavPackDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1745C4D60B90C42500A6768C /* WavPackDecoder.m */; }; 1745C4DB0B90C42500A6768C /* WavPackPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1745C4D80B90C42500A6768C /* WavPackPropertiesReader.m */; }; 177FCF950B90C9450011C3B5 /* Plugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 177FCF940B90C9450011C3B5 /* Plugin.h */; }; 179CFD490B90C6DC00C8C4DB /* WavPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 179CFD480B90C6DC00C8C4DB /* WavPack.framework */; }; 179CFD4C0B90C6DF00C8C4DB /* WavPack.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 179CFD480B90C6DC00C8C4DB /* WavPack.framework */; }; + 17ADB2620B97946600257CA2 /* WavPackPlugin.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17ADB2600B97946600257CA2 /* WavPackPlugin.h */; }; + 17ADB2630B97946600257CA2 /* WavPackPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB2610B97946600257CA2 /* WavPackPlugin.m */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -25,6 +26,7 @@ files = ( 179CFD4C0B90C6DF00C8C4DB /* WavPack.framework in CopyFiles */, 177FCF950B90C9450011C3B5 /* Plugin.h in CopyFiles */, + 17ADB2620B97946600257CA2 /* WavPackPlugin.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -34,14 +36,14 @@ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 1745C4D30B90C42500A6768C /* WavPackCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WavPackCodec.h; sourceTree = ""; }; - 1745C4D40B90C42500A6768C /* WavPackCodec.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WavPackCodec.m; sourceTree = ""; }; 1745C4D50B90C42500A6768C /* WavPackDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WavPackDecoder.h; sourceTree = ""; }; 1745C4D60B90C42500A6768C /* WavPackDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WavPackDecoder.m; sourceTree = ""; }; 1745C4D70B90C42500A6768C /* WavPackPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WavPackPropertiesReader.h; sourceTree = ""; }; 1745C4D80B90C42500A6768C /* WavPackPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WavPackPropertiesReader.m; sourceTree = ""; }; 177FCF940B90C9450011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 179CFD480B90C6DC00C8C4DB /* WavPack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WavPack.framework; path = ../../Frameworks/WavPack/build/Release/WavPack.framework; sourceTree = SOURCE_ROOT; }; + 17ADB2600B97946600257CA2 /* WavPackPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WavPackPlugin.h; sourceTree = ""; }; + 17ADB2610B97946600257CA2 /* WavPackPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WavPackPlugin.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* WavPack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WavPack_Prefix.pch; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* WavPack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WavPack.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; @@ -94,8 +96,8 @@ isa = PBXGroup; children = ( 177FCF940B90C9450011C3B5 /* Plugin.h */, - 1745C4D30B90C42500A6768C /* WavPackCodec.h */, - 1745C4D40B90C42500A6768C /* WavPackCodec.m */, + 17ADB2600B97946600257CA2 /* WavPackPlugin.h */, + 17ADB2610B97946600257CA2 /* WavPackPlugin.m */, 1745C4D50B90C42500A6768C /* WavPackDecoder.h */, 1745C4D60B90C42500A6768C /* WavPackDecoder.m */, 1745C4D70B90C42500A6768C /* WavPackPropertiesReader.h */, @@ -191,9 +193,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1745C4D90B90C42500A6768C /* WavPackCodec.m in Sources */, 1745C4DA0B90C42500A6768C /* WavPackDecoder.m in Sources */, 1745C4DB0B90C42500A6768C /* WavPackPropertiesReader.m in Sources */, + 17ADB2630B97946600257CA2 /* WavPackPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugins/WavPack/WavPackCodec.h b/Plugins/WavPack/WavPackCodec.h deleted file mode 100644 index 342318db8..000000000 --- a/Plugins/WavPack/WavPackCodec.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// MusepackCodec.h -// Musepack -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import -#import "Plugin.h" - -@interface WavPackCodec : NSObject -{ - -} - -@end diff --git a/Plugins/WavPack/WavPackCodec.m b/Plugins/WavPack/WavPackCodec.m deleted file mode 100644 index 3f724083f..000000000 --- a/Plugins/WavPack/WavPackCodec.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// MusepackCodec.m -// MusepackCodec -// -// Created by Vincent Spader on 2/21/07. -// Copyright 2007 __MyCompanyName__. All rights reserved. -// - -#import "WavPackCodec.h" -#import "WavPackDecoder.h" -#import "WavPackPropertiesReader.h" - -@implementation WavPackCodec - -- (int)pluginType -{ - return kCogPluginCodec; -} - -- (Class)decoder -{ - return [WavPackDecoder class]; -} - -- (Class)metadataReader -{ - return nil; -} - -- (Class)propertiesReader -{ - return [WavPackPropertiesReader class]; -} - - - - -@end diff --git a/Plugins/WavPack/WavPackPlugin.h b/Plugins/WavPack/WavPackPlugin.h new file mode 100644 index 000000000..c221b0dfc --- /dev/null +++ b/Plugins/WavPack/WavPackPlugin.h @@ -0,0 +1,17 @@ +// +// MusepackCodec.h +// Musepack +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import +#import "Plugin.h" + +@interface WavPackPlugin : NSObject +{ + +} + +@end diff --git a/Plugins/WavPack/WavPackPlugin.m b/Plugins/WavPack/WavPackPlugin.m new file mode 100644 index 000000000..7743dab32 --- /dev/null +++ b/Plugins/WavPack/WavPackPlugin.m @@ -0,0 +1,24 @@ +// +// MusepackCodec.m +// MusepackCodec +// +// Created by Vincent Spader on 2/21/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "WavPackPlugin.h" +#import "WavPackDecoder.h" +#import "WavPackPropertiesReader.h" + +@implementation WavPackPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + kCogDecoder, [WavPackDecoder className], + kCogPropertiesReader, [WavPackPropertiesReader className, + nil + ]; +} + +@end diff --git a/Scripts/build_plugins.sh b/Scripts/build_plugins.sh index d9e5290c3..f039ad6a2 100755 --- a/Scripts/build_plugins.sh +++ b/Scripts/build_plugins.sh @@ -1,6 +1,6 @@ #!/bin/sh -plugins=( CoreAudio MonkeysAudio Musepack Flac Shorten TagLib Vorbis WavPack MAD ) +plugins=( CoreAudio MonkeysAudio Musepack Flac Shorten TagLib Vorbis WavPack MAD FileSource HTTPSource) for plugin in "${plugins[@]}" do diff --git a/TODO b/TODO new file mode 100644 index 000000000..3ed7e7f57 --- /dev/null +++ b/TODO @@ -0,0 +1,2 @@ +Changed SourceNode to BufferedSource. It's not really a node. +Fix all plugins besides ogg vorbis (already fixed), so they use callbacks and the source.