bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
+
+ bp->hostInputIsInterleaved = (hostInputSampleFormat & paNonInterleaved)?0:1;
+ bp->userInputSampleFormatIsEqualToHost = ((userInputSampleFormat & ~paNonInterleaved) == (hostInputSampleFormat & ~paNonInterleaved));
tempInputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;
+ bp->hostOutputIsInterleaved = (hostOutputSampleFormat & paNonInterleaved)?0:1;
+
+ bp->userOutputSampleFormatIsEqualToHost = ((userOutputSampleFormat & ~paNonInterleaved) == (hostOutputSampleFormat & ~paNonInterleaved));
+
tempOutputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;
assert( firstChannel < bp->inputChannelCount );
assert( firstChannel + channelCount <= bp->inputChannelCount );
+ assert( bp->hostInputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
unsigned int channel, void *data )
{
assert( channel < bp->inputChannelCount );
+ assert( !bp->hostInputIsInterleaved );
bp->hostInputChannels[0][channel].data = data;
bp->hostInputChannels[0][channel].stride = 1;
assert( firstChannel < bp->inputChannelCount );
assert( firstChannel + channelCount <= bp->inputChannelCount );
+ assert( bp->hostInputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
unsigned int channel, void *data )
{
assert( channel < bp->inputChannelCount );
+ assert( !bp->hostInputIsInterleaved );
bp->hostInputChannels[1][channel].data = data;
bp->hostInputChannels[1][channel].stride = 1;
assert( firstChannel < bp->outputChannelCount );
assert( firstChannel + channelCount <= bp->outputChannelCount );
+ assert( bp->hostOutputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
unsigned int channel, void *data )
{
assert( channel < bp->outputChannelCount );
+ assert( !bp->hostOutputIsInterleaved );
PaUtil_SetOutputChannel( bp, channel, data, 1 );
}
assert( firstChannel < bp->outputChannelCount );
assert( firstChannel + channelCount <= bp->outputChannelCount );
+ assert( bp->hostOutputIsInterleaved );
for( i=0; i< channelCount; ++i )
{
unsigned int channel, void *data )
{
assert( channel < bp->outputChannelCount );
+ assert( !bp->hostOutputIsInterleaved );
PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
}
unsigned long frameCount;
unsigned long framesToGo = framesToProcess;
unsigned long framesProcessed = 0;
+ int skipOutputConvert = 0;
+ int skipInputConvert = 0;
if( *streamCallbackResult == paContinue )
}
else /* there are input channels */
{
- /*
- could use more elaborate logic here and sometimes process
- buffers in-place.
- */
-
+
destBytePtr = (unsigned char *)bp->tempInputBuffer;
if( bp->userInputIsInterleaved )
{
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
- userInput = bp->tempInputBuffer;
+
+ /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
+ if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved )
+ {
+ userInput = hostInputChannels[0].data;
+ destBytePtr = (unsigned char *)hostInputChannels[0].data;
+ skipInputConvert = 1;
+ }
+ else
+ {
+ userInput = bp->tempInputBuffer;
+ }
}
else /* user input is not interleaved */
{
destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;
/* setup non-interleaved ptrs */
- for( i=0; i<bp->inputChannelCount; ++i )
+ if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved )
{
- bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
- i * bp->bytesPerUserInputSample * frameCount;
+ for( i=0; i<bp->inputChannelCount; ++i )
+ {
+ bp->tempInputBufferPtrs[i] = hostInputChannels[i].data;
+ }
+ skipInputConvert = 1;
+ }
+ else
+ {
+ for( i=0; i<bp->inputChannelCount; ++i )
+ {
+ bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
+ i * bp->bytesPerUserInputSample * frameCount;
+ }
}
userInput = bp->tempInputBufferPtrs;
}
}
else
- {
- for( i=0; i<bp->inputChannelCount; ++i )
+ {
+ if( skipInputConvert )
{
- bp->inputConverter( destBytePtr, destSampleStrideSamples,
- hostInputChannels[i].data,
- hostInputChannels[i].stride,
- frameCount, &bp->ditherGenerator );
-
- destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
-
- /* advance src ptr for next iteration */
- hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
- frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+ for( i=0; i<bp->inputChannelCount; ++i )
+ {
+ /* advance src ptr for next iteration */
+ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+ frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+ }
+ }
+ else
+ {
+ for( i=0; i<bp->inputChannelCount; ++i )
+ {
+ bp->inputConverter( destBytePtr, destSampleStrideSamples,
+ hostInputChannels[i].data,
+ hostInputChannels[i].stride,
+ frameCount, &bp->ditherGenerator );
+
+ destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
+
+ /* advance src ptr for next iteration */
+ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+ frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+ }
}
}
}
{
if( bp->userOutputIsInterleaved )
{
- userOutput = bp->tempOutputBuffer;
+ /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
+ if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved )
+ {
+ userOutput = hostOutputChannels[0].data;
+ skipOutputConvert = 1;
+ }
+ else
+ {
+ userOutput = bp->tempOutputBuffer;
+ }
}
else /* user output is not interleaved */
{
- for( i = 0; i < bp->outputChannelCount; ++i )
+ if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved )
{
- bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
- i * bp->bytesPerUserOutputSample * frameCount;
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data;
+ }
+ skipOutputConvert = 1;
+ }
+ else
+ {
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
+ i * bp->bytesPerUserOutputSample * frameCount;
+ }
}
userOutput = bp->tempOutputBufferPtrs;
if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
{
- /*
- could use more elaborate logic here and sometimes process
- buffers in-place.
- */
-
- srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
-
- if( bp->userOutputIsInterleaved )
- {
- srcSampleStrideSamples = bp->outputChannelCount;
- srcChannelStrideBytes = bp->bytesPerUserOutputSample;
- }
- else /* user output is not interleaved */
- {
- srcSampleStrideSamples = 1;
- srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
- }
-
- for( i=0; i<bp->outputChannelCount; ++i )
- {
- bp->outputConverter( hostOutputChannels[i].data,
- hostOutputChannels[i].stride,
- srcBytePtr, srcSampleStrideSamples,
- frameCount, &bp->ditherGenerator );
-
- srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
-
- /* advance dest ptr for next iteration */
- hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
- frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
- }
+ if( skipOutputConvert )
+ {
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ /* advance dest ptr for next iteration */
+ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+ frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+ }
+ }
+ else
+ {
+
+ srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
+
+ if( bp->userOutputIsInterleaved )
+ {
+ srcSampleStrideSamples = bp->outputChannelCount;
+ srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+ }
+ else /* user output is not interleaved */
+ {
+ srcSampleStrideSamples = 1;
+ srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
+ }
+
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ bp->outputConverter( hostOutputChannels[i].data,
+ hostOutputChannels[i].stride,
+ srcBytePtr, srcSampleStrideSamples,
+ frameCount, &bp->ditherGenerator );
+
+ srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
+
+ /* advance dest ptr for next iteration */
+ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+ frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+ }
+ }
}
framesProcessed += frameCount;