about summary refs log tree commit diff
path: root/src/engine/external/portaudio/pa_process.c
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-03-05 19:38:47 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-03-05 19:38:47 +0000
commit23ffe1ff6577adfce7980f961978ed3e8de59ed6 (patch)
treec0ee4bef0861b560a658305137dd0a0dbfb2b0d5 /src/engine/external/portaudio/pa_process.c
parentc20d99b81d2867193f7f971b230b0d59d1358991 (diff)
downloadzcatch-23ffe1ff6577adfce7980f961978ed3e8de59ed6.tar.gz
zcatch-23ffe1ff6577adfce7980f961978ed3e8de59ed6.zip
updated to svn version of portaudio. fixed a couple of issues with linux and multiple sound devices.
Diffstat (limited to 'src/engine/external/portaudio/pa_process.c')
-rw-r--r--src/engine/external/portaudio/pa_process.c1772
1 files changed, 0 insertions, 1772 deletions
diff --git a/src/engine/external/portaudio/pa_process.c b/src/engine/external/portaudio/pa_process.c
deleted file mode 100644
index bc8848e2..00000000
--- a/src/engine/external/portaudio/pa_process.c
+++ /dev/null
@@ -1,1772 +0,0 @@
-/*

- * $Id: pa_process.c 1097 2006-08-26 08:27:53Z rossb $

- * Portable Audio I/O Library

- * streamCallback <-> host buffer processing adapter

- *

- * Based on the Open Source API proposed by Ross Bencina

- * Copyright (c) 1999-2002 Ross Bencina, Phil Burk

- *

- * Permission is hereby granted, free of charge, to any person obtaining

- * a copy of this software and associated documentation files

- * (the "Software"), to deal in the Software without restriction,

- * including without limitation the rights to use, copy, modify, merge,

- * publish, distribute, sublicense, and/or sell copies of the Software,

- * and to permit persons to whom the Software is furnished to do so,

- * subject to the following conditions:

- *

- * The above copyright notice and this permission notice shall be

- * included in all copies or substantial portions of the Software.

- *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF

- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR

- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF

- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION

- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

- */

-

-/*

- * The text above constitutes the entire PortAudio license; however, 

- * the PortAudio community also makes the following non-binding requests:

- *

- * Any person wishing to distribute modifications to the Software is

- * requested to send the modifications to the original developer so that

- * they can be incorporated into the canonical version. It is also 

- * requested that these non-binding requests be included along with the 

- * license above.

- */

-

-/** @file

- @ingroup common_src

-

- @brief Buffer Processor implementation.

-    

- The code in this file is not optimised yet - although it's not clear that

- it needs to be. there may appear to be redundancies

- that could be factored into common functions, but the redundanceis are left

- intentionally as each appearance may have different optimisation possibilities.

-

- The optimisations which are planned involve only converting data in-place

- where possible, rather than copying to the temp buffer(s).

-

- Note that in the extreme case of being able to convert in-place, and there

- being no conversion necessary there should be some code which short-circuits

- the operation.

-

-    @todo Consider cache tilings for intereave<->deinterleave.

-

-    @todo implement timeInfo->currentTime int PaUtil_BeginBufferProcessing()

-

-    @todo specify and implement some kind of logical policy for handling the

-        underflow and overflow stream flags when the underflow/overflow overlaps

-        multiple user buffers/callbacks.

-

-	@todo provide support for priming the buffers with data from the callback.

-        The client interface is now implemented through PaUtil_SetNoInput()

-        which sets bp->hostInputChannels[0][0].data to zero. However this is

-        currently only implemented in NonAdaptingProcess(). It shouldn't be

-        needed for AdaptingInputOnlyProcess() (no priming should ever be

-        requested for AdaptingInputOnlyProcess()).

-        Not sure if additional work should be required to make it work with

-        AdaptingOutputOnlyProcess, but it definitely is required for

-        AdaptingProcess.

-

-    @todo implement PaUtil_SetNoOutput for AdaptingProcess

-

-    @todo don't allocate temp buffers for blocking streams unless they are

-        needed. At the moment they are needed, but perhaps for host APIs

-        where the implementation passes a buffer to the host they could be

-        used.

-*/

-

-

-#include <assert.h>

-#include <string.h> /* memset() */

-

-#include "pa_process.h"

-#include "pa_util.h"

-

-

-#define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_    1024

-

-#define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) )

-

-

-/* greatest common divisor - PGCD in French */

-static unsigned long GCD( unsigned long a, unsigned long b )

-{

-    return (b==0) ? a : GCD( b, a%b);

-}

-

-/* least common multiple - PPCM in French */

-static unsigned long LCM( unsigned long a, unsigned long b )

-{

-    return (a*b) / GCD(a,b);

-}

-

-#define PA_MAX_( a, b ) (((a) > (b)) ? (a) : (b))

-

-static unsigned long CalculateFrameShift( unsigned long M, unsigned long N )

-{

-    unsigned long result = 0;

-    unsigned long i;

-    unsigned long lcm;

-

-    assert( M > 0 );

-    assert( N > 0 );

-

-    lcm = LCM( M, N );

-    for( i = M; i < lcm; i += M )

-        result = PA_MAX_( result, i % N );

-

-    return result;

-}

-

-

-PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,

-        int inputChannelCount, PaSampleFormat userInputSampleFormat,

-        PaSampleFormat hostInputSampleFormat,

-        int outputChannelCount, PaSampleFormat userOutputSampleFormat,

-        PaSampleFormat hostOutputSampleFormat,

-        double sampleRate,

-        PaStreamFlags streamFlags,

-        unsigned long framesPerUserBuffer,

-        unsigned long framesPerHostBuffer,

-        PaUtilHostBufferSizeMode hostBufferSizeMode,

-        PaStreamCallback *streamCallback, void *userData )

-{

-    PaError result = paNoError;

-    PaError bytesPerSample;

-    unsigned long tempInputBufferSize, tempOutputBufferSize;

-

-    if( streamFlags & paNeverDropInput )

-    {

-        /* paNeverDropInput is only valid for full-duplex callback streams, with an unspecified number of frames per buffer. */

-        if( !streamCallback || !(inputChannelCount > 0 && outputChannelCount > 0) ||

-                framesPerUserBuffer != paFramesPerBufferUnspecified )

-            return paInvalidFlag;

-    }

-

-    /* initialize buffer ptrs to zero so they can be freed if necessary in error */

-    bp->tempInputBuffer = 0;

-    bp->tempInputBufferPtrs = 0;

-    bp->tempOutputBuffer = 0;

-    bp->tempOutputBufferPtrs = 0;

-

-    bp->framesPerUserBuffer = framesPerUserBuffer;

-    bp->framesPerHostBuffer = framesPerHostBuffer;

-

-    bp->inputChannelCount = inputChannelCount;

-    bp->outputChannelCount = outputChannelCount;

-

-    bp->hostBufferSizeMode = hostBufferSizeMode;

-

-    bp->hostInputChannels[0] = bp->hostInputChannels[1] = 0;

-    bp->hostOutputChannels[0] = bp->hostOutputChannels[1] = 0;

-

-    if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */

-    {

-        bp->useNonAdaptingProcess = 1;

-        bp->initialFramesInTempInputBuffer = 0;

-        bp->initialFramesInTempOutputBuffer = 0;

-

-        if( hostBufferSizeMode == paUtilFixedHostBufferSize

-                || hostBufferSizeMode == paUtilBoundedHostBufferSize )

-        {

-            bp->framesPerTempBuffer = framesPerHostBuffer;

-        }

-        else /* unknown host buffer size */

-        {

-             bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_;

-        }

-    }

-    else

-    {

-        bp->framesPerTempBuffer = framesPerUserBuffer;

-

-        if( hostBufferSizeMode == paUtilFixedHostBufferSize

-                && framesPerHostBuffer % framesPerUserBuffer == 0 )

-        {

-            bp->useNonAdaptingProcess = 1;

-            bp->initialFramesInTempInputBuffer = 0;

-            bp->initialFramesInTempOutputBuffer = 0;

-        }

-        else

-        {

-            bp->useNonAdaptingProcess = 0;

-

-            if( inputChannelCount > 0 && outputChannelCount > 0 )

-            {

-                /* full duplex */

-                if( hostBufferSizeMode == paUtilFixedHostBufferSize )

-                {

-                    unsigned long frameShift =

-                        CalculateFrameShift( framesPerHostBuffer, framesPerUserBuffer );

-

-                    if( framesPerUserBuffer > framesPerHostBuffer )

-                    {

-                        bp->initialFramesInTempInputBuffer = frameShift;

-                        bp->initialFramesInTempOutputBuffer = 0;

-                    }

-                    else

-                    {

-                        bp->initialFramesInTempInputBuffer = 0;

-                        bp->initialFramesInTempOutputBuffer = frameShift;

-                    }

-                }

-                else /* variable host buffer size, add framesPerUserBuffer latency */

-                {

-                    bp->initialFramesInTempInputBuffer = 0;

-                    bp->initialFramesInTempOutputBuffer = framesPerUserBuffer;

-                }

-            }

-            else

-            {

-                /* half duplex */

-                bp->initialFramesInTempInputBuffer = 0;

-                bp->initialFramesInTempOutputBuffer = 0;

-            }

-        }

-    }

-

-

-    bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;

-    bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;

-

-    

-    if( inputChannelCount > 0 )

-    {

-        bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat );

-        if( bytesPerSample > 0 )

-        {

-            bp->bytesPerHostInputSample = bytesPerSample;

-        }

-        else

-        {

-            result = bytesPerSample;

-            goto error;

-        }

-

-        bytesPerSample = Pa_GetSampleSize( userInputSampleFormat );

-        if( bytesPerSample > 0 )

-        {

-            bp->bytesPerUserInputSample = bytesPerSample;

-        }

-        else

-        {

-            result = bytesPerSample;

-            goto error;

-        }

-

-        bp->inputConverter =

-            PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, streamFlags );

-

-        bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );

-            

-        bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;

-

-

-        tempInputBufferSize =

-            bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;

-         

-        bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize );

-        if( bp->tempInputBuffer == 0 )

-        {

-            result = paInsufficientMemory;

-            goto error;

-        }

-        

-        if( bp->framesInTempInputBuffer > 0 )

-            memset( bp->tempInputBuffer, 0, tempInputBufferSize );

-

-        if( userInputSampleFormat & paNonInterleaved )

-        {

-            bp->tempInputBufferPtrs =

-                (void **)PaUtil_AllocateMemory( sizeof(void*)*inputChannelCount );

-            if( bp->tempInputBufferPtrs == 0 )

-            {

-                result = paInsufficientMemory;

-                goto error;

-            }

-        }

-

-        bp->hostInputChannels[0] = (PaUtilChannelDescriptor*)

-                PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor) * inputChannelCount * 2);

-        if( bp->hostInputChannels[0] == 0 )

-        {

-            result = paInsufficientMemory;

-            goto error;

-        }

-

-        bp->hostInputChannels[1] = &bp->hostInputChannels[0][inputChannelCount];

-    }

-

-    if( outputChannelCount > 0 )

-    {

-        bytesPerSample = Pa_GetSampleSize( hostOutputSampleFormat );

-        if( bytesPerSample > 0 )

-        {

-            bp->bytesPerHostOutputSample = bytesPerSample;

-        }

-        else

-        {

-            result = bytesPerSample;

-            goto error;

-        }

-

-        bytesPerSample = Pa_GetSampleSize( userOutputSampleFormat );

-        if( bytesPerSample > 0 )

-        {

-            bp->bytesPerUserOutputSample = bytesPerSample;

-        }

-        else

-        {

-            result = bytesPerSample;

-            goto error;

-        }

-

-        bp->outputConverter =

-            PaUtil_SelectConverter( userOutputSampleFormat, hostOutputSampleFormat, streamFlags );

-

-        bp->outputZeroer = PaUtil_SelectZeroer( hostOutputSampleFormat );

-

-        bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;

-

-        tempOutputBufferSize =

-                bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;

-

-        bp->tempOutputBuffer = PaUtil_AllocateMemory( tempOutputBufferSize );

-        if( bp->tempOutputBuffer == 0 )

-        {

-            result = paInsufficientMemory;

-            goto error;

-        }

-

-        if( bp->framesInTempOutputBuffer > 0 )

-            memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );

-        

-        if( userOutputSampleFormat & paNonInterleaved )

-        {

-            bp->tempOutputBufferPtrs =

-                (void **)PaUtil_AllocateMemory( sizeof(void*)*outputChannelCount );

-            if( bp->tempOutputBufferPtrs == 0 )

-            {

-                result = paInsufficientMemory;

-                goto error;

-            }

-        }

-

-        bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*)

-                PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 );

-        if( bp->hostOutputChannels[0] == 0 )

-        {                                                                     

-            result = paInsufficientMemory;

-            goto error;

-        }

-

-        bp->hostOutputChannels[1] = &bp->hostOutputChannels[0][outputChannelCount];

-    }

-

-    PaUtil_InitializeTriangularDitherState( &bp->ditherGenerator );

-

-    bp->samplePeriod = 1. / sampleRate;

-

-    bp->streamCallback = streamCallback;

-    bp->userData = userData;

-

-    return result;

-

-error:

-    if( bp->tempInputBuffer )

-        PaUtil_FreeMemory( bp->tempInputBuffer );

-

-    if( bp->tempInputBufferPtrs )

-        PaUtil_FreeMemory( bp->tempInputBufferPtrs );

-

-    if( bp->hostInputChannels[0] )

-        PaUtil_FreeMemory( bp->hostInputChannels[0] );

-

-    if( bp->tempOutputBuffer )

-        PaUtil_FreeMemory( bp->tempOutputBuffer );

-

-    if( bp->tempOutputBufferPtrs )

-        PaUtil_FreeMemory( bp->tempOutputBufferPtrs );

-

-    if( bp->hostOutputChannels[0] )

-        PaUtil_FreeMemory( bp->hostOutputChannels[0] );

-

-    return result;

-}

-

-

-void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp )

-{

-    if( bp->tempInputBuffer )

-        PaUtil_FreeMemory( bp->tempInputBuffer );

-

-    if( bp->tempInputBufferPtrs )

-        PaUtil_FreeMemory( bp->tempInputBufferPtrs );

-

-    if( bp->hostInputChannels[0] )

-        PaUtil_FreeMemory( bp->hostInputChannels[0] );

-        

-    if( bp->tempOutputBuffer )

-        PaUtil_FreeMemory( bp->tempOutputBuffer );

-

-    if( bp->tempOutputBufferPtrs )

-        PaUtil_FreeMemory( bp->tempOutputBufferPtrs );

-

-    if( bp->hostOutputChannels[0] )

-        PaUtil_FreeMemory( bp->hostOutputChannels[0] );

-}

-

-

-void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp )

-{

-    unsigned long tempInputBufferSize, tempOutputBufferSize;

-

-    bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;

-    bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;

-

-    if( bp->framesInTempInputBuffer > 0 )

-    {

-        tempInputBufferSize =

-            bp->framesPerTempBuffer * bp->bytesPerUserInputSample * bp->inputChannelCount;

-        memset( bp->tempInputBuffer, 0, tempInputBufferSize );

-    }

-

-    if( bp->framesInTempOutputBuffer > 0 )

-    {      

-        tempOutputBufferSize =

-            bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount;

-        memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );

-    }

-}

-

-

-unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bp )

-{

-    return bp->initialFramesInTempInputBuffer;

-}

-

-

-unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bp )

-{

-    return bp->initialFramesInTempOutputBuffer;

-}

-

-

-void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp,

-        unsigned long frameCount )

-{

-    if( frameCount == 0 )

-        bp->hostInputFrameCount[0] = bp->framesPerHostBuffer;

-    else

-        bp->hostInputFrameCount[0] = frameCount;

-}

-        

-

-void PaUtil_SetNoInput( PaUtilBufferProcessor* bp )

-{

-    assert( bp->inputChannelCount > 0 );

-

-    bp->hostInputChannels[0][0].data = 0;

-}

-

-

-void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data, unsigned int stride )

-{

-    assert( channel < bp->inputChannelCount );

-    

-    bp->hostInputChannels[0][channel].data = data;

-    bp->hostInputChannels[0][channel].stride = stride;

-}

-

-

-void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp,

-        unsigned int firstChannel, void *data, unsigned int channelCount )

-{

-    unsigned int i;

-    unsigned int channel = firstChannel;

-    unsigned char *p = (unsigned char*)data;

-

-    if( channelCount == 0 )

-        channelCount = bp->inputChannelCount;

-

-    assert( firstChannel < bp->inputChannelCount );

-    assert( firstChannel + channelCount <= bp->inputChannelCount );

-

-    for( i=0; i< channelCount; ++i )

-    {

-        bp->hostInputChannels[0][channel+i].data = p;

-        p += bp->bytesPerHostInputSample;

-        bp->hostInputChannels[0][channel+i].stride = channelCount;

-    }

-}

-

-

-void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data )

-{

-    assert( channel < bp->inputChannelCount );

-    

-    bp->hostInputChannels[0][channel].data = data;

-    bp->hostInputChannels[0][channel].stride = 1;

-}

-

-

-void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bp,

-        unsigned long frameCount )

-{

-    bp->hostInputFrameCount[1] = frameCount;

-}

-

-

-void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data, unsigned int stride )

-{

-    assert( channel < bp->inputChannelCount );

-

-    bp->hostInputChannels[1][channel].data = data;

-    bp->hostInputChannels[1][channel].stride = stride;

-}

-

-

-void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp,

-        unsigned int firstChannel, void *data, unsigned int channelCount )

-{

-    unsigned int i;

-    unsigned int channel = firstChannel;

-    unsigned char *p = (unsigned char*)data;

-

-    if( channelCount == 0 )

-        channelCount = bp->inputChannelCount;

-

-    assert( firstChannel < bp->inputChannelCount );

-    assert( firstChannel + channelCount <= bp->inputChannelCount );

-    

-    for( i=0; i< channelCount; ++i )

-    {

-        bp->hostInputChannels[1][channel+i].data = p;

-        p += bp->bytesPerHostInputSample;

-        bp->hostInputChannels[1][channel+i].stride = channelCount;

-    }

-}

-

-        

-void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data )

-{

-    assert( channel < bp->inputChannelCount );

-    

-    bp->hostInputChannels[1][channel].data = data;

-    bp->hostInputChannels[1][channel].stride = 1;

-}

-

-

-void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bp,

-        unsigned long frameCount )

-{

-    if( frameCount == 0 )

-        bp->hostOutputFrameCount[0] = bp->framesPerHostBuffer;

-    else

-        bp->hostOutputFrameCount[0] = frameCount;

-}

-

-

-void PaUtil_SetNoOutput( PaUtilBufferProcessor* bp )

-{

-    assert( bp->outputChannelCount > 0 );

-

-    bp->hostOutputChannels[0][0].data = 0;

-}

-

-

-void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data, unsigned int stride )

-{

-    assert( channel < bp->outputChannelCount );

-    assert( data != NULL );

-

-    bp->hostOutputChannels[0][channel].data = data;

-    bp->hostOutputChannels[0][channel].stride = stride;

-}

-

-

-void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp,

-        unsigned int firstChannel, void *data, unsigned int channelCount )

-{

-    unsigned int i;

-    unsigned int channel = firstChannel;

-    unsigned char *p = (unsigned char*)data;

-

-    if( channelCount == 0 )

-        channelCount = bp->outputChannelCount;

-

-    assert( firstChannel < bp->outputChannelCount );

-    assert( firstChannel + channelCount <= bp->outputChannelCount );

-    

-    for( i=0; i< channelCount; ++i )

-    {

-        PaUtil_SetOutputChannel( bp, channel + i, p, channelCount );

-        p += bp->bytesPerHostOutputSample;

-    }

-}

-

-

-void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data )

-{

-    assert( channel < bp->outputChannelCount );

-

-    PaUtil_SetOutputChannel( bp, channel, data, 1 );

-}

-

-

-void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bp,

-        unsigned long frameCount )

-{

-    bp->hostOutputFrameCount[1] = frameCount;

-}

-

-

-void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data, unsigned int stride )

-{

-    assert( channel < bp->outputChannelCount );

-    assert( data != NULL );

-

-    bp->hostOutputChannels[1][channel].data = data;

-    bp->hostOutputChannels[1][channel].stride = stride;

-}

-

-

-void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp,

-        unsigned int firstChannel, void *data, unsigned int channelCount )

-{

-    unsigned int i;

-    unsigned int channel = firstChannel;

-    unsigned char *p = (unsigned char*)data;

-

-    if( channelCount == 0 )

-        channelCount = bp->outputChannelCount;

-

-    assert( firstChannel < bp->outputChannelCount );

-    assert( firstChannel + channelCount <= bp->outputChannelCount );

-    

-    for( i=0; i< channelCount; ++i )

-    {

-        PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount );

-        p += bp->bytesPerHostOutputSample;

-    }

-}

-

-        

-void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,

-        unsigned int channel, void *data )

-{

-    assert( channel < bp->outputChannelCount );

-    

-    PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );

-}

-

-

-void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp,

-        PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags )

-{

-    bp->timeInfo = timeInfo;

-

-    /* the first streamCallback will be called to process samples which are

-        currently in the input buffer before the ones starting at the timeInfo time */

-        

-    bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod;

-    

-    bp->timeInfo->currentTime = 0; /** FIXME: @todo time info currentTime not implemented */

-

-    /* the first streamCallback will be called to generate samples which will be

-        outputted after the frames currently in the output buffer have been

-        outputted. */

-    bp->timeInfo->outputBufferDacTime += bp->framesInTempOutputBuffer * bp->samplePeriod;

-

-    bp->callbackStatusFlags = callbackStatusFlags;

-

-    bp->hostInputFrameCount[1] = 0;

-    bp->hostOutputFrameCount[1] = 0;

-}

-

-

-/*

-    NonAdaptingProcess() is a simple buffer copying adaptor that can handle

-    both full and half duplex copies. It processes framesToProcess frames,

-    broken into blocks bp->framesPerTempBuffer long.

-    This routine can be used when the streamCallback doesn't care what length

-    the buffers are, or when framesToProcess is an integer multiple of

-    bp->framesPerTempBuffer, in which case streamCallback will always be called

-    with bp->framesPerTempBuffer samples.

-*/

-static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,

-        int *streamCallbackResult,

-        PaUtilChannelDescriptor *hostInputChannels,

-        PaUtilChannelDescriptor *hostOutputChannels,

-        unsigned long framesToProcess )

-{

-    void *userInput, *userOutput;

-    unsigned char *srcBytePtr, *destBytePtr;

-    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 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;

-    unsigned long frameCount;

-    unsigned long framesToGo = framesToProcess;

-    unsigned long framesProcessed = 0;

-

-

-    if( *streamCallbackResult == paContinue )

-    {

-        do

-        {

-            frameCount = PA_MIN_( bp->framesPerTempBuffer, framesToGo );

-

-            /* configure user input buffer and convert input data (host -> user) */

-            if( bp->inputChannelCount == 0 )

-            {

-                /* no input */

-                userInput = 0;

-            }

-            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;

-                }

-                else /* user input is not interleaved */

-                {

-                    destSampleStrideSamples = 1;

-                    destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;

-

-                    /* setup non-interleaved ptrs */

-                    for( i=0; i<bp->inputChannelCount; ++i )

-                    {

-                        bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +

-                            i * bp->bytesPerUserInputSample * frameCount;

-                    }

-                

-                    userInput = bp->tempInputBufferPtrs;

-                }

-

-                if( !bp->hostInputChannels[0][0].data )

-                {

-                    /* no input was supplied (see PaUtil_SetNoInput), so

-                        zero the input buffer */

-

-                    for( i=0; i<bp->inputChannelCount; ++i )

-                    {

-                        bp->inputZeroer( destBytePtr, destSampleStrideSamples, frameCount );

-                        destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */

-                    }

-                }

-                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;

-                    }

-                }

-            }

-

-            /* configure user output buffer */

-            if( bp->outputChannelCount == 0 )

-            {

-                /* no output */

-                userOutput = 0;

-            }

-            else /* there are output channels */

-            {

-                if( bp->userOutputIsInterleaved )

-                {

-                    userOutput = bp->tempOutputBuffer;

-                }

-                else /* user output is not interleaved */

-                {

-                    for( i = 0; i < bp->outputChannelCount; ++i )

-                    {

-                        bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +

-                            i * bp->bytesPerUserOutputSample * frameCount;

-                    }

-

-                    userOutput = bp->tempOutputBufferPtrs;

-                }

-            }

-        

-            *streamCallbackResult = bp->streamCallback( userInput, userOutput,

-                    frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData );

-

-            if( *streamCallbackResult == paAbort )

-            {

-                /* callback returned paAbort, don't advance framesProcessed

-                        and framesToGo, they will be handled below */

-            }

-            else

-            {

-                bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod;

-                bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod;

-

-                /* convert output data (user -> host) */

-                

-                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;

-                    }

-                }

-             

-                framesProcessed += frameCount;

-

-                framesToGo -= frameCount;

-            }

-        }

-        while( framesToGo > 0  && *streamCallbackResult == paContinue );

-    }

-

-    if( framesToGo > 0 )

-    {

-        /* zero any remaining frames output. There will only be remaining frames

-            if the callback has returned paComplete or paAbort */

-

-        frameCount = framesToGo;

-

-        if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )

-        {

-            for( i=0; i<bp->outputChannelCount; ++i )

-            {

-                bp->outputZeroer(   hostOutputChannels[i].data,

-                                    hostOutputChannels[i].stride,

-                                    frameCount );

-

-                /* advance dest ptr for next iteration */

-                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +

-                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;

-            }

-        }

-

-        framesProcessed += frameCount;

-    }

-

-    return framesProcessed;

-}

-

-

-/*

-    AdaptingInputOnlyProcess() is a half duplex input buffer processor. It

-    converts data from the input buffers into the temporary input buffer,

-    when the temporary input buffer is full, it calls the streamCallback.

-*/

-static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,

-        int *streamCallbackResult,

-        PaUtilChannelDescriptor *hostInputChannels,

-        unsigned long framesToProcess )

-{

-    void *userInput, *userOutput;

-    unsigned char *destBytePtr;

-    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;

-    unsigned long frameCount;

-    unsigned long framesToGo = framesToProcess;

-    unsigned long framesProcessed = 0;

-    

-    userOutput = 0;

-

-    do

-    {

-        frameCount = ( bp->framesInTempInputBuffer + framesToGo > bp->framesPerUserBuffer )

-                ? ( bp->framesPerUserBuffer - bp->framesInTempInputBuffer )

-                : framesToGo;

-

-        /* convert frameCount samples into temp buffer */

-

-        if( bp->userInputIsInterleaved )

-        {

-            destBytePtr = ((unsigned char*)bp->tempInputBuffer) +

-                    bp->bytesPerUserInputSample * bp->inputChannelCount *

-                    bp->framesInTempInputBuffer;

-                      

-            destSampleStrideSamples = bp->inputChannelCount;

-            destChannelStrideBytes = bp->bytesPerUserInputSample;

-

-            userInput = bp->tempInputBuffer;

-        }

-        else /* user input is not interleaved */

-        {

-            destBytePtr = ((unsigned char*)bp->tempInputBuffer) +

-                    bp->bytesPerUserInputSample * bp->framesInTempInputBuffer;

-

-            destSampleStrideSamples = 1;

-            destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample;

-

-            /* setup non-interleaved ptrs */

-            for( i=0; i<bp->inputChannelCount; ++i )

-            {

-                bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +

-                    i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer;

-            }

-                    

-            userInput = bp->tempInputBufferPtrs;

-        }

-

-        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;

-        }

-

-        bp->framesInTempInputBuffer += frameCount;

-

-        if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer )

-        {

-            /**

-            @todo (non-critical optimisation)

-            The conditional below implements the continue/complete/abort mechanism

-            simply by continuing on iterating through the input buffer, but not

-            passing the data to the callback. With care, the outer loop could be

-            terminated earlier, thus some unneeded conversion cycles would be

-            saved.

-            */

-            if( *streamCallbackResult == paContinue )

-            {

-                bp->timeInfo->outputBufferDacTime = 0;

-

-                *streamCallbackResult = bp->streamCallback( userInput, userOutput,

-                        bp->framesPerUserBuffer, bp->timeInfo,

-                        bp->callbackStatusFlags, bp->userData );

-

-                bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod;

-            }

-            

-            bp->framesInTempInputBuffer = 0;

-        }

-

-        framesProcessed += frameCount;

-

-        framesToGo -= frameCount;

-    }while( framesToGo > 0 );

-

-    return framesProcessed;

-}

-

-

-/*

-    AdaptingOutputOnlyProcess() is a half duplex output buffer processor.

-    It converts data from the temporary output buffer, to the output buffers,

-    when the temporary output buffer is empty, it calls the streamCallback.

-*/

-static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,

-        int *streamCallbackResult,

-        PaUtilChannelDescriptor *hostOutputChannels,

-        unsigned long framesToProcess )

-{

-    void *userInput, *userOutput;

-    unsigned char *srcBytePtr;

-    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;

-    unsigned long frameCount;

-    unsigned long framesToGo = framesToProcess;

-    unsigned long framesProcessed = 0;

-

-    do

-    {

-        if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult == paContinue )

-        {

-            userInput = 0;

-

-            /* setup userOutput */

-            if( bp->userOutputIsInterleaved )

-            {

-                userOutput = bp->tempOutputBuffer;

-            }

-            else /* user output is not interleaved */

-            {

-                for( i = 0; i < bp->outputChannelCount; ++i )

-                {

-                    bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +

-                            i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;

-                }

-

-                userOutput = bp->tempOutputBufferPtrs;

-            }

-

-            bp->timeInfo->inputBufferAdcTime = 0;

-            

-            *streamCallbackResult = bp->streamCallback( userInput, userOutput,

-                    bp->framesPerUserBuffer, bp->timeInfo,

-                    bp->callbackStatusFlags, bp->userData );

-

-            if( *streamCallbackResult == paAbort )

-            {

-                /* if the callback returned paAbort, we disregard its output */

-            }

-            else

-            {

-                bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod;

-

-                bp->framesInTempOutputBuffer = bp->framesPerUserBuffer;

-            }

-        }

-

-        if( bp->framesInTempOutputBuffer > 0 )

-        {

-            /* convert frameCount frames from user buffer to host buffer */

-

-            frameCount = PA_MIN_( bp->framesInTempOutputBuffer, framesToGo );

-

-            if( bp->userOutputIsInterleaved )

-            {

-                srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +

-                        bp->bytesPerUserOutputSample * bp->outputChannelCount *

-                        (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);

-

-                srcSampleStrideSamples = bp->outputChannelCount;

-                srcChannelStrideBytes = bp->bytesPerUserOutputSample;

-            }

-            else /* user output is not interleaved */

-            {

-                srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +

-                        bp->bytesPerUserOutputSample *

-                        (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);

-                            

-                srcSampleStrideSamples = 1;

-                srcChannelStrideBytes = bp->framesPerUserBuffer * 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;

-            }

-

-            bp->framesInTempOutputBuffer -= frameCount;

-        }

-        else

-        {

-            /* no more user data is available because the callback has returned

-                paComplete or paAbort. Fill the remainder of the host buffer

-                with zeros.

-            */

-

-            frameCount = framesToGo;

-

-            for( i=0; i<bp->outputChannelCount; ++i )

-            {

-                bp->outputZeroer(   hostOutputChannels[i].data,

-                                    hostOutputChannels[i].stride,

-                                    frameCount );

-

-                /* advance dest ptr for next iteration */

-                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +

-                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;

-            }

-        }

-        

-        framesProcessed += frameCount;

-        

-        framesToGo -= frameCount;

-

-    }while( framesToGo > 0 );

-

-    return framesProcessed;

-}

-

-/* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from

-	tempOutputBuffer to hostOutputChannels. This includes data conversion

-	and interleaving. 

-*/

-static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp)

-{

-    unsigned long maxFramesToCopy;

-    PaUtilChannelDescriptor *hostOutputChannels;

-    unsigned int frameCount;

-    unsigned char *srcBytePtr;

-    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;

-

-     /* copy frames from user to host output buffers */

-     while( bp->framesInTempOutputBuffer > 0 &&

-             ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) )

-     {

-         maxFramesToCopy = bp->framesInTempOutputBuffer;

-

-         /* select the output buffer set (1st or 2nd) */

-         if( bp->hostOutputFrameCount[0] > 0 )

-         {

-             hostOutputChannels = bp->hostOutputChannels[0];

-             frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy );

-         }

-         else

-         {

-             hostOutputChannels = bp->hostOutputChannels[1];

-             frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy );

-         }

-

-         if( bp->userOutputIsInterleaved )

-         {

-             srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +

-                     bp->bytesPerUserOutputSample * bp->outputChannelCount *

-                     (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);

-                         

-             srcSampleStrideSamples = bp->outputChannelCount;

-             srcChannelStrideBytes = bp->bytesPerUserOutputSample;

-         }

-         else /* user output is not interleaved */

-         {

-             srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +

-                     bp->bytesPerUserOutputSample *

-                     (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);

-

-             srcSampleStrideSamples = 1;

-             srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;

-         }

-

-         for( i=0; i<bp->outputChannelCount; ++i )

-         {

-             assert( hostOutputChannels[i].data != NULL );

-             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( bp->hostOutputFrameCount[0] > 0 )

-             bp->hostOutputFrameCount[0] -= frameCount;

-         else

-             bp->hostOutputFrameCount[1] -= frameCount;

-

-         bp->framesInTempOutputBuffer -= frameCount;

-     }

-}

-

-/*

-    AdaptingProcess is a full duplex adapting buffer processor. It converts

-    data from the temporary output buffer into the host output buffers, then

-    from the host input buffers into the temporary input buffers. Calling the

-    streamCallback when necessary.

-    When processPartialUserBuffers is 0, all available input data will be

-    consumed and all available output space will be filled. When

-    processPartialUserBuffers is non-zero, as many full user buffers

-    as possible will be processed, but partial buffers will not be consumed.

-*/

-static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,

-        int *streamCallbackResult, int processPartialUserBuffers )

-{

-    void *userInput, *userOutput;

-    unsigned long framesProcessed = 0;

-    unsigned long framesAvailable;

-    unsigned long endProcessingMinFrameCount;

-    unsigned long maxFramesToCopy;

-    PaUtilChannelDescriptor *hostInputChannels, *hostOutputChannels;

-    unsigned int frameCount;

-    unsigned char *destBytePtr;

-    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, j;

- 

-

-    framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */

-

-    if( processPartialUserBuffers )

-        endProcessingMinFrameCount = 0;

-    else

-        endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1);

-

-    /* Fill host output with remaining frames in user output (tempOutputBuffer) */

-    CopyTempOutputBuffersToHostOutputBuffers( bp );		  	

-

-    while( framesAvailable > endProcessingMinFrameCount ) 

-    {

-

-        if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue )

-        {

-            /* the callback will not be called any more, so zero what remains

-                of the host output buffers */

-

-            for( i=0; i<2; ++i )

-            {

-                frameCount = bp->hostOutputFrameCount[i];

-                if( frameCount > 0 )

-                {

-                    hostOutputChannels = bp->hostOutputChannels[i];

-                    

-                    for( j=0; j<bp->outputChannelCount; ++j )

-                    {

-                        bp->outputZeroer(   hostOutputChannels[j].data,

-                                            hostOutputChannels[j].stride,

-                                            frameCount );

-

-                        /* advance dest ptr for next iteration  */

-                        hostOutputChannels[j].data = ((unsigned char*)hostOutputChannels[j].data) +

-                                frameCount * hostOutputChannels[j].stride * bp->bytesPerHostOutputSample;

-                    }

-                    bp->hostOutputFrameCount[i] = 0;

-                }

-            }

-        }          

-

-

-        /* copy frames from host to user input buffers */

-        while( bp->framesInTempInputBuffer < bp->framesPerUserBuffer &&

-                ((bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) > 0) )

-        {

-            maxFramesToCopy = bp->framesPerUserBuffer - bp->framesInTempInputBuffer;

-

-            /* select the input buffer set (1st or 2nd) */

-            if( bp->hostInputFrameCount[0] > 0 )

-            {

-                hostInputChannels = bp->hostInputChannels[0];

-                frameCount = PA_MIN_( bp->hostInputFrameCount[0], maxFramesToCopy );

-            }

-            else

-            {

-                hostInputChannels = bp->hostInputChannels[1];

-                frameCount = PA_MIN_( bp->hostInputFrameCount[1], maxFramesToCopy );

-            }

-

-            /* configure conversion destination pointers */

-            if( bp->userInputIsInterleaved )

-            {

-                destBytePtr = ((unsigned char*)bp->tempInputBuffer) +

-                        bp->bytesPerUserInputSample * bp->inputChannelCount *

-                        bp->framesInTempInputBuffer;

-

-                destSampleStrideSamples = bp->inputChannelCount;

-                destChannelStrideBytes = bp->bytesPerUserInputSample;

-            }

-            else /* user input is not interleaved */

-            {

-                destBytePtr = ((unsigned char*)bp->tempInputBuffer) +

-                        bp->bytesPerUserInputSample * bp->framesInTempInputBuffer;

-

-                destSampleStrideSamples = 1;

-                destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample;

-            }

-

-            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->hostInputFrameCount[0] > 0 )

-                bp->hostInputFrameCount[0] -= frameCount;

-            else

-                bp->hostInputFrameCount[1] -= frameCount;

-                

-            bp->framesInTempInputBuffer += frameCount;

-

-            /* update framesAvailable and framesProcessed based on input consumed

-                unless something is very wrong this will also correspond to the

-                amount of output generated */

-            framesAvailable -= frameCount;

-            framesProcessed += frameCount;

-        }

-

-        /* call streamCallback */

-        if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer &&

-            bp->framesInTempOutputBuffer == 0 )

-        {

-            if( *streamCallbackResult == paContinue )

-            {

-                /* setup userInput */

-                if( bp->userInputIsInterleaved )

-                {

-                    userInput = bp->tempInputBuffer;

-                }

-                else /* user input is not interleaved */

-                {

-                    for( i = 0; i < bp->inputChannelCount; ++i )

-                    {

-                        bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +

-                                i * bp->framesPerUserBuffer * bp->bytesPerUserInputSample;

-                    }

-

-                    userInput = bp->tempInputBufferPtrs;

-                }

-

-                /* setup userOutput */

-                if( bp->userOutputIsInterleaved )

-                {

-                    userOutput = bp->tempOutputBuffer;

-                }

-                else /* user output is not interleaved */

-                {

-                    for( i = 0; i < bp->outputChannelCount; ++i )

-                    {

-                        bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +

-                                i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;

-                    }

-

-                    userOutput = bp->tempOutputBufferPtrs;

-                }

-

-                /* call streamCallback */

-

-                *streamCallbackResult = bp->streamCallback( userInput, userOutput,

-                        bp->framesPerUserBuffer, bp->timeInfo,

-                        bp->callbackStatusFlags, bp->userData );

-

-                bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod;

-                bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod;

-

-                bp->framesInTempInputBuffer = 0;

-

-                if( *streamCallbackResult == paAbort )

-                    bp->framesInTempOutputBuffer = 0;

-                else

-                    bp->framesInTempOutputBuffer = bp->framesPerUserBuffer;

-            }

-            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( PaUtilBufferProcessor* bp, unsigned long frameCount )

-{

-    PaUtilChannelDescriptor *hostOutputChannels;

-    unsigned int framesToZero;

-    unsigned int i;

-

-    hostOutputChannels = bp->hostOutputChannels[0];

-    framesToZero = PA_MIN_( bp->hostOutputFrameCount[0], frameCount );

-

-    for( i=0; i<bp->outputChannelCount; ++i )

-    {

-        bp->outputZeroer(   hostOutputChannels[i].data,

-                            hostOutputChannels[i].stride,

-                            framesToZero );

-

-

-        /* advance dest ptr for next iteration */

-        hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +

-                framesToZero * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;

-    }

-

-    bp->hostOutputFrameCount[0] += framesToZero;

-    

-    return framesToZero;

-}