diff --git a/Audio/Chain/DSP/DSPRubberbandNode.m b/Audio/Chain/DSP/DSPRubberbandNode.m index 7c9c0417e..d035e311c 100644 --- a/Audio/Chain/DSP/DSPRubberbandNode.m +++ b/Audio/Chain/DSP/DSPRubberbandNode.m @@ -373,6 +373,13 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; return nil; } + double streamTimestamp; + double streamTimeRatio; + if(![self peekTimestamp:&streamTimestamp timeRatio:&streamTimeRatio]) { + processEntered = NO; + return nil; + } + if(!ts || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 || inputChannelConfig != lastInputChannelConfig) { lastInputFormat = inputFormat; @@ -388,8 +395,41 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; if(samplesToProcess > blockSize) samplesToProcess = blockSize; - AudioChunk *chunk = [self readChunkAsFloat32:samplesToProcess]; - if(!chunk) { + size_t totalFrameCount = 0; + AudioChunk *chunk; + int channels = (int)(inputFormat.mChannelsPerFrame); + + BOOL isHDCD = NO; + + while(!stopping && totalFrameCount < samplesToProcess) { + AudioStreamBasicDescription newInputFormat; + uint32_t newChannelConfig; + if(![self peekFormat:&newInputFormat channelConfig:&newChannelConfig] || + memcmp(&newInputFormat, &inputFormat, sizeof(newInputFormat)) != 0 || + newChannelConfig != inputChannelConfig) { + break; + } + + chunk = [self readChunkAsFloat32:samplesToProcess - totalFrameCount]; + if(!chunk) { + break; + } + + if([chunk isHDCD]) { + isHDCD = YES; + } + + size_t frameCount = [chunk frameCount]; + NSData *sampleData = [chunk removeSamples:frameCount]; + + for (size_t i = 0; i < channels; ++i) { + cblas_scopy((int)frameCount, ((const float *)[sampleData bytes]) + i, channels, rsPtrs[i] + totalFrameCount, 1); + } + + totalFrameCount += frameCount; + } + + if(!totalFrameCount) { processEntered = NO; return nil; } @@ -398,18 +438,9 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; bool endOfStream = [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES; - size_t frameCount = [chunk frameCount]; - - double streamTimestamp = [chunk streamTimestamp]; + size_t frameCount = totalFrameCount; int len = (int)frameCount; - int channels = (int)(inputFormat.mChannelsPerFrame); - NSData *samples = [chunk removeSamples:frameCount]; - float *ibuf = (float *)[samples bytes]; - - for(size_t i = 0; i < channels; ++i) { - cblas_scopy(len, ibuf + i, channels, rsPtrs[i], 1); - } rubberband_process(ts, (const float * const *)rsPtrs, len, endOfStream); @@ -461,9 +492,9 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; if(inputChannelConfig) { [outputChunk setChannelConfig:inputChannelConfig]; } - if([chunk isHDCD]) [outputChunk setHDCD]; + if(isHDCD) [outputChunk setHDCD]; [outputChunk setStreamTimestamp:streamTimestamp]; - [outputChunk setStreamTimeRatio:[chunk streamTimeRatio] * tempo]; + [outputChunk setStreamTimeRatio:streamTimeRatio * tempo]; [outputChunk assignSamples:rsOutBuffer frameCount:samplesBuffered]; samplesBuffered = 0; stretchOut += [outputChunk duration];