Core Audio output: Some more minor changes

This commit is contained in:
Christopher Snowhill 2022-01-11 22:06:41 -08:00
parent 3b62842021
commit f8e3b0e1ee
4 changed files with 21 additions and 25 deletions

View file

@ -133,9 +133,6 @@
- (void)play:(id<CogDecoder>)decoder startPaused:(BOOL)paused - (void)play:(id<CogDecoder>)decoder startPaused:(BOOL)paused
{ {
if (output) {
[output close];
}
@synchronized(chainQueue) { @synchronized(chainQueue) {
for (id anObject in chainQueue) for (id anObject in chainQueue)
{ {

View file

@ -60,7 +60,7 @@
n = [super readData:ptr amount:amount]; n = [super readData:ptr amount:amount];
amountPlayed += n; amountPlayed += n;
if (endOfStream == YES && !n) if (endOfStream == YES)
{ {
amountPlayed = 0; amountPlayed = 0;
[controller endOfInputPlayed]; //Updates shouldContinue appropriately? [controller endOfInputPlayed]; //Updates shouldContinue appropriately?

View file

@ -33,7 +33,7 @@
AUAudioUnit *_au; AUAudioUnit *_au;
size_t _bufferSize; size_t _bufferSize;
dispatch_semaphore_t sem; dispatch_semaphore_t _sema;
} }
- (id)initWithController:(OutputNode *)c; - (id)initWithController:(OutputNode *)c;

View file

@ -27,6 +27,8 @@ extern void scale_by_volume(float * buffer, size_t count, float volume);
outputDeviceID = -1; outputDeviceID = -1;
listenerapplied = NO; listenerapplied = NO;
_sema = dispatch_semaphore_create(0);
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.outputDevice" options:0 context:NULL]; [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.outputDevice" options:0 context:NULL];
} }
@ -53,7 +55,7 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
- (void)threadEntry:(id)arg - (void)threadEntry:(id)arg
{ {
while (!stopping) { while (!stopping) {
dispatch_semaphore_wait(sem, 500 * USEC_PER_SEC); dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
} }
[self stop]; [self stop];
} }
@ -312,7 +314,9 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
if (err != nil) if (err != nil)
return NO; return NO;
__unsafe_unretained typeof(self) weakSelf = self; __block dispatch_semaphore_t sema = _sema;
__block OutputNode * outputController = self->outputController;
__block float * volume = &self->volume;
_au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData) _au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData)
{ {
@ -320,30 +324,27 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
int amountToRead, amountRead; int amountToRead, amountRead;
int framesToRead = inputData->mBuffers[0].mDataByteSize / (self->deviceFormat.mBytesPerPacket); amountToRead = inputData->mBuffers[0].mDataByteSize;
amountToRead = framesToRead * (self->deviceFormat.mBytesPerPacket); if (self->stopping == YES || [outputController endOfStream] == YES)
if (self->stopping == YES || [self->outputController shouldContinue] == NO)
{ {
memset(readPointer, 0, amountToRead); memset(readPointer, 0, amountToRead);
inputData->mBuffers[0].mDataByteSize = amountToRead;
self->stopping = YES; self->stopping = YES;
dispatch_semaphore_signal(weakSelf->sem); dispatch_semaphore_signal(sema);
return 0; return 0;
} }
amountRead = [self->outputController readData:(readPointer) amount:amountToRead]; amountRead = [outputController readData:(readPointer) amount:amountToRead];
if ((amountRead < amountToRead) && [self->outputController endOfStream] == NO) //Try one more time! for track changes! if ((amountRead < amountToRead) && [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 int amountRead2; //Use this since return type of readdata isnt known...may want to fix then can do a simple += to readdata
amountRead2 = [self->outputController readData:(readPointer+amountRead) amount:amountToRead-amountRead]; amountRead2 = [outputController readData:(readPointer+amountRead) amount:amountToRead-amountRead];
amountRead += amountRead2; amountRead += amountRead2;
} }
int framesRead = amountRead / sizeof(float); int framesRead = amountRead / sizeof(float);
scale_by_volume((float*)readPointer, framesRead, weakSelf->volume); scale_by_volume((float*)readPointer, framesRead, *volume);
if (amountRead < amountToRead) if (amountRead < amountToRead)
{ {
@ -351,17 +352,15 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
// buffer loop if it doesn't get anything, so always produce a full // buffer loop if it doesn't get anything, so always produce a full
// buffer, and silence anything we couldn't supply. // buffer, and silence anything we couldn't supply.
memset(readPointer + amountRead, 0, amountToRead - amountRead); memset(readPointer + amountRead, 0, amountToRead - amountRead);
amountRead = amountToRead;
} }
inputData->mBuffers[0].mDataByteSize = amountRead; dispatch_semaphore_signal(sema);
return 0; return 0;
}; };
[_au allocateRenderResourcesAndReturnError:&err]; [_au allocateRenderResourcesAndReturnError:&err];
sem = dispatch_semaphore_create(0);
[NSThread detachNewThreadSelector:@selector(threadEntry:) toTarget:self withObject:nil]; [NSThread detachNewThreadSelector:@selector(threadEntry:) toTarget:self withObject:nil];
[outputController setFormat:&deviceFormat]; [outputController setFormat:&deviceFormat];
@ -395,7 +394,7 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
[_au stopHardware]; [_au stopHardware];
_au = nil; _au = nil;
stopping = YES; stopping = YES;
dispatch_semaphore_signal(sem); dispatch_semaphore_signal(_sema);
} }
} }