Rubber Band DSP: Process larger blocks at a time
Attempt to completely fill the input buffer of the Rubber Band library between each call to the process function, instead of processing in as small an increment as the source node provides. May reduce processing power required. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
7994929a80
commit
2364a7d469
1 changed files with 45 additions and 14 deletions
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue