⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pa_process.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
            }
            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 + -