Overhaul of converter, bug fixes, and added position notification

This commit is contained in:
vspader 2006-04-02 15:44:08 +00:00
parent f035fd1cc2
commit abc4edcda1
16 changed files with 253 additions and 98 deletions

View file

@ -20,6 +20,8 @@
IBOutlet NSButton *playButton; IBOutlet NSButton *playButton;
NSTimer *positionTimer;
BOOL waitingForPlay; //No sneaky changing on us BOOL waitingForPlay; //No sneaky changing on us
SoundController *soundController; SoundController *soundController;
@ -52,9 +54,8 @@
//Methods since this is SoundController's delegate //Methods since this is SoundController's delegate
- (void)delegateNotifyStatusUpdate:(NSNumber *)status; - (void)delegateNotifyStatusUpdate:(NSNumber *)status;
- (void)delegateNotifyPositionUpdate:(double)pos;
- (void)delegateNotifyBitrateUpdate:(float)bitrate; - (void)delegateNotifyBitrateUpdate:(float)bitrate;
- (void)delegateNotifySongChanged:(double)length; - (void)delegateNotifySongChanged;
- (void)delegateRequestNextSong:(int)queueSize; - (void)delegateRequestNextSong:(int)queueSize;
@end @end

View file

@ -86,6 +86,13 @@
// DBLog(@"PlayEntry: %@ Sent!", [pe filename]); // DBLog(@"PlayEntry: %@ Sent!", [pe filename]);
if (playbackStatus != kCogStatusStopped) if (playbackStatus != kCogStatusStopped)
[self stop:self]; [self stop:self];
NSLog(@"LENGTH: %lf", [pe length]);
[positionSlider setMaxValue:[pe length]];
[positionSlider setDoubleValue:0.0f];
[self updateTimeField:0.0f];
[soundController play:[pe filename]]; [soundController play:[pe filename]];
} }
@ -180,23 +187,26 @@
- (void)delegateRequestNextSong:(int)queueSize - (void)delegateRequestNextSong:(int)queueSize
{ {
PlaylistEntry *pe; PlaylistEntry *pe;
pe = [playlistController entryAtOffset:(queueSize+1)]; pe = [playlistController entryAtOffset:(queueSize+1)];
if (pe == nil) if (pe == nil)
[soundController setNextSong:nil]; [soundController setNextSong:nil];
else else
{
NSLog(@"NEXT SONG: %@", [pe filename]);
[soundController setNextSong:[pe filename]]; [soundController setNextSong:[pe filename]];
} }
}
- (void)delegateNotifySongChanged:(double)length - (void)delegateNotifySongChanged
{ {
[playlistController next]; [playlistController next];
PlaylistEntry *pe = [playlistController currentEntry];;
// [positionSlider setMaxValue:length]; [positionSlider setMaxValue:[pe length]];
// [positionSlider setDoubleValue:0]; [positionSlider setDoubleValue:0.0f];
// [self updateTimeField:0.0f]; [self updateTimeField:0.0f];
} }
@ -205,8 +215,10 @@
// [bitrateField setIntValue:bitrate]; // [bitrateField setIntValue:bitrate];
} }
- (void)delegateNotifyPositionUpdate:(double)pos - (void)updatePosition:(id)sender
{ {
double pos = [soundController amountPlayed];
if ([positionSlider tracking] == NO) if ([positionSlider tracking] == NO)
{ {
// DBLog(@"Received pos update: %f", pos); // DBLog(@"Received pos update: %f", pos);
@ -221,11 +233,27 @@
int status = [s intValue]; int status = [s intValue];
if (status == kCogStatusStopped || status == kCogStatusPaused) if (status == kCogStatusStopped || status == kCogStatusPaused)
{ {
NSLog(@"INVALIDATING");
if (positionTimer)
{
[positionTimer invalidate];
positionTimer = NULL;
}
if (status == kCogStatusStopped)
{
[positionSlider setDoubleValue:0.0f];
[self updateTimeField:0.0f];
}
//Show play image //Show play image
[self changePlayButtonImage:@"play"]; [self changePlayButtonImage:@"play"];
} }
else if (status == kCogStatusPlaying) else if (status == kCogStatusPlaying)
{ {
if (!positionTimer)
positionTimer = [NSTimer scheduledTimerWithTimeInterval:1.00 target:self selector:@selector(updatePosition:) userInfo:nil repeats:YES];
//Show pause //Show pause
[self changePlayButtonImage:@"pause"]; [self changePlayButtonImage:@"pause"];
} }

View file

@ -121,6 +121,7 @@ NSString *MovedRowsType = @"MOVED_ROWS_TYPE";
- (NSIndexSet *)indexSetFromRows:(NSArray *)rows - (NSIndexSet *)indexSetFromRows:(NSArray *)rows
{ {
NSLog(@"HELLO");
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet]; NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
NSEnumerator *rowEnumerator = [rows objectEnumerator]; NSEnumerator *rowEnumerator = [rows objectEnumerator];
NSNumber *idx; NSNumber *idx;

View file

@ -1,5 +1,5 @@
// //
// InputChain.h // BufferChain.h
// CogNew // CogNew
// //
// Created by Zaphod Beeblebrox on 1/4/06. // Created by Zaphod Beeblebrox on 1/4/06.

View file

@ -1,5 +1,5 @@
// //
// InputChain.m // BufferChain.m
// CogNew // CogNew
// //
// Created by Zaphod Beeblebrox on 1/4/06. // Created by Zaphod Beeblebrox on 1/4/06.
@ -24,6 +24,9 @@
- (void)buildChain - (void)buildChain
{ {
[inputNode release];
[converterNode release];
inputNode = [[InputNode alloc] initWithController:soundController previous:nil]; inputNode = [[InputNode alloc] initWithController:soundController previous:nil];
converterNode = [[ConverterNode alloc] initWithController:soundController previous:inputNode]; converterNode = [[ConverterNode alloc] initWithController:soundController previous:inputNode];
@ -48,6 +51,14 @@
[converterNode launchThread]; [converterNode launchThread];
} }
- (void)dealloc
{
[inputNode release];
[converterNode release];
[super dealloc];
}
- (id)finalNode - (id)finalNode
{ {

View file

@ -1,5 +1,5 @@
// //
// Converter.h // ConverterNode.h
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/2/05. // Created by Zaphod Beeblebrox on 8/2/05.

View file

@ -1,5 +1,5 @@
// //
// Converter.m // ConverterNode.m
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/2/05. // Created by Zaphod Beeblebrox on 8/2/05.
@ -41,9 +41,11 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
void *readPtr; void *readPtr;
int amountToWrite; int amountToWrite;
int availInput; int availInput;
int amountRead;
if ([converter shouldContinue] == NO) if ([converter shouldContinue] == NO || [converter endOfStream] == YES)
{ {
// NSLog(@"END OF STREAM IN CONV");
ioData->mBuffers[0].mDataByteSize = 0; ioData->mBuffers[0].mDataByteSize = 0;
*ioNumberDataPackets = 0; *ioNumberDataPackets = 0;
@ -52,6 +54,27 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
amountToWrite = (*ioNumberDataPackets)*(converter->inputFormat.mBytesPerPacket); amountToWrite = (*ioNumberDataPackets)*(converter->inputFormat.mBytesPerPacket);
if (converter->callbackBuffer != NULL)
free(converter->callbackBuffer);
converter->callbackBuffer = malloc(amountToWrite);
amountRead = [converter readData:converter->callbackBuffer amount:amountToWrite];
/* if ([converter endOfStream] == YES)
{
ioData->mBuffers[0].mDataByteSize = 0;
*ioNumberDataPackets = 0;
return noErr;
}
*/ if (amountRead == 0)
{
ioData->mBuffers[0].mDataByteSize = 0;
*ioNumberDataPackets = 0;
return 100; //Keep asking for data
}
/*
availInput = [[previousNode buffer] lengthAvailableToReadReturningPointer:&readPtr]; availInput = [[previousNode buffer] lengthAvailableToReadReturningPointer:&readPtr];
if (availInput == 0 ) if (availInput == 0 )
{ {
@ -59,10 +82,10 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
ioData->mBuffers[0].mDataByteSize = 0; ioData->mBuffers[0].mDataByteSize = 0;
*ioNumberDataPackets = 0; *ioNumberDataPackets = 0;
if ([previousNode endOfInput] == YES) if ([previousNode endOfStream] == YES)
{ {
NSLog(@"END OF CONVERTER INPUT"); NSLog(@"END OF CONVERTER INPUT");
[converter setEndOfInput:YES]; [converter setEndOfStream:YES];
[converter setShouldContinue:NO]; [converter setShouldContinue:NO];
return noErr; return noErr;
@ -86,9 +109,10 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
[[previousNode buffer] didReadLength:amountToWrite]; [[previousNode buffer] didReadLength:amountToWrite];
[[previousNode semaphore] signal]; [[previousNode semaphore] signal];
} }
*/
// NSLog(@"Amount read: %@ %i", converter, amountRead);
ioData->mBuffers[0].mData = converter->callbackBuffer; ioData->mBuffers[0].mData = converter->callbackBuffer;
ioData->mBuffers[0].mDataByteSize = amountToWrite; ioData->mBuffers[0].mDataByteSize = amountRead;
ioData->mBuffers[0].mNumberChannels = (converter->inputFormat.mChannelsPerFrame); ioData->mBuffers[0].mNumberChannels = (converter->inputFormat.mChannelsPerFrame);
ioData->mNumberBuffers = 1; ioData->mNumberBuffers = 1;
@ -97,12 +121,31 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
-(void)process -(void)process
{ {
void *writePtr; char writeBuf[CHUNK_SIZE];
int amountConverted;
while ([self shouldContinue] == YES) //Need to watch EOS somehow....
{
amountConverted = [self convert:writeBuf amount:CHUNK_SIZE];
// NSLog(@"Amount converted %@: %i %i", self, amountConverted, [self endOfStream]);
if (amountConverted == 0 && [self endOfStream] == YES)
{
// NSLog(@"END OF STREAM FOR ZINE DINNER!!!!");
return;
}
[self writeData:writeBuf amount:amountConverted];
}
/* void *writePtr;
int availOutput; int availOutput;
int amountConverted; int amountConverted;
while ([self shouldContinue] == YES) while ([self shouldContinue] == YES)
{ {
availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr]; availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr];
while (availOutput == 0) while (availOutput == 0)
@ -122,6 +165,7 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
if (amountConverted > 0) if (amountConverted > 0)
[buffer didWriteLength:amountConverted]; [buffer didWriteLength:amountConverted];
} }
*/
} }
- (int)convert:(void *)dest amount:(int)amount - (int)convert:(void *)dest amount:(int)amount
@ -137,8 +181,12 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
ioData.mNumberBuffers = 1; ioData.mNumberBuffers = 1;
err = AudioConverterFillComplexBuffer(converter, ACInputProc, self, &ioNumberFrames, &ioData, NULL); err = AudioConverterFillComplexBuffer(converter, ACInputProc, self, &ioNumberFrames, &ioData, NULL);
// if (err != noErr) if (err == kAudioConverterErr_InvalidInputSize) //It returns insz at EOS at times...so run it again to make sure all data is converted
// DBLog(@"Converter error: %i", err); {
return [self convert:dest amount:amount];
}
if (err != noErr)
NSLog(@"Converter error: %i", err);
return ioData.mBuffers[0].mDataByteSize; return ioData.mBuffers[0].mDataByteSize;
/* /*

View file

@ -1,5 +1,5 @@
// //
// InputController.h // InputNode.h
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/2/05. // Created by Zaphod Beeblebrox on 8/2/05.

View file

@ -1,5 +1,5 @@
// //
// InputController.m // InputNode.m
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/2/05. // Created by Zaphod Beeblebrox on 8/2/05.
@ -17,7 +17,7 @@
[soundFile getFormat:&format]; [soundFile getFormat:&format];
endOfInput = NO; shouldContinue = YES;
} }
- (void)process - (void)process
@ -28,15 +28,14 @@
DBLog(@"Playing file.\n"); DBLog(@"Playing file.\n");
while ([self shouldContinue] == YES) while ([self shouldContinue] == YES && [self endOfStream] == NO)
{ {
amountRead = [soundFile fillBuffer:buf ofSize: chunk_size]; amountRead = [soundFile fillBuffer:buf ofSize: chunk_size];
if (amountRead <= 0) if (amountRead <= 0)
{ {
endOfInput = YES; endOfStream = YES;
NSLog(@"END OF INPUT WAS REACHED"); NSLog(@"END OF INPUT WAS REACHED");
[controller endOfInputReached]; [controller endOfInputReached];
shouldContinue = NO;
[soundFile close]; [soundFile close];
return; //eof return; //eof
} }

View file

@ -1,5 +1,5 @@
// //
// InputChainLink.h // Node.h
// CogNew // CogNew
// //
// Created by Zaphod Beeblebrox on 1/4/06. // Created by Zaphod Beeblebrox on 1/4/06.
@ -21,7 +21,7 @@
id controller; id controller;
BOOL shouldContinue; BOOL shouldContinue;
BOOL endOfInput; //All data is now in buffer BOOL endOfStream; //All data is now in buffer
} }
- (id)initWithPrevious:(id)p; - (id)initWithPrevious:(id)p;
@ -42,7 +42,7 @@
- (Semaphore *)semaphore; - (Semaphore *)semaphore;
- (BOOL)endOfInput; - (BOOL)endOfStream;
- (void)setEndOfInput:(BOOL)e; - (void)setEndOfStream:(BOOL)e;
@end @end

View file

@ -1,5 +1,5 @@
// //
// InputChainLink.m // Node.m
// CogNew // CogNew
// //
// Created by Zaphod Beeblebrox on 1/4/06. // Created by Zaphod Beeblebrox on 1/4/06.
@ -20,7 +20,8 @@
controller = c; controller = c;
previousNode = p; previousNode = p;
endOfInput = NO; endOfStream = NO;
shouldContinue = YES;
} }
return self; return self;
@ -32,20 +33,16 @@
int amountToCopy, availOutput; int amountToCopy, availOutput;
int amountLeft = amount; int amountLeft = amount;
do while (shouldContinue == YES && amountLeft > 0)
{ {
availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr]; availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr];
while (availOutput < CHUNK_SIZE)
if (availOutput == 0)
{ {
[semaphore wait]; [semaphore wait];
}
if (shouldContinue == NO) else
{ {
return (amount - amountLeft);
}
availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr];
}
amountToCopy = availOutput; amountToCopy = availOutput;
if (amountToCopy > amountLeft) if (amountToCopy > amountLeft)
amountToCopy = amountLeft; amountToCopy = amountLeft;
@ -57,7 +54,8 @@
} }
amountLeft -= amountToCopy; amountLeft -= amountToCopy;
} while (amountLeft > 0); }
}
return (amount - amountLeft); return (amount - amountLeft);
} }
@ -72,8 +70,12 @@
{ {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
DBLog(@"In thread entry"); DBLog(@"In thread entry");
[self retain];
[self process]; [self process];
[self release];
[pool release]; [pool release];
} }
@ -85,8 +87,17 @@
availInput = [[previousNode buffer] lengthAvailableToReadReturningPointer:&readPtr]; availInput = [[previousNode buffer] lengthAvailableToReadReturningPointer:&readPtr];
if (availInput <= amount && [previousNode endOfStream] == YES)
{
// NSLog(@"RELEASING: %i %i %i", availInput, [previousNode endOfStream], shouldContinue);
// [previousNode release];
//If it is the outputNode, [soundController newInputChain];
//else
endOfStream = YES;
}
amountToCopy = availInput; amountToCopy = availInput;
if (availInput > amount) if (amountToCopy > amount)
{ {
amountToCopy = amount; amountToCopy = amount;
} }
@ -96,14 +107,9 @@
if (amountToCopy > 0) if (amountToCopy > 0)
{ {
[[previousNode buffer] didReadLength:amountToCopy]; [[previousNode buffer] didReadLength:amountToCopy];
[[previousNode semaphore] signal]; [[previousNode semaphore] signal];
} }
//Do endOfInput fun now...
if ((amountToCopy <= 0) && ([previousNode endOfInput] == YES))
{
endOfInput = YES;
shouldContinue = NO;
}
return amountToCopy; return amountToCopy;
} }
@ -139,14 +145,14 @@
return semaphore; return semaphore;
} }
- (BOOL)endOfInput - (BOOL)endOfStream
{ {
return endOfInput; return endOfStream;
} }
- (void)setEndOfInput:(BOOL)e - (void)setEndOfStream:(BOOL)e
{ {
endOfInput = e; endOfStream = e;
} }
@end @end

View file

@ -17,6 +17,7 @@
if (self) if (self)
{ {
outputController = c; outputController = c;
outputUnit = NULL;
} }
return self; return self;
@ -32,14 +33,24 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
if ([output->outputController shouldContinue] == NO) if ([output->outputController shouldContinue] == NO)
{ {
NSLog(@"STOPPING");
AudioOutputUnitStop(output->outputUnit); AudioOutputUnitStop(output->outputUnit);
// [output stop];
return err; return err;
} }
amountToRead = inNumberFrames*(output->deviceFormat.mBytesPerPacket); amountToRead = inNumberFrames*(output->deviceFormat.mBytesPerPacket);
amountRead = [output->outputController readData:(readPointer) amount:amountToRead]; amountRead = [output->outputController readData:(readPointer) amount:amountToRead];
// NSLog(@"Amount read: %i %i", amountRead, [output->outputController endOfStream]);
if ((amountRead < amountToRead) && [output->outputController endOfStream] == NO) //Try one more time! for track changes!
{
int amountRead2; //Use this since return type of readdata isnt known...may want to fix then can do a simple += to readdata
amountRead2 = [output->outputController readData:(readPointer+amountRead) amount:amountToRead-amountRead];
amountRead += amountRead2;
}
// NSLog(@"Amount read: %i", amountRead);
ioData->mBuffers[0].mDataByteSize = amountRead; ioData->mBuffers[0].mDataByteSize = amountRead;
return err; return err;
@ -48,6 +59,9 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
- (BOOL)setup - (BOOL)setup
{ {
NSLog(@"SETUP"); NSLog(@"SETUP");
if (outputUnit)
[self stop];
ComponentDescription desc; ComponentDescription desc;
OSStatus err; OSStatus err;
@ -154,6 +168,11 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
} }
} }
- (void)dealloc
{
[self stop];
}
- (void)pause - (void)pause
{ {
AudioOutputUnitStop(outputUnit); AudioOutputUnitStop(outputUnit);

View file

@ -1,5 +1,5 @@
// //
// OutputController.h // OutputNode.h
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/2/05. // Created by Zaphod Beeblebrox on 8/2/05.
@ -18,13 +18,17 @@
@interface OutputNode : Node { @interface OutputNode : Node {
AudioStreamBasicDescription format; AudioStreamBasicDescription format;
int amountPlayed;
OutputCoreAudio *output; OutputCoreAudio *output;
} }
- (id)initWithController:(id)c previousLink:p; - (id)initWithController:(id)c previousLink:p;
- (double)amountPlayed;
- (void)setup; - (void)setup;
- (void)process; - (void)process;
- (void)close;
- (int)readData:(void *)ptr amount:(int)amount; - (int)readData:(void *)ptr amount:(int)amount;

View file

@ -1,5 +1,5 @@
// //
// OutputController.m // OutputNode.m
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/2/05. // Created by Zaphod Beeblebrox on 8/2/05.
@ -13,6 +13,8 @@
- (void)setup - (void)setup
{ {
amountPlayed = 0;
output = [[OutputCoreAudio alloc] initWithController:self]; output = [[OutputCoreAudio alloc] initWithController:self];
[output setup]; [output setup];
@ -35,37 +37,35 @@
- (int)readData:(void *)ptr amount:(int)amount - (int)readData:(void *)ptr amount:(int)amount
{ {
int n; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int n;
previousNode = [[controller bufferChain] finalNode]; previousNode = [[controller bufferChain] finalNode];
n = [super readData:ptr amount:amount]; n = [super readData:ptr amount:amount];
if ((n == 0) && (endOfInput == YES)) // NSLog(@"N: %i %i", n, endOfStream);
if (endOfStream == YES)
{ {
endOfInput = NO; NSLog(@"End of stream reached: %i", endOfStream);
shouldContinue = YES;
NSLog(@"DONE IN"); amountPlayed = 0;
return 0; [controller endOfInputPlayed]; //Updates shouldContinue appropriately?
NSLog(@"End of stream reached: %i", endOfStream);
// return (n + [self readData:ptr amount:(amount-n)]);
} }
void *tempPtr; amountPlayed += n;
if (([[[[controller bufferChain] finalNode] buffer] lengthAvailableToReadReturningPointer:&tempPtr] == 0) && ([[[controller bufferChain] finalNode] endOfInput] == YES))
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"END OF OUTPUT INPUT?!");
[controller endOfInputPlayed];
endOfInput = YES;
[pool release]; [pool release];
return n + [self readData:&ptr[n] amount:(amount-n)]; return n;
} }
return n;
- (double)amountPlayed
{
return (amountPlayed/format.mBytesPerFrame)/(format.mSampleRate/1000.0);
} }
- (AudioStreamBasicDescription) format - (AudioStreamBasicDescription) format
@ -78,6 +78,16 @@
format = *f; format = *f;
} }
- (void)close
{
[output stop];
}
- (void)dealloc
{
[output release];
}
- (void)setVolume:(double) v - (void)setVolume:(double) v
{ {
[output setVolume:v]; [output setVolume:v];
@ -87,7 +97,7 @@
{ {
[super setShouldContinue:s]; [super setShouldContinue:s];
if (s == NO) // if (s == NO)
[output stop]; // [output stop];
} }
@end @end

View file

@ -37,6 +37,9 @@
- (void)seekToTime:(double)time; - (void)seekToTime:(double)time;
- (void)setVolume:(double)v; - (void)setVolume:(double)v;
- (double)amountPlayed;
- (void)setNextSong:(NSString *)s; - (void)setNextSong:(NSString *)s;
- (void)setPlaybackStatus:(int)s; - (void)setPlaybackStatus:(int)s;

View file

@ -1,5 +1,5 @@
// //
// Controller.m // SoundController.m
// Cog // Cog
// //
// Created by Zaphod Beeblebrox on 8/7/05. // Created by Zaphod Beeblebrox on 8/7/05.
@ -19,8 +19,8 @@
if (self) if (self)
{ {
//things //things
output = [[OutputNode alloc] initWithController:self previous:nil]; output = NULL;
bufferChain = [[BufferChain alloc] initWithController:self]; bufferChain = NULL;
chainQueue = [[NSMutableArray alloc] init]; chainQueue = [[NSMutableArray alloc] init];
@ -33,7 +33,28 @@
- (void)play:(NSString *)filename - (void)play:(NSString *)filename
{ {
DBLog(@"OPENING FILE: %s\n", filename); DBLog(@"OPENING FILE: %s\n", filename);
if (output)
{
[output release];
}
output = [[OutputNode alloc] initWithController:self previous:nil];
[output setup]; [output setup];
NSEnumerator *enumerator = [chainQueue objectEnumerator];
id anObject;
while (anObject = [enumerator nextObject])
{
[anObject setShouldContinue:NO];
}
[chainQueue removeAllObjects];
if (bufferChain)
{
[bufferChain setShouldContinue:NO];
[bufferChain release];
}
bufferChain = [[BufferChain alloc] initWithController:self];
[bufferChain open:filename]; [bufferChain open:filename];
[self setShouldContinue:YES]; [self setShouldContinue:YES];
@ -91,6 +112,11 @@
[output setShouldContinue:s]; [output setShouldContinue:s];
} }
- (double)amountPlayed
{
return [output amountPlayed];
}
- (void)endOfInputReached - (void)endOfInputReached
{ {
[delegate delegateRequestNextSong:[chainQueue count]]; [delegate delegateRequestNextSong:[chainQueue count]];
@ -117,7 +143,8 @@
if ([chainQueue count] <= 0) if ([chainQueue count] <= 0)
{ {
//End of playlist //End of playlist
[self setPlaybackStatus:kCogStatusStopped]; NSLog(@"STOPPED");
[self stop];
return; return;
} }
@ -130,10 +157,8 @@
[chainQueue removeObjectAtIndex:0]; [chainQueue removeObjectAtIndex:0];
NSLog(@"SONG CHANGED"); [delegate delegateNotifySongChanged];
[delegate delegateNotifySongChanged:0.0]; [output setEndOfStream:NO];
// NSLog(@"SWAPPED");
} }
- (void)setPlaybackStatus:(int)s - (void)setPlaybackStatus:(int)s