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 cddfc3d1db
commit 98bac743df

View file

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