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;
|
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
|
||||||
|
|
|
@ -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"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
52
Sound/Node.m
52
Sound/Node.m
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue