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/* Includes */ 212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/ 232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "CompLim_private.h" 252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/ 272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION: NonLinComp_D16 */ 292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION: */ 312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Non-linear compression by companding. The function works on a sample by sample */ 322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* basis by increasing the level near the zero crossing. This gives a ttrade-off */ 332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* between THD and compression. It uses the equation: */ 342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Output = Input + K * (Input - Input^2) if Input > 0 */ 362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* = Input + K * (Input + Input^2) if Input <= 0 */ 372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* The value of K controls the amount of compression and as a side effect the amount */ 392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* distortion introduced. The amount of compression is signal dependent and the values */ 402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* given below are approximate. */ 412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Gain (fractional) Gain (integer) Compression Pk-Pk THD */ 432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 1.0 32767 +6dB 16dB */ 442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 0.78 25559 +5dB 19dB */ 452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 0.6 19661 +4dB 21dB */ 462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 0.41 13435 +3dB 24dB */ 472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 0.26 8520 +2dB 28dB */ 482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 0.12 3932 +1dB 34dB */ 492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* 0.0 0 +0dB 98dB */ 502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS: */ 522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Gain - compression control parameter */ 532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pDataIn - pointer to the input data buffer */ 542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pDataOut - pointer to the output data buffer */ 552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* BlockLength - number of samples to process */ 562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS: */ 582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* None */ 592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES: */ 612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/ 632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid NonLinComp_D16(LVM_INT16 Gain, 652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pDataIn, 662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pDataOut, 672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT32 BlockLength) 682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 Sample; /* Input samples */ 712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT32 SampleNo; /* Sample index */ 722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 Temp; 732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Process a block of samples 772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent for(SampleNo = 0; SampleNo<BlockLength; SampleNo++) 792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Read the input 832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Sample = *pDataIn; 852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pDataIn++; 862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Apply the compander, this compresses the signal at the expense of 902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * harmonic distortion. The amount of compression is control by the 912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * gain factor 922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if ((LVM_INT32)Sample != -32768) 942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Temp = (LVM_INT16)((Sample * Sample) >> 15); 962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(Sample >0) 972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Sample = (LVM_INT16)(Sample + ((Gain * (Sample - Temp)) >> 15)); 992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Sample = (LVM_INT16)(Sample + ((Gain * (Sample + Temp)) >> 15)); 1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* 1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Save the output 1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */ 1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *pDataOut = Sample; 1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pDataOut++; 1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 118