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/*  Includes                                                                        */
212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS.h"
252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_Private.h"
262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_ReverbGenerator.h"
272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVC_Mixer.h"
282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "VectorArithmetic.h"
292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "BIQUAD.h"
302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_Tables.h"
312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                LVCS_ReverbGeneratorInit                                */
352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                     */
372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Initialises the reverb module. The delay buffer size is configured for the      */
382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  sample rate and the speaker type.                                               */
392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  The routine may also be called for re-initialisation, i.e. when one of the      */
412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  control parameters has changed. In this case the delay and filters are only     */
422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  re-initialised if one of the following two conditions is met:                   */
432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      -   the sample rate has changed                                             */
442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      -   the speaker type changes to/from the mobile speaker                     */
452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                      */
482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance               Instance Handle                                         */
492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pParams                 Pointer to the inialisation parameters                  */
502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                         */
522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVCS_Success            Always succeeds                                         */
532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                           */
552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  1.  In the delay settings 'Samples' is the number of samples to the end of the  */
562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      buffer.                                                                     */
572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  2.  The numerator coefficients of the filter are negated to cause an inversion. */
582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
612c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t     hInstance,
622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              LVCS_Params_t     *pParams)
632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_UINT16              Delay;
662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_UINT16              Offset;
672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Instance_t         *pInstance = (LVCS_Instance_t  *)hInstance;
682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_ReverbGenerator_t  *pConfig   = (LVCS_ReverbGenerator_t *)&pInstance->Reverberation;
692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Data_t             *pData     = (LVCS_Data_t *)pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Coefficient_t      *pCoefficients = (LVCS_Coefficient_t *)pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    BQ_C16_Coefs_t          Coeffs;
722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    const BiquadA012B12CoefsSP_t  *pReverbCoefTable;
732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Initialise the delay and filters if:
762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     *  - the sample rate has changed
772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     *  - the speaker type has changed to or from the mobile speaker
782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(pInstance->Params.SampleRate != pParams->SampleRate )      /* Sample rate change test */
802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Setup the delay
842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Delay = (LVM_UINT16)LVCS_StereoDelayCS[(LVM_UINT16)pParams->SampleRate];
862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pConfig->DelaySize      = (LVM_INT16)(2 * Delay);
892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pConfig->DelayOffset    = 0;
902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LoadConst_16(0,                                                                 /* Value */
912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     (LVM_INT16 *)&pConfig->StereoSamples[0],                           /* Destination */
922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     (LVM_UINT16)(sizeof(pConfig->StereoSamples)/sizeof(LVM_INT16)));   /* Number of words */
932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Setup the filters
962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Offset = (LVM_UINT16)pParams->SampleRate;
982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pReverbCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_ReverbCoefTable[0];
992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* Convert incoming coefficients to the required format/ordering */
1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Coeffs.A0 = (LVM_INT16)pReverbCoefTable[Offset].A0;
1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Coeffs.A1 = (LVM_INT16)pReverbCoefTable[Offset].A1;
1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Coeffs.A2 = (LVM_INT16)pReverbCoefTable[Offset].A2;
1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Coeffs.B1 = (LVM_INT16)-pReverbCoefTable[Offset].B1;
1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Coeffs.B2 = (LVM_INT16)-pReverbCoefTable[Offset].B2;
1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LoadConst_16(0,                                                                 /* Value */
10809d5ca3766d4bab91cdaad7206716a5747ebad77Eric Laurent                     (void *)&pData->ReverbBiquadTaps,                             /* Destination Cast to void: no dereferencing in function*/
1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     (LVM_UINT16)(sizeof(pData->ReverbBiquadTaps)/sizeof(LVM_INT16)));  /* Number of words */
1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        BQ_2I_D16F16Css_TRC_WRA_01_Init(&pCoefficients->ReverbBiquadInstance,
1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                        &pData->ReverbBiquadTaps,
1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                        &Coeffs);
1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* Callbacks */
1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        switch(pReverbCoefTable[Offset].Scale)
1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            case 14:
1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                pConfig->pBiquadCallBack  = BQ_2I_D16F16C14_TRC_WRA_01;
1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                break;
1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            case 15:
1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                pConfig->pBiquadCallBack  = BQ_2I_D16F16C15_TRC_WRA_01;
1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                break;
1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Setup the mixer
1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pConfig->ProcGain = (LVM_UINT16)(HEADPHONEGAINPROC);
1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pConfig->UnprocGain  = (LVM_UINT16)(HEADPHONEGAINUNPROC);
1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(pInstance->Params.ReverbLevel != pParams->ReverbLevel)
1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVM_INT32   ReverbPercentage=83886;                     // 1 Percent Reverb i.e 1/100 in Q 23 format
1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ReverbPercentage*=pParams->ReverbLevel;                 // Actual Reverb Level in Q 23 format
1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pConfig->ReverbLevel=(LVM_INT16)(ReverbPercentage>>8);  // Reverb Level in Q 15 format
1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVCS_SUCCESS);
1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                LVCS_Reverb                                             */
1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                     */
1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Create reverb using the block of input samples based on the following block     */
1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  diagram:                                                                        */
1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                           ________              ________                         */
1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                          |        |            |        |                        */
1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*     _____     _______    |        |----------->|        |    ______     ___      */
1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*    |     |   |       |   | Stereo |            | L & R  |   |      |   |   |     */
1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* -->| LPF |-->| Delay |-->|   to   |    ____    |   to   |-->| Gain |-->| + |-->  */
1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  | |_____|   |_______|   | L & R  |   |    |   | Stereo |   |______|   |___|     */
1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  |                       |        |-->| -1 |-->|        |                |       */
1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  |                       |________|   |____|   |________|                |       */
1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  |                                                                       |       */
1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  |-----------------------------------------------------------------------|       */
1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  The input buffer is broken in to sub-blocks of the size of the delay or less.   */
1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This allows the delay buffer to be treated as a circular buffer but processed   */
1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  as a linear buffer.                                                             */
1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                      */
1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance               Instance Handle                                         */
1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pInData                 Pointer to the input buffer                             */
1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pOutData                Pointer to the output buffer                            */
1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  NumSamples              Number of samples to process                            */
1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                         */
1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVCS_Success            Always succeeds                                         */
1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                           */
1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  1.  Process in blocks of samples the size of the delay where possible, if not   */
1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      the number of samples left over                                             */
1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  2.  The Gain is combined with the LPF and incorporated in to the coefficients   */
1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t         hInstance,
1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                          const LVM_INT16       *pInData,
1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                          LVM_INT16             *pOutData,
1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                          LVM_UINT16            NumSamples)
1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Instance_t         *pInstance = (LVCS_Instance_t  *)hInstance;
1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_ReverbGenerator_t  *pConfig   = (LVCS_ReverbGenerator_t *)&pInstance->Reverberation;
1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Coefficient_t      *pCoefficients = (LVCS_Coefficient_t *)pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16               *pScratch  = (LVM_INT16 *)pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Copy the data to the output in outplace processing
1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInData != pOutData)
1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Reverb not required so just copy the data
2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16((LVM_INT16 *)pInData,                                       /* Source */
2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16 *)pOutData,                                      /* Destination */
2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(2*NumSamples));                                 /* Left and right */
2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if the reverb is required
2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (((pInstance->Params.SpeakerType == LVCS_HEADPHONE) ||           /* Disable when CS4MS in stereo mode */
2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         (pInstance->Params.SpeakerType == LVCS_EX_HEADPHONES) ||
2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         (pInstance->Params.SourceFormat != LVCS_STEREO))  &&
2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ((pInstance->Params.OperatingMode & LVCS_REVERBSWITCH) !=0))    /* For validation testing */
2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /********************************************************************************/
2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*                                                                              */
2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* Copy the input data to scratch memory and filter it                          */
2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*                                                                              */
2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /********************************************************************************/
2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Copy the input data to the scratch memory
2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16((LVM_INT16 *)pInData,                                     /* Source */
2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16 *)pScratch,                                    /* Destination */
2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(2*NumSamples));                               /* Left and right */
2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Filter the data
2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (pConfig->pBiquadCallBack)((Biquad_Instance_t*)&pCoefficients->ReverbBiquadInstance,
2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                   (LVM_INT16 *)pScratch,
2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                   (LVM_INT16 *)pScratch,
2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                   (LVM_INT16)NumSamples);
2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Mult3s_16x16( (LVM_INT16 *)pScratch,
2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                      pConfig->ReverbLevel,
2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                      (LVM_INT16 *)pScratch,
2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                      (LVM_INT16)(2*NumSamples));
2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Apply the delay mix
2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        DelayMix_16x16((LVM_INT16 *)pScratch,
2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       &pConfig->StereoSamples[0],
2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       pConfig->DelaySize,
2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       pOutData,
2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       &pConfig->DelayOffset,
2532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       (LVM_INT16)NumSamples);
2542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVCS_SUCCESS);
2592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
265