Overhaul of converter, bug fixes, and added position notification
This commit is contained in:
parent
f035fd1cc2
commit
abc4edcda1
16 changed files with 253 additions and 98 deletions
|
@ -20,6 +20,8 @@
|
|||
|
||||
IBOutlet NSButton *playButton;
|
||||
|
||||
NSTimer *positionTimer;
|
||||
|
||||
BOOL waitingForPlay; //No sneaky changing on us
|
||||
SoundController *soundController;
|
||||
|
||||
|
@ -52,9 +54,8 @@
|
|||
|
||||
//Methods since this is SoundController's delegate
|
||||
- (void)delegateNotifyStatusUpdate:(NSNumber *)status;
|
||||
- (void)delegateNotifyPositionUpdate:(double)pos;
|
||||
- (void)delegateNotifyBitrateUpdate:(float)bitrate;
|
||||
- (void)delegateNotifySongChanged:(double)length;
|
||||
- (void)delegateNotifySongChanged;
|
||||
- (void)delegateRequestNextSong:(int)queueSize;
|
||||
|
||||
@end
|
||||
|
|
|
@ -86,6 +86,13 @@
|
|||
// DBLog(@"PlayEntry: %@ Sent!", [pe filename]);
|
||||
if (playbackStatus != kCogStatusStopped)
|
||||
[self stop:self];
|
||||
|
||||
NSLog(@"LENGTH: %lf", [pe length]);
|
||||
[positionSlider setMaxValue:[pe length]];
|
||||
[positionSlider setDoubleValue:0.0f];
|
||||
|
||||
[self updateTimeField:0.0f];
|
||||
|
||||
[soundController play:[pe filename]];
|
||||
}
|
||||
|
||||
|
@ -180,23 +187,26 @@
|
|||
- (void)delegateRequestNextSong:(int)queueSize
|
||||
{
|
||||
PlaylistEntry *pe;
|
||||
|
||||
pe = [playlistController entryAtOffset:(queueSize+1)];
|
||||
|
||||
if (pe == nil)
|
||||
[soundController setNextSong:nil];
|
||||
else
|
||||
{
|
||||
NSLog(@"NEXT SONG: %@", [pe filename]);
|
||||
[soundController setNextSong:[pe filename]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)delegateNotifySongChanged:(double)length
|
||||
- (void)delegateNotifySongChanged
|
||||
{
|
||||
[playlistController next];
|
||||
PlaylistEntry *pe = [playlistController currentEntry];;
|
||||
|
||||
// [positionSlider setMaxValue:length];
|
||||
// [positionSlider setDoubleValue:0];
|
||||
[positionSlider setMaxValue:[pe length]];
|
||||
[positionSlider setDoubleValue:0.0f];
|
||||
|
||||
// [self updateTimeField:0.0f];
|
||||
[self updateTimeField:0.0f];
|
||||
|
||||
}
|
||||
|
||||
|
@ -205,8 +215,10 @@
|
|||
// [bitrateField setIntValue:bitrate];
|
||||
}
|
||||
|
||||
- (void)delegateNotifyPositionUpdate:(double)pos
|
||||
- (void)updatePosition:(id)sender
|
||||
{
|
||||
double pos = [soundController amountPlayed];
|
||||
|
||||
if ([positionSlider tracking] == NO)
|
||||
{
|
||||
// DBLog(@"Received pos update: %f", pos);
|
||||
|
@ -221,11 +233,27 @@
|
|||
int status = [s intValue];
|
||||
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
|
||||
[self changePlayButtonImage:@"play"];
|
||||
}
|
||||
else if (status == kCogStatusPlaying)
|
||||
{
|
||||
if (!positionTimer)
|
||||
positionTimer = [NSTimer scheduledTimerWithTimeInterval:1.00 target:self selector:@selector(updatePosition:) userInfo:nil repeats:YES];
|
||||
|
||||
//Show pause
|
||||
[self changePlayButtonImage:@"pause"];
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ NSString *MovedRowsType = @"MOVED_ROWS_TYPE";
|
|||
|
||||
- (NSIndexSet *)indexSetFromRows:(NSArray *)rows
|
||||
{
|
||||
NSLog(@"HELLO");
|
||||
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
|
||||
NSEnumerator *rowEnumerator = [rows objectEnumerator];
|
||||
NSNumber *idx;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// InputChain.h
|
||||
// BufferChain.h
|
||||
// CogNew
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 1/4/06.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// InputChain.m
|
||||
// BufferChain.m
|
||||
// CogNew
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 1/4/06.
|
||||
|
@ -24,6 +24,9 @@
|
|||
|
||||
- (void)buildChain
|
||||
{
|
||||
[inputNode release];
|
||||
[converterNode release];
|
||||
|
||||
inputNode = [[InputNode alloc] initWithController:soundController previous:nil];
|
||||
converterNode = [[ConverterNode alloc] initWithController:soundController previous:inputNode];
|
||||
|
||||
|
@ -48,6 +51,14 @@
|
|||
[converterNode launchThread];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[inputNode release];
|
||||
[converterNode release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (id)finalNode
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Converter.h
|
||||
// ConverterNode.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Converter.m
|
||||
// ConverterNode.m
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
|
@ -41,9 +41,11 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
void *readPtr;
|
||||
int amountToWrite;
|
||||
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;
|
||||
*ioNumberDataPackets = 0;
|
||||
|
||||
|
@ -51,7 +53,28 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
}
|
||||
|
||||
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];
|
||||
if (availInput == 0 )
|
||||
{
|
||||
|
@ -59,10 +82,10 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
ioData->mBuffers[0].mDataByteSize = 0;
|
||||
*ioNumberDataPackets = 0;
|
||||
|
||||
if ([previousNode endOfInput] == YES)
|
||||
if ([previousNode endOfStream] == YES)
|
||||
{
|
||||
NSLog(@"END OF CONVERTER INPUT");
|
||||
[converter setEndOfInput:YES];
|
||||
[converter setEndOfStream:YES];
|
||||
[converter setShouldContinue:NO];
|
||||
|
||||
return noErr;
|
||||
|
@ -86,9 +109,10 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
[[previousNode buffer] didReadLength:amountToWrite];
|
||||
[[previousNode semaphore] signal];
|
||||
}
|
||||
|
||||
*/
|
||||
// NSLog(@"Amount read: %@ %i", converter, amountRead);
|
||||
ioData->mBuffers[0].mData = converter->callbackBuffer;
|
||||
ioData->mBuffers[0].mDataByteSize = amountToWrite;
|
||||
ioData->mBuffers[0].mDataByteSize = amountRead;
|
||||
ioData->mBuffers[0].mNumberChannels = (converter->inputFormat.mChannelsPerFrame);
|
||||
ioData->mNumberBuffers = 1;
|
||||
|
||||
|
@ -97,12 +121,31 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
|
||||
-(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 amountConverted;
|
||||
|
||||
while ([self shouldContinue] == YES)
|
||||
{
|
||||
|
||||
availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr];
|
||||
|
||||
while (availOutput == 0)
|
||||
|
@ -122,6 +165,7 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
if (amountConverted > 0)
|
||||
[buffer didWriteLength:amountConverted];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
- (int)convert:(void *)dest amount:(int)amount
|
||||
|
@ -137,8 +181,12 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
|
|||
ioData.mNumberBuffers = 1;
|
||||
|
||||
err = AudioConverterFillComplexBuffer(converter, ACInputProc, self, &ioNumberFrames, &ioData, NULL);
|
||||
// if (err != noErr)
|
||||
// DBLog(@"Converter error: %i", err);
|
||||
if (err == kAudioConverterErr_InvalidInputSize) //It returns insz at EOS at times...so run it again to make sure all data is converted
|
||||
{
|
||||
return [self convert:dest amount:amount];
|
||||
}
|
||||
if (err != noErr)
|
||||
NSLog(@"Converter error: %i", err);
|
||||
|
||||
return ioData.mBuffers[0].mDataByteSize;
|
||||
/*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// InputController.h
|
||||
// InputNode.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// InputController.m
|
||||
// InputNode.m
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
[soundFile getFormat:&format];
|
||||
|
||||
endOfInput = NO;
|
||||
shouldContinue = YES;
|
||||
}
|
||||
|
||||
- (void)process
|
||||
|
@ -28,21 +28,20 @@
|
|||
|
||||
DBLog(@"Playing file.\n");
|
||||
|
||||
while ([self shouldContinue] == YES)
|
||||
while ([self shouldContinue] == YES && [self endOfStream] == NO)
|
||||
{
|
||||
amountRead = [soundFile fillBuffer:buf ofSize: chunk_size];
|
||||
if (amountRead <= 0)
|
||||
{
|
||||
endOfInput = YES;
|
||||
endOfStream = YES;
|
||||
NSLog(@"END OF INPUT WAS REACHED");
|
||||
[controller endOfInputReached];
|
||||
shouldContinue = NO;
|
||||
[soundFile close];
|
||||
return; //eof
|
||||
}
|
||||
[self writeData:buf amount:amountRead];
|
||||
}
|
||||
|
||||
|
||||
[soundFile close];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// InputChainLink.h
|
||||
// Node.h
|
||||
// CogNew
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 1/4/06.
|
||||
|
@ -21,7 +21,7 @@
|
|||
id controller;
|
||||
|
||||
BOOL shouldContinue;
|
||||
BOOL endOfInput; //All data is now in buffer
|
||||
BOOL endOfStream; //All data is now in buffer
|
||||
}
|
||||
- (id)initWithPrevious:(id)p;
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
|
||||
- (Semaphore *)semaphore;
|
||||
|
||||
- (BOOL)endOfInput;
|
||||
- (void)setEndOfInput:(BOOL)e;
|
||||
- (BOOL)endOfStream;
|
||||
- (void)setEndOfStream:(BOOL)e;
|
||||
|
||||
@end
|
||||
|
|
70
Sound/Node.m
70
Sound/Node.m
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// InputChainLink.m
|
||||
// Node.m
|
||||
// CogNew
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 1/4/06.
|
||||
|
@ -20,7 +20,8 @@
|
|||
|
||||
controller = c;
|
||||
previousNode = p;
|
||||
endOfInput = NO;
|
||||
endOfStream = NO;
|
||||
shouldContinue = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -31,33 +32,30 @@
|
|||
void *writePtr;
|
||||
int amountToCopy, availOutput;
|
||||
int amountLeft = amount;
|
||||
|
||||
do
|
||||
|
||||
while (shouldContinue == YES && amountLeft > 0)
|
||||
{
|
||||
availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr];
|
||||
while (availOutput < CHUNK_SIZE)
|
||||
|
||||
if (availOutput == 0)
|
||||
{
|
||||
[semaphore wait];
|
||||
}
|
||||
else
|
||||
{
|
||||
amountToCopy = availOutput;
|
||||
if (amountToCopy > amountLeft)
|
||||
amountToCopy = amountLeft;
|
||||
|
||||
if (shouldContinue == NO)
|
||||
memcpy(writePtr, &((char *)ptr)[amount - amountLeft], amountToCopy);
|
||||
if (amountToCopy > 0)
|
||||
{
|
||||
return (amount - amountLeft);
|
||||
[buffer didWriteLength:amountToCopy];
|
||||
}
|
||||
|
||||
availOutput = [buffer lengthAvailableToWriteReturningPointer:&writePtr];
|
||||
amountLeft -= amountToCopy;
|
||||
}
|
||||
amountToCopy = availOutput;
|
||||
if (amountToCopy > amountLeft)
|
||||
amountToCopy = amountLeft;
|
||||
|
||||
memcpy(writePtr, &((char *)ptr)[amount - amountLeft], amountToCopy);
|
||||
if (amountToCopy > 0)
|
||||
{
|
||||
[buffer didWriteLength:amountToCopy];
|
||||
}
|
||||
|
||||
amountLeft -= amountToCopy;
|
||||
} while (amountLeft > 0);
|
||||
}
|
||||
|
||||
return (amount - amountLeft);
|
||||
}
|
||||
|
@ -72,8 +70,12 @@
|
|||
{
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
DBLog(@"In thread entry");
|
||||
[self retain];
|
||||
|
||||
[self process];
|
||||
|
||||
|
||||
[self release];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
|
@ -85,8 +87,17 @@
|
|||
|
||||
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;
|
||||
if (availInput > amount)
|
||||
if (amountToCopy > amount)
|
||||
{
|
||||
amountToCopy = amount;
|
||||
}
|
||||
|
@ -96,14 +107,9 @@
|
|||
if (amountToCopy > 0)
|
||||
{
|
||||
[[previousNode buffer] didReadLength:amountToCopy];
|
||||
|
||||
[[previousNode semaphore] signal];
|
||||
}
|
||||
//Do endOfInput fun now...
|
||||
if ((amountToCopy <= 0) && ([previousNode endOfInput] == YES))
|
||||
{
|
||||
endOfInput = YES;
|
||||
shouldContinue = NO;
|
||||
}
|
||||
|
||||
return amountToCopy;
|
||||
}
|
||||
|
@ -139,14 +145,14 @@
|
|||
return semaphore;
|
||||
}
|
||||
|
||||
- (BOOL)endOfInput
|
||||
- (BOOL)endOfStream
|
||||
{
|
||||
return endOfInput;
|
||||
return endOfStream;
|
||||
}
|
||||
|
||||
- (void)setEndOfInput:(BOOL)e
|
||||
- (void)setEndOfStream:(BOOL)e
|
||||
{
|
||||
endOfInput = e;
|
||||
endOfStream = e;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
if (self)
|
||||
{
|
||||
outputController = c;
|
||||
outputUnit = NULL;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -32,14 +33,24 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
|
|||
|
||||
if ([output->outputController shouldContinue] == NO)
|
||||
{
|
||||
NSLog(@"STOPPING");
|
||||
AudioOutputUnitStop(output->outputUnit);
|
||||
|
||||
// [output stop];
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
amountToRead = inNumberFrames*(output->deviceFormat.mBytesPerPacket);
|
||||
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;
|
||||
|
||||
return err;
|
||||
|
@ -48,6 +59,9 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
|
|||
- (BOOL)setup
|
||||
{
|
||||
NSLog(@"SETUP");
|
||||
if (outputUnit)
|
||||
[self stop];
|
||||
|
||||
ComponentDescription desc;
|
||||
OSStatus err;
|
||||
|
||||
|
@ -154,6 +168,11 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
|
|||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self stop];
|
||||
}
|
||||
|
||||
- (void)pause
|
||||
{
|
||||
AudioOutputUnitStop(outputUnit);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// OutputController.h
|
||||
// OutputNode.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
|
@ -18,13 +18,17 @@
|
|||
@interface OutputNode : Node {
|
||||
AudioStreamBasicDescription format;
|
||||
|
||||
int amountPlayed;
|
||||
OutputCoreAudio *output;
|
||||
}
|
||||
|
||||
- (id)initWithController:(id)c previousLink:p;
|
||||
|
||||
- (double)amountPlayed;
|
||||
|
||||
- (void)setup;
|
||||
- (void)process;
|
||||
- (void)close;
|
||||
|
||||
- (int)readData:(void *)ptr amount:(int)amount;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// OutputController.m
|
||||
// OutputNode.m
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
|
@ -13,6 +13,8 @@
|
|||
|
||||
- (void)setup
|
||||
{
|
||||
amountPlayed = 0;
|
||||
|
||||
output = [[OutputCoreAudio alloc] initWithController:self];
|
||||
|
||||
[output setup];
|
||||
|
@ -35,39 +37,37 @@
|
|||
|
||||
- (int)readData:(void *)ptr amount:(int)amount
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
int n;
|
||||
|
||||
previousNode = [[controller bufferChain] finalNode];
|
||||
|
||||
n = [super readData:ptr amount:amount];
|
||||
if ((n == 0) && (endOfInput == YES))
|
||||
// NSLog(@"N: %i %i", n, endOfStream);
|
||||
if (endOfStream == YES)
|
||||
{
|
||||
endOfInput = NO;
|
||||
shouldContinue = YES;
|
||||
NSLog(@"DONE IN");
|
||||
return 0;
|
||||
NSLog(@"End of stream reached: %i", endOfStream);
|
||||
|
||||
amountPlayed = 0;
|
||||
[controller endOfInputPlayed]; //Updates shouldContinue appropriately?
|
||||
NSLog(@"End of stream reached: %i", endOfStream);
|
||||
// return (n + [self readData:ptr amount:(amount-n)]);
|
||||
}
|
||||
|
||||
void *tempPtr;
|
||||
|
||||
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;
|
||||
amountPlayed += n;
|
||||
|
||||
[pool release];
|
||||
|
||||
return n + [self readData:&ptr[n] amount:(amount-n)];
|
||||
|
||||
|
||||
}
|
||||
[pool release];
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
- (double)amountPlayed
|
||||
{
|
||||
|
||||
return (amountPlayed/format.mBytesPerFrame)/(format.mSampleRate/1000.0);
|
||||
}
|
||||
|
||||
- (AudioStreamBasicDescription) format
|
||||
{
|
||||
return format;
|
||||
|
@ -78,6 +78,16 @@
|
|||
format = *f;
|
||||
}
|
||||
|
||||
- (void)close
|
||||
{
|
||||
[output stop];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[output release];
|
||||
}
|
||||
|
||||
- (void)setVolume:(double) v
|
||||
{
|
||||
[output setVolume:v];
|
||||
|
@ -87,7 +97,7 @@
|
|||
{
|
||||
[super setShouldContinue:s];
|
||||
|
||||
if (s == NO)
|
||||
[output stop];
|
||||
// if (s == NO)
|
||||
// [output stop];
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
- (void)seekToTime:(double)time;
|
||||
- (void)setVolume:(double)v;
|
||||
|
||||
- (double)amountPlayed;
|
||||
|
||||
|
||||
- (void)setNextSong:(NSString *)s;
|
||||
- (void)setPlaybackStatus:(int)s;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Controller.m
|
||||
// SoundController.m
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/7/05.
|
||||
|
@ -19,8 +19,8 @@
|
|||
if (self)
|
||||
{
|
||||
//things
|
||||
output = [[OutputNode alloc] initWithController:self previous:nil];
|
||||
bufferChain = [[BufferChain alloc] initWithController:self];
|
||||
output = NULL;
|
||||
bufferChain = NULL;
|
||||
|
||||
chainQueue = [[NSMutableArray alloc] init];
|
||||
|
||||
|
@ -33,7 +33,28 @@
|
|||
- (void)play:(NSString *)filename
|
||||
{
|
||||
DBLog(@"OPENING FILE: %s\n", filename);
|
||||
|
||||
if (output)
|
||||
{
|
||||
[output release];
|
||||
}
|
||||
output = [[OutputNode alloc] initWithController:self previous:nil];
|
||||
[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];
|
||||
|
||||
[self setShouldContinue:YES];
|
||||
|
@ -91,6 +112,11 @@
|
|||
[output setShouldContinue:s];
|
||||
}
|
||||
|
||||
- (double)amountPlayed
|
||||
{
|
||||
return [output amountPlayed];
|
||||
}
|
||||
|
||||
- (void)endOfInputReached
|
||||
{
|
||||
[delegate delegateRequestNextSong:[chainQueue count]];
|
||||
|
@ -117,7 +143,8 @@
|
|||
if ([chainQueue count] <= 0)
|
||||
{
|
||||
//End of playlist
|
||||
[self setPlaybackStatus:kCogStatusStopped];
|
||||
NSLog(@"STOPPED");
|
||||
[self stop];
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -130,14 +157,12 @@
|
|||
|
||||
[chainQueue removeObjectAtIndex:0];
|
||||
|
||||
NSLog(@"SONG CHANGED");
|
||||
[delegate delegateNotifySongChanged:0.0];
|
||||
|
||||
// NSLog(@"SWAPPED");
|
||||
[delegate delegateNotifySongChanged];
|
||||
[output setEndOfStream:NO];
|
||||
}
|
||||
|
||||
- (void)setPlaybackStatus:(int)s
|
||||
{
|
||||
{
|
||||
[delegate performSelectorOnMainThread:@selector(delegateNotifyStatusUpdate:) withObject:[NSNumber numberWithInt:s] waitUntilDone:NO];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue