Audio: Adjust node buffering behavior a bit

Change one remaining semaphore wait to 500us, and change the buffering
so that it can always overflow the requested duration by one chunk, so
that at least one chunk will always fit in the buffer. This also allows
the DSP nodes to flush at the end of the stream without losing their
output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-02-11 18:11:26 -08:00
parent 108186450f
commit 8f1ef5eb6b

View file

@ -67,11 +67,10 @@
[chunk setLossless:nodeLossless]; [chunk setLossless:nodeLossless];
[chunk assignSamples:ptr frameCount:amount / nodeFormat.mBytesPerPacket]; [chunk assignSamples:ptr frameCount:amount / nodeFormat.mBytesPerPacket];
const double chunkDuration = [chunk duration];
double durationList = [buffer listDuration]; double durationList = [buffer listDuration];
double durationLeft = [buffer maxDuration] - durationList; double durationLeft = [buffer maxDuration] - durationList;
if(shouldContinue == YES && durationList > durationPrebuffer) { if(shouldContinue == YES && durationList >= durationPrebuffer) {
if(initialBufferFilled == NO) { if(initialBufferFilled == NO) {
initialBufferFilled = YES; initialBufferFilled = YES;
if([controller respondsToSelector:@selector(initialBufferFilled:)]) if([controller respondsToSelector:@selector(initialBufferFilled:)])
@ -79,10 +78,10 @@
} }
} }
while(shouldContinue == YES && chunkDuration > durationLeft) { while(shouldContinue == YES && durationLeft <= 0.0) {
if(durationLeft < chunkDuration || shouldReset) { if(durationLeft <= 0.0 || shouldReset) {
[accessLock unlock]; [accessLock unlock];
[semaphore wait]; [semaphore timedWait:500];
[accessLock lock]; [accessLock lock];
} }
@ -97,11 +96,10 @@
- (void)writeChunk:(AudioChunk *)chunk { - (void)writeChunk:(AudioChunk *)chunk {
[accessLock lock]; [accessLock lock];
const double chunkDuration = [chunk duration];
double durationList = [buffer listDuration]; double durationList = [buffer listDuration];
double durationLeft = [buffer maxDuration] - durationList; double durationLeft = [buffer maxDuration] - durationList;
if(shouldContinue == YES && durationList > durationPrebuffer) { if(shouldContinue == YES && durationList >= durationPrebuffer) {
if(initialBufferFilled == NO) { if(initialBufferFilled == NO) {
initialBufferFilled = YES; initialBufferFilled = YES;
if([controller respondsToSelector:@selector(initialBufferFilled:)]) if([controller respondsToSelector:@selector(initialBufferFilled:)])
@ -109,13 +107,13 @@
} }
} }
while(shouldContinue == YES && chunkDuration > durationLeft) { while(shouldContinue == YES && durationLeft <= 0.0) {
if(previousNode && [previousNode shouldContinue] == NO) { if(previousNode && [previousNode shouldContinue] == NO) {
shouldContinue = NO; shouldContinue = NO;
break; break;
} }
if(durationLeft < chunkDuration || shouldReset) { if(durationLeft <= 0.0 || shouldReset) {
[accessLock unlock]; [accessLock unlock];
[semaphore timedWait:500]; [semaphore timedWait:500];
[accessLock lock]; [accessLock lock];