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