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