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/************************************************************************************/ 69d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#ifdef BUILD_FLOAT 70d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh KaturiLVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t hInstance, 71d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri const LVM_FLOAT *pInData, 72d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT *pOutData, 73d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_UINT16 NumSamples) 74d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri{ 75d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri const LVM_FLOAT *pInput; 76d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 77d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT *pScratch; 78d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVCS_ReturnStatus_en err; 79d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 80d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pScratch = (LVM_FLOAT *) \ 81d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress; 822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 83d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 84d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Check if the processing is inplace 85d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 86d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if (pInData == pOutData) 87d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 88d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* Processing inplace */ 89d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInput = pScratch + (2 * NumSamples); 90d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Copy_Float((LVM_FLOAT *)pInData, /* Source */ 91d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_FLOAT *)pInput, /* Destination */ 92d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_INT16)(2 * NumSamples)); /* Left and right */ 93d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 94d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri else 95d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 96d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* Processing outplace */ 97d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInput = pInData; 98d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 99d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 100d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 101d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Call the stereo enhancer 102d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 103d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri err = LVCS_StereoEnhancer(hInstance, /* Instance handle */ 104d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInData, /* Pointer to the input data */ 105d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, /* Pointer to the output data */ 106d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NumSamples); /* Number of samples to process */ 107d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 108d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 109d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Call the reverb generator 110d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 111d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri err = LVCS_ReverbGenerator(hInstance, /* Instance handle */ 112d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, /* Pointer to the input data */ 113d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, /* Pointer to the output data */ 114d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NumSamples); /* Number of samples to process */ 115d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 116d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 117d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Call the equaliser 118d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 119d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri err = LVCS_Equaliser(hInstance, /* Instance handle */ 120d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, /* Pointer to the input data */ 121d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NumSamples); /* Number of samples to process */ 122d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 123d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 124d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Call the bypass mixer 125d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 126d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri err = LVCS_BypassMixer(hInstance, /* Instance handle */ 127d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, /* Pointer to the processed data */ 128d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInput, /* Pointer to the input (unprocessed) data */ 129d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, /* Pointer to the output data */ 130d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NumSamples); /* Number of samples to process */ 131d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 132d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if(err != LVCS_SUCCESS) 133d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 134d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri return err; 135d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 136d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 137d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri return(LVCS_SUCCESS); 138d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri} 139d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#else 1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t hInstance, 1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent const LVM_INT16 *pInData, 1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pOutData, 1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT16 NumSamples) 1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent const LVM_INT16 *pInput; 1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pScratch = (LVM_INT16 *)pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress; 1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_ReturnStatus_en err; 1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Check if the processing is inplace 1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (pInData == pOutData) 1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Processing inplace */ 1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pInput = pScratch + (2*NumSamples); 1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Copy_16((LVM_INT16 *)pInData, /* Source */ 1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)pInput, /* Destination */ 1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)(2*NumSamples)); /* Left and right */ 1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Processing outplace */ 1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pInput = pInData; 1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Call the stereo enhancer 1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent err=LVCS_StereoEnhancer(hInstance, /* Instance handle */ 1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pInData, /* Pointer to the input data */ 1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, /* Pointer to the output data */ 1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent NumSamples); /* Number of samples to process */ 1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Call the reverb generator 1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent err=LVCS_ReverbGenerator(hInstance, /* Instance handle */ 1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, /* Pointer to the input data */ 1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, /* Pointer to the output data */ 1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent NumSamples); /* Number of samples to process */ 1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Call the equaliser 1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent err=LVCS_Equaliser(hInstance, /* Instance handle */ 1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, /* Pointer to the input data */ 1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent NumSamples); /* Number of samples to process */ 1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Call the bypass mixer 1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent err=LVCS_BypassMixer(hInstance, /* Instance handle */ 1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, /* Pointer to the processed data */ 1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pInput, /* Pointer to the input (unprocessed) data */ 1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, /* Pointer to the output data */ 1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent NumSamples); /* Number of samples to process */ 1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(err !=LVCS_SUCCESS) 2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return err; 2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVCS_SUCCESS); 2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 206d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#endif 2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION: LVCS_Process */ 2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION: */ 2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Process function for the Concert Sound module. The implementation supports two */ 2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* variants of the algorithm, one for headphones and one for mobile speakers. */ 2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Data can be processed in two formats, stereo or mono-in-stereo. Data in mono */ 2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* format is not supported, the calling routine must convert the mono stream to */ 2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* mono-in-stereo. */ 2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS: */ 2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* hInstance Instance handle */ 2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pInData Pointer to the input data */ 2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pOutData Pointer to the output data */ 2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NumSamples Number of samples in the input buffer */ 2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS: */ 2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* LVCS_Success Succeeded */ 2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* LVCS_TooManySamples NumSamples was larger than the maximum block size */ 2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES: */ 2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 233d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#ifdef BUILD_FLOAT 234d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh KaturiLVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance, 235d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri const LVM_FLOAT *pInData, 236d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT *pOutData, 237d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_UINT16 NumSamples) 238d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri{ 2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 240d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 241d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVCS_ReturnStatus_en err; 242d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 243d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 244d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Check the number of samples is not too large 245d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 246d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if (NumSamples > pInstance->Capabilities.MaxBlockSize) 247d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 248d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri return(LVCS_TOOMANYSAMPLES); 249d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 250d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 251d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 252d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Check if the algorithm is enabled 253d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 254d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if (pInstance->Params.OperatingMode != LVCS_OFF) 255d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 256d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 257d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Call CS process function 258d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 259d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri err = LVCS_Process_CS(hInstance, 260d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInData, 261d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, 262d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NumSamples); 263d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 264d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 265d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 266d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Compress to reduce expansion effect of Concert Sound and correct volume 267d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * differences for difference settings. Not applied in test modes 268d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 269d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if ((pInstance->Params.OperatingMode == LVCS_ON)&& \ 270d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (pInstance->Params.CompressorMode == LVM_MODE_ON)) 271d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 272d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT Gain = pInstance->VolCorrect.CompMin; 273d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT Current1; 274d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 275d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Current1 = LVC_Mixer_GetCurrent(&pInstance->BypassMix.Mixer_Instance.MixerStream[0]); 276d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Gain = (LVM_FLOAT)( pInstance->VolCorrect.CompMin 277d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri - (((LVM_FLOAT)pInstance->VolCorrect.CompMin * (Current1))) 278d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri + (((LVM_FLOAT)pInstance->VolCorrect.CompFull * (Current1)))); 279d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 280d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if(NumSamples < LVCS_COMPGAINFRAME) 281d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 282d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NonLinComp_Float(Gain, /* Compressor gain setting */ 283d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, 284d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutData, 285d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_INT32)(2 * NumSamples)); 286d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 287d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri else 288d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 289d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT GainStep; 290d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT FinalGain; 291d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_INT16 SampleToProcess = NumSamples; 292d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_FLOAT *pOutPtr; 293d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 294d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* Large changes in Gain can cause clicks in output 295d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Split data into small blocks and use interpolated gain values */ 296d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 297d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri GainStep = (LVM_FLOAT)(((Gain-pInstance->CompressGain) * \ 298d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVCS_COMPGAINFRAME) / NumSamples); 299d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 300d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if((GainStep == 0) && (pInstance->CompressGain < Gain)) 301d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 302d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri GainStep = 1; 303d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 304d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri else 305d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 306d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if((GainStep == 0) && (pInstance->CompressGain > Gain)) 307d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 308d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri GainStep = -1; 309d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 310d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 311d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 312d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri FinalGain = Gain; 313d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Gain = pInstance->CompressGain; 314d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutPtr = pOutData; 315d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 316d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri while(SampleToProcess > 0) 317d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 318d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Gain = (LVM_FLOAT)(Gain + GainStep); 319d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if((GainStep > 0) && (FinalGain <= Gain)) 320d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 321d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Gain = FinalGain; 322d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri GainStep = 0; 323d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 324d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 325d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if((GainStep < 0) && (FinalGain > Gain)) 326d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 327d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Gain = FinalGain; 328d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri GainStep = 0; 329d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 330d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 331d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if(SampleToProcess > LVCS_COMPGAINFRAME) 332d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 333d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NonLinComp_Float(Gain, /* Compressor gain setting */ 334d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutPtr, 335d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutPtr, 336d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_INT32)(2 * LVCS_COMPGAINFRAME)); 337d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutPtr += (2 * LVCS_COMPGAINFRAME); 338d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri SampleToProcess = (LVM_INT16)(SampleToProcess - LVCS_COMPGAINFRAME); 339d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 340d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri else 341d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 342d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri NonLinComp_Float(Gain, /* Compressor gain setting */ 343d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutPtr, 344d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pOutPtr, 345d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_INT32)(2 * SampleToProcess)); 346d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri SampleToProcess = 0; 347d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 348d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 349d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 350d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 351d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 352d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* Store gain value*/ 353d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri pInstance->CompressGain = Gain; 354d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 355d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 356d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 357d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if(pInstance->bInOperatingModeTransition == LVM_TRUE){ 358d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 359d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 360d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * Re-init bypass mix when timer has completed 361d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 362d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if ((pInstance->bTimerDone == LVM_TRUE) && 363d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (pInstance->BypassMix.Mixer_Instance.MixerStream[1].CallbackSet == 0)) 364d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 365d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri err = LVCS_BypassMixInit(hInstance, 366d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri &pInstance->Params); 367d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 368d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if(err != LVCS_SUCCESS) 369d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 370d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri return err; 371d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 372d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 373d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 374d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri else{ 375d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri LVM_Timer ( &pInstance->TimerInstance, 376d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_INT16)NumSamples); 377d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 378d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 379d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 380d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri else 381d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 382d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri if (pInData != pOutData) 383d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri { 384d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri /* 385d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri * The algorithm is disabled so just copy the data 386d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri */ 387d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri Copy_Float((LVM_FLOAT *)pInData, /* Source */ 388d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_FLOAT *)pOutData, /* Destination */ 389d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri (LVM_INT16)(2 * NumSamples)); /* Left and right */ 390d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 391d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri } 392d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 393d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri 394d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri return(LVCS_SUCCESS); 395d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri} 396d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#else 3972c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t hInstance, 3982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent const LVM_INT16 *pInData, 3992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pOutData, 4002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT16 NumSamples) 4012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 4022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 4032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_Instance_t *pInstance =(LVCS_Instance_t *)hInstance; 4042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVCS_ReturnStatus_en err; 4052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 4062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 4072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Check the number of samples is not too large 4082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 4092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (NumSamples > pInstance->Capabilities.MaxBlockSize) 4102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 4112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVCS_TOOMANYSAMPLES); 4122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 4132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 4142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 4152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Check if the algorithm is enabled 4162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 4172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (pInstance->Params.OperatingMode != LVCS_OFF) 4182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 4192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 4202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Call CS process function 4212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 4222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent err=LVCS_Process_CS(hInstance, 4232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pInData, 4242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pOutData, 4252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent NumSamples); 4262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 4272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 4282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Compress to reduce expansion effect of Concert Sound and correct volume 4292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * differences for difference settings. Not applied in test modes 4302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 4312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if ((pInstance->Params.OperatingMode == LVCS_ON)&&(pInstance->Params.CompressorMode == LVM_MODE_ON)) 4322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 4332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 Gain = pInstance->VolCorrect.CompMin; 4342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT32 Current1; 4352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 4362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Current1 = LVC_Mixer_GetCurrent(&pInstance->BypassMix.Mixer_Instance.MixerStream[0]); 4372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Gain = (LVM_INT16)( pInstance->VolCorrect.CompMin 4382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent - (((LVM_INT32)pInstance->VolCorrect.CompMin * (Current1)) >> 15) 4392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent + (((LVM_INT32)pInstance->VolCorrect.CompFull * (Current1)) >> 15) ); 4402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 441d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent if(NumSamples < LVCS_COMPGAINFRAME) 442d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 443d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent NonLinComp_D16(Gain, /* Compressor gain setting */ 444d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutData, 445d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutData, 446d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent (LVM_INT32)(2*NumSamples)); 447d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 448d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent else 449d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 450d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent LVM_INT16 GainStep; 451d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent LVM_INT16 FinalGain; 452d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent LVM_INT16 SampleToProcess = NumSamples; 453d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent LVM_INT16 *pOutPtr; 454d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 455d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent /* Large changes in Gain can cause clicks in output 456d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent Split data into small blocks and use interpolated gain values */ 457d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 458d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent GainStep = (LVM_INT16)(((Gain-pInstance->CompressGain) * LVCS_COMPGAINFRAME)/NumSamples); 459d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 460d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent if((GainStep ==0)&&(pInstance->CompressGain < Gain)) 461d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 462d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent GainStep=1; 463d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 464d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent else 465d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 466d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent if((GainStep ==0)&&(pInstance->CompressGain > Gain)) 467d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 468d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent GainStep=-1; 469d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 470d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 471d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 472d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent FinalGain = Gain; 473d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent Gain = pInstance->CompressGain; 474d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutPtr = pOutData; 475d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 476d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent while(SampleToProcess > 0) 477d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 478d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent Gain = (LVM_INT16)(Gain + GainStep); 479d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent if((GainStep > 0)&& (FinalGain <= Gain)) 480d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 481d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent Gain = FinalGain; 482d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent GainStep =0; 483d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 484d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 485d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent if((GainStep < 0)&& (FinalGain > Gain)) 486d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 487d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent Gain = FinalGain; 488d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent GainStep =0; 489d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 490d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 491d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent if(SampleToProcess > LVCS_COMPGAINFRAME) 492d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 493d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent NonLinComp_D16(Gain, /* Compressor gain setting */ 494d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutPtr, 495d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutPtr, 496d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent (LVM_INT32)(2*LVCS_COMPGAINFRAME)); 497d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutPtr +=(2*LVCS_COMPGAINFRAME); 498d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent SampleToProcess = (LVM_INT16)(SampleToProcess-LVCS_COMPGAINFRAME); 499d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 500d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent else 501d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent { 502d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent NonLinComp_D16(Gain, /* Compressor gain setting */ 503d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutPtr, 504d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pOutPtr, 505d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent (LVM_INT32)(2*SampleToProcess)); 506d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 507d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent SampleToProcess = 0; 508d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 509d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 510d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 511d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent } 512d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent 513d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent /* Store gain value*/ 514d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent pInstance->CompressGain = Gain; 5152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(pInstance->bInOperatingModeTransition == LVM_TRUE){ 5192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 5212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Re-init bypass mix when timer has completed 5222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 5232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if ((pInstance->bTimerDone == LVM_TRUE) && 5242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (pInstance->BypassMix.Mixer_Instance.MixerStream[1].CallbackSet == 0)) 5252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 5262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent err=LVCS_BypassMixInit(hInstance, 5272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent &pInstance->Params); 5282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(err != LVCS_SUCCESS) 5302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 5312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return err; 5322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else{ 5362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_Timer ( &pInstance->TimerInstance, 5372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)NumSamples); 5382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 5422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 5432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (pInData != pOutData) 5442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 5452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 5462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * The algorithm is disabled so just copy the data 5472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 5482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Copy_16((LVM_INT16 *)pInData, /* Source */ 5492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16 *)pOutData, /* Destination */ 5502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)(2*NumSamples)); /* Left and right */ 5512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 5532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 5552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVCS_SUCCESS); 5562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 557d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#endif 558