From e1a3e3d2dc83a4151ed1e7e3db80559ddcc64101 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 27 Feb 2025 00:55:18 -0800 Subject: [PATCH] Bug Fix: Rubber Band should now flush last chunk There is a race condition with the next Node in the chain and the End of Stream marker, considering how tiny the buffering is for these DSPs. Set End of Stream instead after inserting the end of stream flush chunk. Signed-off-by: Christopher Snowhill --- Audio/Chain/DSP/DSPRubberbandNode.m | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Audio/Chain/DSP/DSPRubberbandNode.m b/Audio/Chain/DSP/DSPRubberbandNode.m index 5abc14d37..397174807 100644 --- a/Audio/Chain/DSP/DSPRubberbandNode.m +++ b/Audio/Chain/DSP/DSPRubberbandNode.m @@ -37,6 +37,8 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; BOOL stopping, paused; BOOL processEntered; + BOOL flushed; + BOOL observersapplied; AudioStreamBasicDescription lastInputFormat; @@ -261,6 +263,7 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; tsapplynewoptions = NO; tsrestartengine = NO; + flushed = NO; stretchIn = 0.0; stretchOut = 0.0; @@ -357,7 +360,8 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; AudioChunk *chunk = nil; chunk = [self convert]; if(!chunk || ![chunk frameCount]) { - if([self endOfStream] == YES) { + if(flushed) { + endOfStream = YES; break; } if(paused) { @@ -385,7 +389,7 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; processEntered = YES; - if(stopping || [self endOfStream] == YES || [self shouldContinue] == NO) { + if(stopping || flushed || [self endOfStream] == YES || [self shouldContinue] == NO) { processEntered = NO; return nil; } @@ -448,11 +452,11 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; cblas_scopy((int)frameCount, ((const float *)[sampleData bytes]) + i, channels, rsPtrs[i], 1); } - endOfStream = [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES; + flushed = [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES; int len = (int)frameCount; - rubberband_process(ts, (const float * const *)rsPtrs, len, endOfStream); + rubberband_process(ts, (const float * const *)rsPtrs, len, flushed); } ssize_t samplesAvailable; @@ -481,7 +485,7 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; samplesBuffered += samplesOut; } - if(endOfStream) { + if(flushed) { if(samplesBuffered > 0) { ssize_t delta = (stretchIn - stretchOut) * inputFormat.mSampleRate; if(delta > 0 && samplesBuffered > delta) {