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;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double streamTimestamp;
|
||||||
|
double streamTimeRatio;
|
||||||
|
if(![self peekTimestamp:&streamTimestamp timeRatio:&streamTimeRatio]) {
|
||||||
|
processEntered = NO;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
if(!ts || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
if(!ts || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
||||||
inputChannelConfig != lastInputChannelConfig) {
|
inputChannelConfig != lastInputChannelConfig) {
|
||||||
lastInputFormat = inputFormat;
|
lastInputFormat = inputFormat;
|
||||||
|
@ -388,8 +395,41 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext;
|
||||||
if(samplesToProcess > blockSize)
|
if(samplesToProcess > blockSize)
|
||||||
samplesToProcess = blockSize;
|
samplesToProcess = blockSize;
|
||||||
|
|
||||||
AudioChunk *chunk = [self readChunkAsFloat32:samplesToProcess];
|
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) {
|
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;
|
processEntered = NO;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -398,18 +438,9 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext;
|
||||||
|
|
||||||
bool endOfStream = [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES;
|
bool endOfStream = [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES;
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
size_t frameCount = totalFrameCount;
|
||||||
|
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
|
|
||||||
int len = (int)frameCount;
|
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);
|
rubberband_process(ts, (const float * const *)rsPtrs, len, endOfStream);
|
||||||
|
|
||||||
|
@ -461,9 +492,9 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext;
|
||||||
if(inputChannelConfig) {
|
if(inputChannelConfig) {
|
||||||
[outputChunk setChannelConfig:inputChannelConfig];
|
[outputChunk setChannelConfig:inputChannelConfig];
|
||||||
}
|
}
|
||||||
if([chunk isHDCD]) [outputChunk setHDCD];
|
if(isHDCD) [outputChunk setHDCD];
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
[outputChunk setStreamTimestamp:streamTimestamp];
|
||||||
[outputChunk setStreamTimeRatio:[chunk streamTimeRatio] * tempo];
|
[outputChunk setStreamTimeRatio:streamTimeRatio * tempo];
|
||||||
[outputChunk assignSamples:rsOutBuffer frameCount:samplesBuffered];
|
[outputChunk assignSamples:rsOutBuffer frameCount:samplesBuffered];
|
||||||
samplesBuffered = 0;
|
samplesBuffered = 0;
|
||||||
stretchOut += [outputChunk duration];
|
stretchOut += [outputChunk duration];
|
||||||
|
|
Loading…
Reference in a new issue