📄 pa_process.c
字号:
}
else
{
/* paComplete or paAbort has already been called. */
bp->framesInTempInputBuffer = 0;
}
}
/* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels)
Means to process the user output provided by the callback. Has to be called after
each callback. */
CopyTempOutputBuffersToHostOutputBuffers( bp );
}
return framesProcessed;
}
unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult )
{
unsigned long framesToProcess, framesToGo;
unsigned long framesProcessed = 0;
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0
&& bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */
&& bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ )
{
assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) ==
(bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) );
}
assert( *streamCallbackResult == paContinue
|| *streamCallbackResult == paComplete
|| *streamCallbackResult == paAbort ); /* don't forget to pass in a valid callback result value */
if( bp->useNonAdaptingProcess )
{
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
{
/* full duplex non-adapting process, splice buffers if they are
different lengths */
framesToGo = bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]; /* relies on assert above for input/output equivalence */
do{
unsigned long noInputInputFrameCount;
unsigned long *hostInputFrameCount;
PaUtilChannelDescriptor *hostInputChannels;
unsigned long noOutputOutputFrameCount;
unsigned long *hostOutputFrameCount;
PaUtilChannelDescriptor *hostOutputChannels;
unsigned long framesProcessedThisIteration;
if( !bp->hostInputChannels[0][0].data )
{
/* no input was supplied (see PaUtil_SetNoInput)
NonAdaptingProcess knows how to deal with this
*/
noInputInputFrameCount = framesToGo;
hostInputFrameCount = &noInputInputFrameCount;
hostInputChannels = 0;
}
else if( bp->hostInputFrameCount[0] != 0 )
{
hostInputFrameCount = &bp->hostInputFrameCount[0];
hostInputChannels = bp->hostInputChannels[0];
}
else
{
hostInputFrameCount = &bp->hostInputFrameCount[1];
hostInputChannels = bp->hostInputChannels[1];
}
if( !bp->hostOutputChannels[0][0].data )
{
/* no output was supplied (see PaUtil_SetNoOutput)
NonAdaptingProcess knows how to deal with this
*/
noOutputOutputFrameCount = framesToGo;
hostOutputFrameCount = &noOutputOutputFrameCount;
hostOutputChannels = 0;
}
if( bp->hostOutputFrameCount[0] != 0 )
{
hostOutputFrameCount = &bp->hostOutputFrameCount[0];
hostOutputChannels = bp->hostOutputChannels[0];
}
else
{
hostOutputFrameCount = &bp->hostOutputFrameCount[1];
hostOutputChannels = bp->hostOutputChannels[1];
}
framesToProcess = PA_MIN_( *hostInputFrameCount,
*hostOutputFrameCount );
assert( framesToProcess != 0 );
framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult,
hostInputChannels, hostOutputChannels,
framesToProcess );
*hostInputFrameCount -= framesProcessedThisIteration;
*hostOutputFrameCount -= framesProcessedThisIteration;
framesProcessed += framesProcessedThisIteration;
framesToGo -= framesProcessedThisIteration;
}while( framesToGo > 0 );
}
else
{
/* half duplex non-adapting process, just process 1st and 2nd buffer */
/* process first buffer */
framesToProcess = (bp->inputChannelCount != 0)
? bp->hostInputFrameCount[0]
: bp->hostOutputFrameCount[0];
framesProcessed = NonAdaptingProcess( bp, streamCallbackResult,
bp->hostInputChannels[0], bp->hostOutputChannels[0],
framesToProcess );
/* process second buffer if provided */
framesToProcess = (bp->inputChannelCount != 0)
? bp->hostInputFrameCount[1]
: bp->hostOutputFrameCount[1];
if( framesToProcess > 0 )
{
framesProcessed += NonAdaptingProcess( bp, streamCallbackResult,
bp->hostInputChannels[1], bp->hostOutputChannels[1],
framesToProcess );
}
}
}
else /* block adaption necessary*/
{
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
{
/* full duplex */
if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed )
{
framesProcessed = AdaptingProcess( bp, streamCallbackResult,
0 /* dont process partial user buffers */ );
}
else
{
framesProcessed = AdaptingProcess( bp, streamCallbackResult,
1 /* process partial user buffers */ );
}
}
else if( bp->inputChannelCount != 0 )
{
/* input only */
framesToProcess = bp->hostInputFrameCount[0];
framesProcessed = AdaptingInputOnlyProcess( bp, streamCallbackResult,
bp->hostInputChannels[0], framesToProcess );
framesToProcess = bp->hostInputFrameCount[1];
if( framesToProcess > 0 )
{
framesProcessed += AdaptingInputOnlyProcess( bp, streamCallbackResult,
bp->hostInputChannels[1], framesToProcess );
}
}
else
{
/* output only */
framesToProcess = bp->hostOutputFrameCount[0];
framesProcessed = AdaptingOutputOnlyProcess( bp, streamCallbackResult,
bp->hostOutputChannels[0], framesToProcess );
framesToProcess = bp->hostOutputFrameCount[1];
if( framesToProcess > 0 )
{
framesProcessed += AdaptingOutputOnlyProcess( bp, streamCallbackResult,
bp->hostOutputChannels[1], framesToProcess );
}
}
}
return framesProcessed;
}
int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp )
{
return (bp->framesInTempOutputBuffer) ? 0 : 1;
}
unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
void **buffer, unsigned long frameCount )
{
PaUtilChannelDescriptor *hostInputChannels;
unsigned int framesToCopy;
unsigned char *destBytePtr;
void **nonInterleavedDestPtrs;
unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
unsigned int i;
hostInputChannels = bp->hostInputChannels[0];
framesToCopy = PA_MIN_( bp->hostInputFrameCount[0], frameCount );
if( bp->userInputIsInterleaved )
{
destBytePtr = (unsigned char*)*buffer;
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
for( i=0; i<bp->inputChannelCount; ++i )
{
bp->inputConverter( destBytePtr, destSampleStrideSamples,
hostInputChannels[i].data,
hostInputChannels[i].stride,
framesToCopy, &bp->ditherGenerator );
destBytePtr += destChannelStrideBytes; /* skip to next source channel */
/* advance dest ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
/* advance callers dest pointer (buffer) */
*buffer = ((unsigned char *)*buffer) +
framesToCopy * bp->inputChannelCount * bp->bytesPerUserInputSample;
}
else
{
/* user input is not interleaved */
nonInterleavedDestPtrs = (void**)*buffer;
destSampleStrideSamples = 1;
for( i=0; i<bp->inputChannelCount; ++i )
{
destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i];
bp->inputConverter( destBytePtr, destSampleStrideSamples,
hostInputChannels[i].data,
hostInputChannels[i].stride,
framesToCopy, &bp->ditherGenerator );
/* advance callers dest pointer (nonInterleavedDestPtrs[i]) */
destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
nonInterleavedDestPtrs[i] = destBytePtr;
/* advance dest ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
}
bp->hostInputFrameCount[0] -= framesToCopy;
return framesToCopy;
}
unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
const void ** buffer, unsigned long frameCount )
{
PaUtilChannelDescriptor *hostOutputChannels;
unsigned int framesToCopy;
unsigned char *srcBytePtr;
void **nonInterleavedSrcPtrs;
unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
unsigned int i;
hostOutputChannels = bp->hostOutputChannels[0];
framesToCopy = PA_MIN_( bp->hostOutputFrameCount[0], frameCount );
if( bp->userOutputIsInterleaved )
{
srcBytePtr = (unsigned char*)*buffer;
srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample;
for( i=0; i<bp->outputChannelCount; ++i )
{
bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples,
framesToCopy, &bp->ditherGenerator );
srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
/* advance callers source pointer (buffer) */
*buffer = ((unsigned char *)*buffer) +
framesToCopy * bp->outputChannelCount * bp->bytesPerUserOutputSample;
}
else
{
/* user output is not interleaved */
nonInterleavedSrcPtrs = (void**)*buffer;
srcSampleStrideSamples = 1;
for( i=0; i<bp->outputChannelCount; ++i )
{
srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i];
bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples,
framesToCopy, &bp->ditherGenerator );
/* advance callers source pointer (nonInterleavedSrcPtrs[i]) */
srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy;
nonInterleavedSrcPtrs[i] = srcBytePtr;
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
}
bp->hostOutputFrameCount[0] += framesToCopy;
return framesToCopy;
}
unsigned long PaUtil_ZeroOutput( PaUtilBuff
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -