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