LVCS_Process.c revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
1/* 2 * Copyright (C) 2004-2010 NXP Software 3 * Copyright (C) 2010 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/************************************************************************************ 19 20 $Author: beq07716 $ 21 $Revision: 1001 $ 22 $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $ 23 24*************************************************************************************/ 25 26 27/************************************************************************************/ 28/* */ 29/* Includes */ 30/* */ 31/************************************************************************************/ 32 33#include "LVCS.h" 34#include "LVCS_Private.h" 35#include "VectorArithmetic.h" 36#include "CompLim.h" 37 38/************************************************************************************/ 39/* */ 40/* FUNCTION: LVCS_Process_CS */ 41/* */ 42/* DESCRIPTION: */ 43/* Process function for the Concert Sound module based on the following block */ 44/* diagram: */ 45/* _________ ________ _____ _______ ___ ______ */ 46/* | | | | | | | | | | | | */ 47/* ----->| Stereo |->| Reverb |->| Equ |->| Alpha |-->| + |-| Gain |----> */ 48/* | | Enhance | |________| |_____| |_______| |___| |______| */ 49/* | |_________| | */ 50/* | ___________ | */ 51/* | | | | */ 52/* |------------------------------->| 1 - Alpha |-----| */ 53/* |___________| */ 54/* */ 55/* The Stereo Enhancer, Reverb and Equaliser blocks are each configured to have */ 56/* their gain to give a near peak to peak output (-0.1dBFS) with a worst case */ 57/* input signal. The gains of these blocks are re-combined in the Alpha mixer and */ 58/* the gain block folloing the sum. */ 59/* */ 60/* The processing uses the output buffer for data storage after each processing */ 61/* block. When processing is inplace a copy of the input signal is made in scratch */ 62/* memory for the 1-Alpha path. */ 63/* */ 64/* */ 65/* PARAMETERS: */ 66/* hInstance Instance handle */ 67/* pInData Pointer to the input data */ 68/* pOutData Pointer to the output data */ 69/* NumSamples Number of samples in the input buffer */ 70/* */ 71/* RETURNS: */ 72/* LVCS_Success Succeeded */ 73/* */ 74/* NOTES: */ 75/* */ 76/************************************************************************************/ 77 78LVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t hInstance, 79 const LVM_INT16 *pInData, 80 LVM_INT16 *pOutData, 81 LVM_UINT16 NumSamples) 82{ 83 const LVM_INT16 *pInput; 84 LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 85 LVM_INT16 *pScratch = (LVM_INT16 *)pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress; 86 LVCS_ReturnStatus_en err; 87 88 /* 89 * Check if the processing is inplace 90 */ 91 if (pInData == pOutData) 92 { 93 /* Processing inplace */ 94 pInput = pScratch + (2*NumSamples); 95 Copy_16((LVM_INT16 *)pInData, /* Source */ 96 (LVM_INT16 *)pInput, /* Destination */ 97 (LVM_INT16)(2*NumSamples)); /* Left and right */ 98 } 99 else 100 { 101 /* Processing outplace */ 102 pInput = pInData; 103 } 104 105 /* 106 * Call the stereo enhancer 107 */ 108 err=LVCS_StereoEnhancer(hInstance, /* Instance handle */ 109 pInData, /* Pointer to the input data */ 110 pOutData, /* Pointer to the output data */ 111 NumSamples); /* Number of samples to process */ 112 113 /* 114 * Call the reverb generator 115 */ 116 err=LVCS_ReverbGenerator(hInstance, /* Instance handle */ 117 pOutData, /* Pointer to the input data */ 118 pOutData, /* Pointer to the output data */ 119 NumSamples); /* Number of samples to process */ 120 121 /* 122 * Call the equaliser 123 */ 124 err=LVCS_Equaliser(hInstance, /* Instance handle */ 125 pOutData, /* Pointer to the input data */ 126 NumSamples); /* Number of samples to process */ 127 128 /* 129 * Call the bypass mixer 130 */ 131 err=LVCS_BypassMixer(hInstance, /* Instance handle */ 132 pOutData, /* Pointer to the processed data */ 133 pInput, /* Pointer to the input (unprocessed) data */ 134 pOutData, /* Pointer to the output data */ 135 NumSamples); /* Number of samples to process */ 136 137 if(err !=LVCS_SUCCESS) 138 { 139 return err; 140 } 141 142 return(LVCS_SUCCESS); 143} 144 145/************************************************************************************/ 146/* */ 147/* FUNCTION: LVCS_Process */ 148/* */ 149/* DESCRIPTION: */ 150/* Process function for the Concert Sound module. The implementation supports two */ 151/* variants of the algorithm, one for headphones and one for mobile speakers. */ 152/* */ 153/* Data can be processed in two formats, stereo or mono-in-stereo. Data in mono */ 154/* format is not supported, the calling routine must convert the mono stream to */ 155/* mono-in-stereo. */ 156/* */ 157/* */ 158/* PARAMETERS: */ 159/* hInstance Instance handle */ 160/* pInData Pointer to the input data */ 161/* pOutData Pointer to the output data */ 162/* NumSamples Number of samples in the input buffer */ 163/* */ 164/* RETURNS: */ 165/* LVCS_Success Succeeded */ 166/* LVCS_TooManySamples NumSamples was larger than the maximum block size */ 167/* */ 168/* NOTES: */ 169/* */ 170/************************************************************************************/ 171 172LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance, 173 const LVM_INT16 *pInData, 174 LVM_INT16 *pOutData, 175 LVM_UINT16 NumSamples) 176{ 177 178 LVCS_Instance_t *pInstance =(LVCS_Instance_t *)hInstance; 179 LVCS_ReturnStatus_en err; 180 181 /* 182 * Check the number of samples is not too large 183 */ 184 if (NumSamples > pInstance->Capabilities.MaxBlockSize) 185 { 186 return(LVCS_TOOMANYSAMPLES); 187 } 188 189 /* 190 * Check if the algorithm is enabled 191 */ 192 if (pInstance->Params.OperatingMode != LVCS_OFF) 193 { 194 /* 195 * Call CS process function 196 */ 197 err=LVCS_Process_CS(hInstance, 198 pInData, 199 pOutData, 200 NumSamples); 201 202 /* 203 * Compress to reduce expansion effect of Concert Sound and correct volume 204 * differences for difference settings. Not applied in test modes 205 */ 206 if ((pInstance->Params.OperatingMode == LVCS_ON)&&(pInstance->Params.CompressorMode == LVM_MODE_ON)) 207 { 208 LVM_INT16 Gain = pInstance->VolCorrect.CompMin; 209 LVM_INT32 Current1; 210 211 Current1 = LVC_Mixer_GetCurrent(&pInstance->BypassMix.Mixer_Instance.MixerStream[0]); 212 Gain = (LVM_INT16)( pInstance->VolCorrect.CompMin 213 - (((LVM_INT32)pInstance->VolCorrect.CompMin * (Current1)) >> 15) 214 + (((LVM_INT32)pInstance->VolCorrect.CompFull * (Current1)) >> 15) ); 215 216 NonLinComp_D16(Gain, /* Compressor gain setting */ 217 pOutData, 218 pOutData, 219 (LVM_INT32)(2*NumSamples)); 220 } 221 222 223 if(pInstance->bInOperatingModeTransition == LVM_TRUE){ 224 225 /* 226 * Re-init bypass mix when timer has completed 227 */ 228 if ((pInstance->bTimerDone == LVM_TRUE) && 229 (pInstance->BypassMix.Mixer_Instance.MixerStream[1].CallbackSet == 0)) 230 { 231 err=LVCS_BypassMixInit(hInstance, 232 &pInstance->Params); 233 234 if(err != LVCS_SUCCESS) 235 { 236 return err; 237 } 238 239 } 240 else{ 241 LVM_Timer ( &pInstance->TimerInstance, 242 (LVM_INT16)NumSamples); 243 } 244 } 245 } 246 else 247 { 248 if (pInData != pOutData) 249 { 250 /* 251 * The algorithm is disabled so just copy the data 252 */ 253 Copy_16((LVM_INT16 *)pInData, /* Source */ 254 (LVM_INT16 *)pOutData, /* Destination */ 255 (LVM_INT16)(2*NumSamples)); /* Left and right */ 256 } 257 } 258 259 260 return(LVCS_SUCCESS); 261} 262 263 264 265 266 267 268 269 270 271 272