LVCS_StereoEnhancer.c revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
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 $Author: beq07716 $ 212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent $Revision: 1001 $ 222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $ 232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent*************************************************************************************/ 252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Includes */ 292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS.h" 332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_Private.h" 342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_StereoEnhancer.h" 352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "VectorArithmetic.h" 362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVCS_Tables.h" 372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION: LVCS_StereoEnhanceInit */ 412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION: */ 432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Initialises the stereo enhancement module based on the sample rate. */ 442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* The function selects the coefficients for the filters and clears the data */ 462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* history. It is also used for re-initialisation when one of the system control */ 472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* parameters changes but will only change the coefficients and clear the history */ 482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* if the sample rate or speaker type has changed. */ 492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS: */ 512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* hInstance Instance Handle */ 522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pParams Initialisation parameters */ 532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS: */ 552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* LVCS_Success Always succeeds */ 562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES: */ 582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 612c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t hInstance, 622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Params_t *pParams) 632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT16 Offset; 662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_StereoEnhancer_t *pConfig = (LVCS_StereoEnhancer_t *)&pInstance->StereoEnhancer; 682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Data_t *pData = (LVCS_Data_t *)pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress; 692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Coefficient_t *pCoefficient = (LVCS_Coefficient_t *)pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress; 702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent FO_C16_Coefs_t CoeffsMid; 712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent BQ_C16_Coefs_t CoeffsSide; 722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent const BiquadA012B12CoefsSP_t *pSESideCoefs; 732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * If the sample rate or speaker type has changed update the filters 762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if ((pInstance->Params.SampleRate != pParams->SampleRate) || 782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (pInstance->Params.SpeakerType != pParams->SpeakerType)) 792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Set the filter coefficients based on the sample rate 822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Mid filter */ 842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Offset = (LVM_UINT16)pParams->SampleRate; 852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Convert incoming coefficients to the required format/ordering */ 872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsMid.A0 = (LVM_INT16) LVCS_SEMidCoefTable[Offset].A0; 882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsMid.A1 = (LVM_INT16) LVCS_SEMidCoefTable[Offset].A1; 892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsMid.B1 = (LVM_INT16)-LVCS_SEMidCoefTable[Offset].B1; 902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Clear the taps */ 922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LoadConst_16(0, /* Value */ 932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)&pData->SEBiquadTapsMid, /* Destination */ 942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_UINT16)(sizeof(pData->SEBiquadTapsMid)/sizeof(LVM_UINT16))); /* Number of words */ 952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent FO_1I_D16F16Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceMid, 972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &pData->SEBiquadTapsMid, 982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &CoeffsMid); 992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Callbacks */ 1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(LVCS_SEMidCoefTable[Offset].Scale==15) 1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pConfig->pBiquadCallBack_Mid = FO_1I_D16F16C15_TRC_WRA_01; 1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Offset = (LVM_UINT16)(pParams->SampleRate); 1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pSESideCoefs = (BiquadA012B12CoefsSP_t*)&LVCS_SESideCoefTable[0]; 1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Side filter */ 1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Convert incoming coefficients to the required format/ordering */ 1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsSide.A0 = (LVM_INT16) pSESideCoefs[Offset].A0; 1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsSide.A1 = (LVM_INT16) pSESideCoefs[Offset].A1; 1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsSide.A2 = (LVM_INT16) pSESideCoefs[Offset].A2; 1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsSide.B1 = (LVM_INT16)-pSESideCoefs[Offset].B1; 1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CoeffsSide.B2 = (LVM_INT16)-pSESideCoefs[Offset].B2; 1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Clear the taps */ 1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LoadConst_16(0, /* Value */ 1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)&pData->SEBiquadTapsSide, /* Destination */ 1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_UINT16)(sizeof(pData->SEBiquadTapsSide)/sizeof(LVM_UINT16))); /* Number of words */ 1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Callbacks */ 1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent switch(pSESideCoefs[Offset].Scale) 1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent case 14: 1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent BQ_1I_D16F32Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceSide, 1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &pData->SEBiquadTapsSide, 1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &CoeffsSide); 1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pConfig->pBiquadCallBack_Side = BQ_1I_D16F32C14_TRC_WRA_01; 1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent break; 1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent case 15: 1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent BQ_1I_D16F16Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceSide, 1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &pData->SEBiquadTapsSide, 1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &CoeffsSide); 1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pConfig->pBiquadCallBack_Side = BQ_1I_D16F16C15_TRC_WRA_01; 1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent break; 1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVCS_SUCCESS); 1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION: LVCS_StereoEnhance */ 1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION: */ 1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Enhance the stereo image in the input samples based on the following block */ 1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* diagram: */ 1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* ________ */ 1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* ________ | | ________ */ 1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* | | Middle | Treble | | | */ 1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* | |---------->| Boost |-------->| | */ 1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* | Stereo | |________| | M & S | */ 1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* -->| to | ________ | to |--> */ 1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* | M & S | Side | | | Stereo | */ 1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* | |---------->| Side |-------->| | */ 1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* |________| | Boost | |________| */ 1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* |________| */ 1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* If the input signal is a mono signal there will be no side signal and hence */ 1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* the side filter will not be run. In mobile speaker mode the middle filter is */ 1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* not required and the Trebble boost filter is replaced by a simple gain block. */ 1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS: */ 1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* hInstance Instance Handle */ 1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pInData Pointer to the input data */ 1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pOutData Pointer to the output data */ 1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NumSamples Number of samples to process */ 1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS: */ 1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* LVCS_Success Always succeeds */ 1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES: */ 1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 1. The side filter is not used in Mobile Speaker mode */ 1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t hInstance, 1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent const LVM_INT16 *pInData, 1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pOutData, 1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT16 NumSamples) 1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_StereoEnhancer_t *pConfig = (LVCS_StereoEnhancer_t *)&pInstance->StereoEnhancer; 1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Coefficient_t *pCoefficient = (LVCS_Coefficient_t *)pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress; 1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pScratch = (LVM_INT16 *)pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress; 1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Check if the Stereo Enhancer is enabled 2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if ((pInstance->Params.OperatingMode & LVCS_STEREOENHANCESWITCH) != 0) 2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Convert from stereo to middle and side 2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent From2iToMS_16x16(pInData, 2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch, 2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch+NumSamples, 2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)NumSamples); 2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Apply filter to the middle signal 2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (pInstance->OutputDevice == LVCS_HEADPHONE) 2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (pConfig->pBiquadCallBack_Mid)((Biquad_Instance_t*)&pCoefficient->SEBiquadInstanceMid, 2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)pScratch, 2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)pScratch, 2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)NumSamples); 2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Mult3s_16x16(pScratch, /* Source */ 2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)pConfig->MidGain, /* Gain */ 2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch, /* Destination */ 2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)NumSamples); /* Number of samples */ 2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Apply the filter the side signal only in stereo mode for headphones 2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * and in all modes for mobile speakers 2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (pInstance->Params.SourceFormat == LVCS_STEREO) 2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (pConfig->pBiquadCallBack_Side)((Biquad_Instance_t*)&pCoefficient->SEBiquadInstanceSide, 2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)(pScratch + NumSamples), 2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)(pScratch + NumSamples), 2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)NumSamples); 2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Convert from middle and side to stereo 2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent MSTo2i_Sat_16x16(pScratch, 2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch+NumSamples, 2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, 2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)NumSamples); 2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 2532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * The stereo enhancer is disabled so just copy the data 2542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 2552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Copy_16((LVM_INT16 *)pInData, /* Source */ 2562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)pOutData, /* Destination */ 2572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)(2*NumSamples)); /* Left and right */ 2582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVCS_SUCCESS); 2622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 2632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 267