12c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*
22c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Copyright (C) 2004-2010 NXP Software
32c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Copyright (C) 2010 The Android Open Source Project
42c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *
52c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
62c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * you may not use this file except in compliance with the License.
72c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * You may obtain a copy of the License at
82c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *
92c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *
112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Unless required by applicable law or agreed to in writing, software
122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * See the License for the specific language governing permissions and
152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * limitations under the License.
162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */
172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                        */
212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    Includes                                                                              */
222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                        */
232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVM_Private.h"
262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "VectorArithmetic.h"
272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferManagedIn                                        */
312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    Full buffer management allowing the user to provide input and output buffers on   */
342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  any alignment and with any number of samples. The alignment is corrected within     */
352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  the buffer management and the samples are grouped in to blocks of the correct size  */
362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  before processing.                                                                  */
372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        -    Instance handle                                             */
402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pInData            -    Pointer to the input data stream                          */
412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pToProcess        -    Pointer to pointer to the start of data processing          */
422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pProcessed        -    Pointer to pointer to the destination of the processed data */
432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        -    Pointer to the number of samples to process               */
442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferManagedIn(LVM_Handle_t       hInstance,
532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         const LVM_INT16    *pInData,
542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         LVM_INT16          **pToProcess,
552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         LVM_INT16          **pProcessed,
562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         LVM_UINT16         *pNumSamples)
572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        SampleCount;           /* Number of samples to be processed this call */
602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        NumSamples;            /* Number of samples in scratch buffer */
612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        *pStart;
622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Buffer_t     *pBuffer;
642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        *pDest;
652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        NumChannels =2;
662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Set the processing address pointers
702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pBuffer     = pInstance->pBufferManagement;
722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pDest       = pBuffer->pScratch;
732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *pToProcess = pBuffer->pScratch;
742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *pProcessed = pBuffer->pScratch;
752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if it is the first call of a block
782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->SamplesToProcess == 0)
802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * First call for a new block of samples
832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pInputSamples    = (LVM_INT16 *)pInData;
862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->BufferState        = LVM_FIRSTCALL;
872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pStart = pInstance->pInputSamples;                       /* Pointer to the input samples */
892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pBuffer->SamplesToOutput  = 0;                           /* Samples to output is same as number read for inplace processing */
902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Calculate the number of samples to process this call and update the buffer state
942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Process the maximum bock size of samples.
992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        SampleCount = pInstance->InternalBlockSize;
1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumSamples  = pInstance->InternalBlockSize;
1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Last call for the block, so calculate how many frames and samples to process
1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent          */
1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_INT16   NumFrames;
1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumSamples  = pInstance->SamplesToProcess;
1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumFrames    = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Update the buffer state
1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pBuffer->BufferState == LVM_FIRSTCALL)
1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->BufferState = LVM_FIRSTLASTCALL;
1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->BufferState = LVM_LASTCALL;
1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *pNumSamples = (LVM_UINT16)SampleCount;                        /* Set the number of samples to process this call */
1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Copy samples from the delay buffer as required
1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (((pBuffer->BufferState == LVM_FIRSTCALL) ||
1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (pBuffer->InDelaySamples != 0))
1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16(&pBuffer->InDelayBuffer[0],                             /* Source */
1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                pDest,                                                  /* Destination */
1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(NumChannels*pBuffer->InDelaySamples));      /* Number of delay samples, left and right */
1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pDest += NumChannels * pBuffer->InDelaySamples;                 /* Update the destination pointer */
1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Copy the rest of the samples for this call from the input buffer
1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (NumSamples > 0)
1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16(pStart,                                             /* Source */
1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                pDest,                                              /* Destination */
1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(NumChannels*NumSamples));               /* Number of input samples */
1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pStart += NumChannels * NumSamples;                         /* Update the input pointer */
1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Update the input data pointer and samples to output
1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples); /* Update samples to output */
1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      * Update the sample count and input pointer
1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);      /* Update the count of samples */
1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pInputSamples     = pStart;                                                      /* Update input sample pointer */
1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Save samples to the delay buffer if any left unprocessed
1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) ||
1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (pBuffer->BufferState == LVM_LASTCALL))
1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumSamples = pInstance->SamplesToProcess;
1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pStart     = pBuffer->pScratch;                             /* Start of the buffer */
1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pStart    += NumChannels*SampleCount;                       /* Offset by the number of processed samples */
1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (NumSamples != 0)
1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pStart,                                         /* Source */
1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    &pBuffer->InDelayBuffer[0],                     /* Destination */
1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(NumChannels*NumSamples));           /* Number of input samples */
1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Update the delay sample count
1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->InDelaySamples     = NumSamples;                   /* Number of delay sample pairs */
1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->SamplesToProcess = 0;                            /* All Samples used */
1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferUnmanagedIn                                      */
1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    This mode is selected by the user code and disables the buffer management with the */
2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  exception of the maximum block size processing. The user must ensure that the       */
2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  input and output buffers are 32-bit aligned and also that the number of samples to  */
2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    process is a correct multiple of samples.                                         */
2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        -    Instance handle                                             */
2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pToProcess        -    Pointer to the start of data processing                     */
2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pProcessed        -    Pointer to the destination of the processed data            */
2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        -    Pointer to the number of samples to process               */
2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferUnmanagedIn(LVM_Handle_t     hInstance,
2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           LVM_INT16        **pToProcess,
2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           LVM_INT16        **pProcessed,
2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           LVM_UINT16       *pNumSamples)
2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if this is the first call of a block
2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->SamplesToProcess == 0)
2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples;       /* Get the number of samples on first call */
2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pInputSamples    = *pToProcess;                   /* Get the I/O pointers */
2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pOutputSamples    = *pProcessed;
2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Set te block size to process
2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Set the process pointers
2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *pToProcess = pInstance->pInputSamples;
2532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *pProcessed = pInstance->pOutputSamples;
2542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
2582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferOptimisedIn                                      */
2602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
2622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    Optimised buffer management for the case where the data is outplace processing,   */
2632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    the output data is 32-bit aligned and there are sufficient samples to allow some  */
2642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    processing directly in the output buffer. This saves one data copy per sample     */
2652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    compared with the unoptimsed version.                                             */
2662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
2682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        -    Instance handle                                             */
2692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pInData            -    Pointer to the input data stream                          */
2702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pToProcess        -    Pointer to the start of data processing                     */
2712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pProcessed        -    Pointer to the destination of the processed data            */
2722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        -    Pointer to the number of samples to process               */
2732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
2752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
2762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
2782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
2792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
2802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferOptimisedIn(LVM_Handle_t         hInstance,
2822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           const LVM_INT16      *pInData,
2832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           LVM_INT16            **pToProcess,
2842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           LVM_INT16            **pProcessed,
2852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                           LVM_UINT16           *pNumSamples)
2862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
2872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
2892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Buffer_t     *pBuffer    = pInstance->pBufferManagement;
2902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        *pDest;
2912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        SampleCount;
2922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        NumSamples;
2932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16        NumFrames;
2942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if it is the first call for this block
2972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->SamplesToProcess == 0)
2992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
3012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * First call for a new block of samples
3022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
3032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->BufferState = LVM_FIRSTCALL;
3042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pInputSamples    = (LVM_INT16 *)pInData;
3052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples;
3062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->SamplesToOutput    = (LVM_INT16)*pNumSamples;
3072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pDest = *pProcessed;                                    /* The start of the output buffer */
3082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
3112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Copy the already processed samples to the output buffer
3122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
3132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pBuffer->OutDelaySamples != 0)
3142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
3162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pDest,                                          /* Detsination */
3172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of delay samples */
3182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pDest += 2 * pBuffer->OutDelaySamples;                  /* Update the output pointer */
3192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - pBuffer->OutDelaySamples); /* Update the numbr of samples to output */
3202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *pToProcess = pDest;                                    /* Set the address to start processing */
3222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *pProcessed = pDest;                                    /* Process in the output buffer, now inplace */
3232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
3252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Copy the input delay buffer (unprocessed) samples to the output buffer
3262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
3272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pBuffer->InDelaySamples != 0)
3282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(&pBuffer->InDelayBuffer[0],                     /* Source */
3302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pDest,                                          /* Destination */
3312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*pBuffer->InDelaySamples));        /* Number of delay samples */
3322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pDest += 2 * pBuffer->InDelaySamples;                   /* Update the output pointer */
3332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
3372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Calculate how many input samples to process and copy
3382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
3392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumSamples    = (LVM_INT16)(*pNumSamples - pBuffer->OutDelaySamples);  /* Number that will fit in the output buffer */
3402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (NumSamples >= pInstance->InternalBlockSize)
3412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples = pInstance->InternalBlockSize;
3432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        NumFrames      = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
3452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        SampleCount   = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
3462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *pNumSamples  = (LVM_UINT16)SampleCount;                                        /* The number of samples to process */
3472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - SampleCount); /* Update the number of samples to output */
3482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        SampleCount   = (LVM_INT16)(SampleCount - pBuffer->InDelaySamples);             /* The number of samples to copy from the input */
3492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
3522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Copy samples from the input buffer and update counts and pointers
3532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
3542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16(pInstance->pInputSamples,                           /* Source */
3552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                pDest,                                              /* Destination */
3562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(2*SampleCount));                        /* Number of input samples */
3572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pInputSamples += 2 * SampleCount;                /* Update the input pointer */
3582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pOutputSamples = pDest + (2 * SampleCount);      /* Update the output pointer */
3592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */
3602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
3622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
3642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Second or subsequent call in optimised mode
3652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
3662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pBuffer->SamplesToOutput >= MIN_INTERNAL_BLOCKSIZE)
3672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
3692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * More samples can be processed directly in the output buffer
3702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
3712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pToProcess = pInstance->pOutputSamples;                /* Set the address to start processing */
3722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pProcessed = pInstance->pOutputSamples;                /* Process in the output buffer, now inplace */
3732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples  = pBuffer->SamplesToOutput;                 /* Number that will fit in the output buffer */
3742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            if (NumSamples >= pInstance->InternalBlockSize)
3752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            {
3762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                NumSamples = pInstance->InternalBlockSize;
3772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            }
3782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumFrames      = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
3792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            SampleCount   = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
3802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pNumSamples  = (LVM_UINT16)SampleCount;            /* The number of samples to process */
3812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
3842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Copy samples from the input buffer and update counts and pointers
3852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
3862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pInstance->pInputSamples,                       /* Source */
3872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pInstance->pOutputSamples,                      /* Destination */
3882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*SampleCount));                    /* Number of input samples */
3892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pInstance->pInputSamples += 2 * SampleCount;            /* Update the input pointer */
3902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pInstance->pOutputSamples += 2 * SampleCount;           /* Update the output pointer */
3912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);   /* Samples left in the input buffer */
3922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - SampleCount);         /* Number that will fit in the output buffer */
3932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
3952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
3972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * The remaining samples can not be processed in the output buffer
3982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
3992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->BufferState = LVM_LASTCALL;                    /* Indicate this is the last bock to process */
4002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pToProcess  = pBuffer->pScratch;                       /* Set the address to start processing */
4012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pProcessed  = pBuffer->pScratch;                       /* Process in the output buffer, now inplace */
4022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples   = pInstance->SamplesToProcess;             /* Number left to be processed */
4032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumFrames     = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
4042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            SampleCount  = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
4052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pNumSamples = (LVM_UINT16)SampleCount;                /* The number of samples to process */
4062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
4092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Copy samples from the input buffer and update counts and pointers
4102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
4112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pInstance->pInputSamples,                       /* Source */
4122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pBuffer->pScratch,                              /* Destination */
4132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*SampleCount));                    /* Number of input samples */
4142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pInstance->pInputSamples += 2 * SampleCount;            /* Update the input pointer */
4152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */
4162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
4172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
4182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
4192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
4212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferIn                                               */
4232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
4252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    This function manages the data input, it has the following features:              */
4262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Accepts data in 16-bit aligned memory                                       */
4272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Copies the data to 32-bit aligned memory                                    */
4282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Converts Mono inputs to Mono-in-Stereo                                      */
4292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Accepts any number of samples as input, except 0                            */
4302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Breaks the input sample stream in to blocks of the configured frame size or */
4312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*          multiples of the frame size                                                 */
4322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Limits the processing block size to the maximum block size.                 */
4332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Works with inplace or outplace processing automatically                     */
4342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  To manage the data the function has a number of operating states:                   */
4362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        LVM_FIRSTCALL        - The first call for this block of input samples         */
4372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        LVM_MAXBLOCKCALL    - The current block is the maximum size. Only used for the */
4382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                              second and subsequent blocks.                           */
4392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        LVM_LASTCALL        - The last call for this block of input samples           */
4402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        LVM_FIRSTLASTCALL    - This is the first and last call for this block of input*/
4412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                              samples, this occurs when the number of samples to      */
4422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                              process is less than the maximum block size.            */
4432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    The function uses an internal delay buffer the size of the minimum frame, this is */
4452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  used to temporarily hold samples when the number of samples to process is not a     */
4462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  multiple of the frame size.                                                         */
4472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    To ensure correct operation with inplace buffering the number of samples to output*/
4492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  per call is calculated in this function and is set to the number of samples read    */
4502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  from the input buffer.                                                              */
4512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    The total number of samples to process is stored when the function is called for  */
4532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  the first time. The value is overwritten by the size of the block to be processed   */
4542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  in each call so the size of the processing blocks can be controlled. The number of  */
4552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    samples actually processed for each block of input samples is always a multiple of*/
4562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  the frame size so for any particular block of input samples the actual number of    */
4572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  processed samples may not match the number of input samples, sometime it will be    */
4582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  sometimes less. The average is the same and the difference is never more than the   */
4592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  frame size.                                                                         */
4602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
4622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        -    Instance handle                                             */
4632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pInData            -    Pointer to the input data stream                          */
4642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pToProcess        -    Pointer to the start of data processing                     */
4652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  *pProcessed        -    Pointer to the destination of the processed data            */
4662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        -    Pointer to the number of samples to process               */
4672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
4692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
4702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
4722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
4732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
4742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferIn(LVM_Handle_t      hInstance,
4762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                  const LVM_INT16   *pInData,
4772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                  LVM_INT16         **pToProcess,
4782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                  LVM_INT16         **pProcessed,
4792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                  LVM_UINT16        *pNumSamples)
4802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
4812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
4832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
4852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
4862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check which mode, managed or unmanaged
4872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
4882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
4892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
4902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_BufferManagedIn(hInstance,
4912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pInData,
4922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pToProcess,
4932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pProcessed,
4942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pNumSamples);
4952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
4962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
4972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
4982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_BufferUnmanagedIn(hInstance,
4992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                              pToProcess,
5002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                              pProcessed,
5012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                              pNumSamples);
5022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
5032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
5042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
5062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
5072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferManagedOut                                       */
5082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
5092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
5102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Full buffer management output. This works in conjunction with the managed input     */
5112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  routine and ensures the correct number of samples are always output to the output   */
5122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  buffer.                                                                             */
5132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
5142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
5152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        - Instance handle                                                */
5162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pOutData        - Pointer to the output data stream                               */
5172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        - Pointer to the number of samples to process                  */
5182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
5192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
5202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
5212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
5222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
5232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
5242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
5252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferManagedOut(LVM_Handle_t        hInstance,
5272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                          LVM_INT16            *pOutData,
5282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                          LVM_UINT16        *pNumSamples)
5292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
5302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t  *pInstance  = (LVM_Instance_t  *)hInstance;
5322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Buffer_t    *pBuffer    = pInstance->pBufferManagement;
5332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16       SampleCount = (LVM_INT16)*pNumSamples;
5342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16       NumSamples;
5352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16       *pStart;
5362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16       *pDest;
5372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
5402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Set the pointers
5412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
5422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    NumSamples = pBuffer->SamplesToOutput;
5432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pStart     = pBuffer->pScratch;
5442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
5472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * check if it is the first call of a block
5482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      */
5492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if ((pBuffer->BufferState == LVM_FIRSTCALL) ||
5502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (pBuffer->BufferState == LVM_FIRSTLASTCALL))
5512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
5522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* First call for a new block */
5532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInstance->pOutputSamples = pOutData;                        /* Initialise the destination */
5542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
5552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pDest = pInstance->pOutputSamples;                               /* Set the output address */
5562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
5592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * If the number of samples is non-zero then there are still samples to send to
5602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * the output buffer
5612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
5622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if ((NumSamples != 0) &&
5632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (pBuffer->OutDelaySamples != 0))
5642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
5652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
5662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Copy the delayed output buffer samples to the output
5672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
5682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pBuffer->OutDelaySamples <= NumSamples)
5692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
5702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
5712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Copy all output delay samples to the output
5722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
5732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
5742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pDest,                                          /* Detsination */
5752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of delay samples */
5762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
5782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Update the pointer and sample counts
5792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
5802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pDest += 2*pBuffer->OutDelaySamples;                                /* Output sample pointer */
5812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples);    /* Samples left to send */
5822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->OutDelaySamples = 0;                                       /* No samples left in the buffer */
5832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
5852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
5862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
5872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
5882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Copy only some of the ouput delay samples to the output
5892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
5902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
5912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pDest,                                          /* Detsination */
5922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*NumSamples));                     /* Number of delay samples */
5932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
5942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
5952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Update the pointer and sample counts
5962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
5972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pDest += 2*NumSamples;                                                              /* Output sample pointer */
5982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);      /* No samples left in the buffer */
5992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
6022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Realign the delay buffer data to avoid using circular buffer management
6032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
6042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(&pBuffer->OutDelayBuffer[2*NumSamples],         /* Source */
6052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    &pBuffer->OutDelayBuffer[0],                    /* Destination */
6062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of samples to move */
6072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples = 0;                                         /* Samples left to send */
6082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
6092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
6102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
6132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Copy the processed results to the output
6142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
6152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if ((NumSamples != 0) &&
6162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (SampleCount != 0))
6172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
6182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (SampleCount <= NumSamples)
6192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
6202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
6212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Copy all processed samples to the output
6222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
6232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pStart,                                      /* Source */
6242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pDest,                                       /* Detsination */
6252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*SampleCount));                 /* Number of processed samples */
6262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
6282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Update the pointer and sample counts
6292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
6302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pDest      += 2 * SampleCount;                          /* Output sample pointer */
6312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples  = (LVM_INT16)(NumSamples - SampleCount);    /* Samples left to send */
6322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            SampleCount = 0;                                        /* No samples left in the buffer */
6332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
6342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
6352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
6362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
6372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Copy only some processed samples to the output
6382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
6392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pStart,                                         /* Source */
6402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pDest,                                          /* Destination */
6412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*NumSamples));                     /* Number of processed samples */
6422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
6452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Update the pointers and sample counts
6462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent               */
6472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pStart      += 2 * NumSamples;                          /* Processed sample pointer */
6482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pDest        += 2 * NumSamples;                         /* Output sample pointer */
6492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            SampleCount  = (LVM_INT16)(SampleCount - NumSamples);   /* Processed samples left */
6502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            NumSamples   = 0;                                       /* Clear the sample count */
6512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
6522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
6532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
6562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Copy the remaining processed data to the output delay buffer
6572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
6582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (SampleCount != 0)
6592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
6602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16(pStart,                                                 /* Source */
6612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                &pBuffer->OutDelayBuffer[2*pBuffer->OutDelaySamples],   /* Destination */
6622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(2*SampleCount));                            /* Number of processed samples */
6632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount); /* Update the buffer count */
6642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
6652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
6682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * pointers, counts and set default buffer processing
6692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
6702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pBuffer->SamplesToOutput  = NumSamples;                         /* Samples left to send */
6712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pOutputSamples = pDest;                              /* Output sample pointer */
6722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pBuffer->BufferState      = LVM_MAXBLOCKCALL;                   /* Set for the default call block size */
6732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;         /* This will terminate the loop when all samples processed */
6742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
6752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
6782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
6792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferUnmanagedOut                                     */
6802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
6812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
6822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This works in conjunction with the unmanaged input routine and updates the number   */
6832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    of samples left to be processed    and adjusts the buffer pointers.               */
6842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
6852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
6862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        - Instance handle                                                */
6872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        - Pointer to the number of samples to process                  */
6882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
6892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
6902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
6912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
6922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
6932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
6942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
6952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
6962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferUnmanagedOut(LVM_Handle_t        hInstance,
6972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            LVM_UINT16          *pNumSamples)
6982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
6992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
7012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16           NumChannels =2;
7022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
7052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Update sample counts
7062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
7072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pInputSamples    += (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */
7082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pOutputSamples   += (LVM_INT16)(*pNumSamples * 2);
7092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */
7102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
7122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Set te block size to process
7132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
7142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
7152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
7162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
7172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
7182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
7192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
7202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
7212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
7222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
7232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
7262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
7272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferOptimisedOut                                     */
7282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
7292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
7302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This works in conjunction with the optimised input routine and copies the last few  */
7312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  processed and unprocessed samples to their respective buffers.                      */
7322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
7332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
7342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        - Instance handle                                                */
7352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        - Pointer to the number of samples to process                  */
7362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
7372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
7382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
7392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
7402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
7412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
7422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
7432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferOptimisedOut(LVM_Handle_t    hInstance,
7452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            LVM_UINT16        *pNumSamples)
7462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
7472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t      *pInstance = (LVM_Instance_t  *)hInstance;
7492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Buffer_t        *pBuffer   = pInstance->pBufferManagement;
7502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
7522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if it is the last block to process
7532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
7542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pBuffer->BufferState == LVM_LASTCALL)
7552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
7562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_INT16    *pSrc = pBuffer->pScratch;
7572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
7592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Copy the unprocessed samples to the input delay buffer
7602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
7612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pInstance->SamplesToProcess != 0)
7622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
7632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pInstance->pInputSamples,                       /* Source */
7642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    &pBuffer->InDelayBuffer[0],                     /* Destination */
7652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*pInstance->SamplesToProcess));    /* Number of input samples */
7662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->InDelaySamples = pInstance->SamplesToProcess;
7672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pInstance->SamplesToProcess = 0;
7682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
7692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
7702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
7712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->InDelaySamples = 0;
7722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
7732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
7762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Fill the last empty spaces in the output buffer
7772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
7782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pBuffer->SamplesToOutput != 0)
7792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
7802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pSrc,                                           /* Source */
7812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    pInstance->pOutputSamples,                      /* Destination */
7822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2*pBuffer->SamplesToOutput));       /* Number of input samples */
7832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pNumSamples = (LVM_UINT16)(*pNumSamples - pBuffer->SamplesToOutput);
7842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pSrc += 2 * pBuffer->SamplesToOutput;                  /* Update scratch pointer */
7852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->SamplesToOutput = 0;                          /* No more samples in this block */
7862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
7872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
7902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Save any remaining processed samples in the output delay buffer
7912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
7922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (*pNumSamples != 0)
7932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
7942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16(pSrc,                                           /* Source */
7952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    &pBuffer->OutDelayBuffer[0],                    /* Destination */
7962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    (LVM_INT16)(2**pNumSamples));                   /* Number of input samples */
7972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
7982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->OutDelaySamples = (LVM_INT16)*pNumSamples;
7992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            *pNumSamples = 0;                                      /* No more samples in this block */
8012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
8022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else
8032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
8042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pBuffer->OutDelaySamples = 0;
8052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
8062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
8072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
8082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
8112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                 LVM_BufferOut                                              */
8132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
8152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This function manages the data output, it has the following features:               */
8162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Output data to 16-bit aligned memory                                        */
8172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Reads data from 32-bit aligned memory                                       */
8182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Reads data only in blocks of frame size or multiples of frame size          */
8192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Writes the same number of samples as the LVM_BufferIn function reads        */
8202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        - Works with inplace or outplace processing automatically                     */
8212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  To manage the data the function has a number of operating states:                   */
8232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        LVM_FIRSTCALL        - The first call for this block of input samples         */
8242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        LVM_FIRSTLASTCALL    - This is the first and last call for this block of input*/
8252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                              samples, this occurs when the number of samples to      */
8262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                              process is less than the maximum block size.            */
8272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    The function uses an internal delay buffer the size of the minimum frame, this is */
8292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  used to temporarily hold samples when the number of samples to write is not a       */
8302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  multiple of the frame size.                                                         */
8312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    To ensure correct operation with inplace buffering the number of samples to output*/
8332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  per call is always the same as the number of samples read from the input buffer.    */
8342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
8362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    hInstance        - Instance handle                                                */
8372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pOutData        - Pointer to the output data stream                               */
8382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    pNumSamples        - Pointer to the number of samples to process                  */
8392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
8412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    None                                                                              */
8422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
8442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
8452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
8462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid LVM_BufferOut(LVM_Handle_t     hInstance,
8482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   LVM_INT16        *pOutData,
8492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   LVM_UINT16       *pNumSamples)
8502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
8512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_Instance_t    *pInstance  = (LVM_Instance_t  *)hInstance;
8532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
8552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
8562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check which mode, managed or unmanaged
8572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
8582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
8592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
8602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_BufferManagedOut(hInstance,
8612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                             pOutData,
8622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                             pNumSamples);
8632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
8642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
8652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
8662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_BufferUnmanagedOut(hInstance,
8672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                               pNumSamples);
8682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
8692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
8702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
871