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