NonLinComp_D16.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: 1000 $ 22 $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $ 23 24***********************************************************************************/ 25 26/****************************************************************************************/ 27/* */ 28/* Includes */ 29/* */ 30/****************************************************************************************/ 31 32#include "CompLim_private.h" 33 34/****************************************************************************************/ 35/* */ 36/* FUNCTION: NonLinComp_D16 */ 37/* */ 38/* DESCRIPTION: */ 39/* Non-linear compression by companding. The function works on a sample by sample */ 40/* basis by increasing the level near the zero crossing. This gives a ttrade-off */ 41/* between THD and compression. It uses the equation: */ 42/* */ 43/* Output = Input + K * (Input - Input^2) if Input > 0 */ 44/* = Input + K * (Input + Input^2) if Input <= 0 */ 45/* */ 46/* The value of K controls the amount of compression and as a side effect the amount */ 47/* distortion introduced. The amount of compression is signal dependent and the values */ 48/* given below are approximate. */ 49/* */ 50/* Gain (fractional) Gain (integer) Compression Pk-Pk THD */ 51/* 1.0 32767 +6dB 16dB */ 52/* 0.78 25559 +5dB 19dB */ 53/* 0.6 19661 +4dB 21dB */ 54/* 0.41 13435 +3dB 24dB */ 55/* 0.26 8520 +2dB 28dB */ 56/* 0.12 3932 +1dB 34dB */ 57/* 0.0 0 +0dB 98dB */ 58/* */ 59/* PARAMETERS: */ 60/* Gain - compression control parameter */ 61/* pDataIn - pointer to the input data buffer */ 62/* pDataOut - pointer to the output data buffer */ 63/* BlockLength - number of samples to process */ 64/* */ 65/* RETURNS: */ 66/* None */ 67/* */ 68/* NOTES: */ 69/* */ 70/****************************************************************************************/ 71 72void NonLinComp_D16(LVM_INT16 Gain, 73 LVM_INT16 *pDataIn, 74 LVM_INT16 *pDataOut, 75 LVM_INT32 BlockLength) 76{ 77 78 LVM_INT16 Sample; /* Input samples */ 79 LVM_INT32 SampleNo; /* Sample index */ 80 LVM_INT16 Temp; 81 82 83 /* 84 * Process a block of samples 85 */ 86 for(SampleNo = 0; SampleNo<BlockLength; SampleNo++) 87 { 88 89 /* 90 * Read the input 91 */ 92 Sample = *pDataIn; 93 pDataIn++; 94 95 96 /* 97 * Apply the compander, this compresses the signal at the expense of 98 * harmonic distortion. The amount of compression is control by the 99 * gain factor 100 */ 101 if ((LVM_INT32)Sample != -32768) 102 { 103 Temp = (LVM_INT16)((Sample * Sample) >> 15); 104 if(Sample >0) 105 { 106 Sample = (LVM_INT16)(Sample + ((Gain * (Sample - Temp)) >> 15)); 107 } 108 else 109 { 110 Sample = (LVM_INT16)(Sample + ((Gain * (Sample + Temp)) >> 15)); 111 } 112 } 113 114 115 /* 116 * Save the output 117 */ 118 *pDataOut = Sample; 119 pDataOut++; 120 121 122 } 123 124} 125 126