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 "LVCS.h"
262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_Private.h"
272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "VectorArithmetic.h"
282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "CompLim.h"
292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                LVCS_Process_CS                                         */
332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                     */
352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Process function for the Concert Sound module based on the following block      */
362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  diagram:                                                                        */
372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*            _________    ________    _____    _______     ___   ______            */
382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*           |         |  |        |  |     |  |       |   |   | |      |           */
392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*     ----->| Stereo  |->| Reverb |->| Equ |->| Alpha |-->| + |-| Gain |---->      */
402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        |  | Enhance |  |________|  |_____|  |_______|   |___| |______|           */
412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        |  |_________|                                     |                      */
422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        |                                 ___________      |                      */
432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        |                                |           |     |                      */
442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*        |------------------------------->| 1 - Alpha |-----|                      */
452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                         |___________|                            */
462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  The Stereo Enhancer, Reverb and Equaliser blocks are each configured to have    */
482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  their gain to give a near peak to peak output (-0.1dBFS) with a worst case      */
492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  input signal. The gains of these blocks are re-combined in the Alpha mixer and  */
502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  the gain block folloing the sum.                                                */
512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  The processing uses the output buffer for data storage after each processing    */
532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  block. When processing is inplace a copy of the input signal is made in scratch */
542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  memory for the 1-Alpha path.                                                    */
552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                      */
582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance               Instance handle                                         */
592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pInData                 Pointer to the input data                               */
602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pOutData                Pointer to the output data                              */
612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  NumSamples              Number of samples in the input buffer                   */
622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                         */
642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVCS_Success            Succeeded                                               */
652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                           */
672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
702c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t              hInstance,
712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                     const LVM_INT16            *pInData,
722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                     LVM_INT16                  *pOutData,
732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                     LVM_UINT16                 NumSamples)
742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    const LVM_INT16     *pInput;
762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16           *pScratch  = (LVM_INT16 *)pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_ReturnStatus_en err;
792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if the processing is inplace
822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInData == pOutData)
842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* Processing inplace */
862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInput = pScratch + (2*NumSamples);
872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        Copy_16((LVM_INT16 *)pInData,           /* Source */
882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16 *)pInput,            /* Destination */
892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(2*NumSamples));     /* Left and right */
902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* Processing outplace */
942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pInput = pInData;
952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Call the stereo enhancer
992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    err=LVCS_StereoEnhancer(hInstance,              /* Instance handle */
1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                        pInData,                    /* Pointer to the input data */
1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                        pOutData,                   /* Pointer to the output data */
1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                        NumSamples);                /* Number of samples to process */
1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Call the reverb generator
1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    err=LVCS_ReverbGenerator(hInstance,             /* Instance handle */
1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         pOutData,                  /* Pointer to the input data */
1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         pOutData,                  /* Pointer to the output data */
1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                         NumSamples);               /* Number of samples to process */
1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Call the equaliser
1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    err=LVCS_Equaliser(hInstance,                   /* Instance handle */
1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   pOutData,                        /* Pointer to the input data */
1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   NumSamples);                     /* Number of samples to process */
1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Call the bypass mixer
1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    err=LVCS_BypassMixer(hInstance,                 /* Instance handle */
1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     pOutData,                      /* Pointer to the processed data */
1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     pInput,                        /* Pointer to the input (unprocessed) data */
1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     pOutData,                      /* Pointer to the output data */
1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                     NumSamples);                   /* Number of samples to process */
1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(err !=LVCS_SUCCESS)
1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return err;
1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVCS_SUCCESS);
1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                LVCS_Process                                            */
1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                     */
1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Process function for the Concert Sound module. The implementation supports two  */
1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  variants of the algorithm, one for headphones and one for mobile speakers.      */
1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Data can be processed in two formats, stereo or mono-in-stereo. Data in mono    */
1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  format is not supported, the calling routine must convert the mono stream to    */
1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  mono-in-stereo.                                                                 */
1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                      */
1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance               Instance handle                                         */
1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pInData                 Pointer to the input data                               */
1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pOutData                Pointer to the output data                              */
1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  NumSamples              Number of samples in the input buffer                   */
1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                         */
1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVCS_Success            Succeeded                                               */
1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVCS_TooManySamples     NumSamples was larger than the maximum block size       */
1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                           */
1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t             hInstance,
1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                  const LVM_INT16           *pInData,
1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                  LVM_INT16                 *pOutData,
1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                  LVM_UINT16                NumSamples)
1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_Instance_t *pInstance =(LVCS_Instance_t  *)hInstance;
1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVCS_ReturnStatus_en err;
1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check the number of samples is not too large
1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return(LVCS_TOOMANYSAMPLES);
1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check if the algorithm is enabled
1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pInstance->Params.OperatingMode != LVCS_OFF)
1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Call CS process function
1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            err=LVCS_Process_CS(hInstance,
1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pInData,
1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pOutData,
1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            NumSamples);
1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Compress to reduce expansion effect of Concert Sound and correct volume
1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * differences for difference settings. Not applied in test modes
1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if ((pInstance->Params.OperatingMode == LVCS_ON)&&(pInstance->Params.CompressorMode == LVM_MODE_ON))
1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            LVM_INT16 Gain = pInstance->VolCorrect.CompMin;
2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            LVM_INT32 Current1;
2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Current1 = LVC_Mixer_GetCurrent(&pInstance->BypassMix.Mixer_Instance.MixerStream[0]);
2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Gain = (LVM_INT16)(  pInstance->VolCorrect.CompMin
2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                               - (((LVM_INT32)pInstance->VolCorrect.CompMin  * (Current1)) >> 15)
2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                               + (((LVM_INT32)pInstance->VolCorrect.CompFull * (Current1)) >> 15) );
2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
208d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            if(NumSamples < LVCS_COMPGAINFRAME)
209d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            {
210d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                NonLinComp_D16(Gain,                    /* Compressor gain setting */
211d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    pOutData,
212d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    pOutData,
213d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    (LVM_INT32)(2*NumSamples));
214d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            }
215d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            else
216d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            {
217d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                LVM_INT16  GainStep;
218d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                LVM_INT16  FinalGain;
219d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                LVM_INT16  SampleToProcess = NumSamples;
220d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                LVM_INT16  *pOutPtr;
221d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
222d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                /* Large changes in Gain can cause clicks in output
223d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                   Split data into small blocks and use interpolated gain values */
224d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
225d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                GainStep = (LVM_INT16)(((Gain-pInstance->CompressGain) * LVCS_COMPGAINFRAME)/NumSamples);
226d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
227d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                if((GainStep ==0)&&(pInstance->CompressGain < Gain))
228d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                {
229d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    GainStep=1;
230d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                }
231d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                else
232d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                {
233d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    if((GainStep ==0)&&(pInstance->CompressGain > Gain))
234d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    {
235d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        GainStep=-1;
236d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    }
237d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                }
238d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
239d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                FinalGain = Gain;
240d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                Gain = pInstance->CompressGain;
241d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                pOutPtr = pOutData;
242d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
243d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                while(SampleToProcess > 0)
244d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                {
245d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    Gain = (LVM_INT16)(Gain + GainStep);
246d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    if((GainStep > 0)&& (FinalGain <= Gain))
247d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    {
248d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        Gain = FinalGain;
249d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        GainStep =0;
250d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    }
251d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
252d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    if((GainStep < 0)&& (FinalGain > Gain))
253d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    {
254d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        Gain = FinalGain;
255d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        GainStep =0;
256d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    }
257d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
258d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    if(SampleToProcess > LVCS_COMPGAINFRAME)
259d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    {
260d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        NonLinComp_D16(Gain,                    /* Compressor gain setting */
261d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                            pOutPtr,
262d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                            pOutPtr,
263d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                            (LVM_INT32)(2*LVCS_COMPGAINFRAME));
264d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        pOutPtr +=(2*LVCS_COMPGAINFRAME);
265d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        SampleToProcess = (LVM_INT16)(SampleToProcess-LVCS_COMPGAINFRAME);
266d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    }
267d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    else
268d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    {
269d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        NonLinComp_D16(Gain,                    /* Compressor gain setting */
270d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                            pOutPtr,
271d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                            pOutPtr,
272d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                            (LVM_INT32)(2*SampleToProcess));
273d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
274d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                        SampleToProcess = 0;
275d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                    }
276d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
277d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent                }
278d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            }
279d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
280d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            /* Store gain value*/
281d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent            pInstance->CompressGain = Gain;
2822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if(pInstance->bInOperatingModeTransition == LVM_TRUE){
2862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
2882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * Re-init bypass mix when timer has completed
2892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
2902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            if ((pInstance->bTimerDone == LVM_TRUE) &&
2912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (pInstance->BypassMix.Mixer_Instance.MixerStream[1].CallbackSet == 0))
2922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            {
2932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                err=LVCS_BypassMixInit(hInstance,
2942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                   &pInstance->Params);
2952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                if(err != LVCS_SUCCESS)
2972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                {
2982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    return err;
2992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                }
3002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            }
3022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            else{
3032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                LVM_Timer ( &pInstance->TimerInstance,
3042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            (LVM_INT16)NumSamples);
3052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            }
3062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
3092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pInData != pOutData)
3112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*
3132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             * The algorithm is disabled so just copy the data
3142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent             */
3152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            Copy_16((LVM_INT16 *)pInData,               /* Source */
3162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16 *)pOutData,                  /* Destination */
3172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (LVM_INT16)(2*NumSamples));             /* Left and right */
3182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVCS_SUCCESS);
3232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
3242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
334