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
NonLinComp_D16(LVM_INT16 Gain,LVM_INT16 * pDataIn,LVM_INT16 * pDataOut,LVM_INT32 BlockLength)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 #ifdef BUILD_FLOAT
NonLinComp_Float(LVM_FLOAT Gain,LVM_FLOAT * pDataIn,LVM_FLOAT * pDataOut,LVM_INT32 BlockLength)118 void NonLinComp_Float(LVM_FLOAT Gain,
119 LVM_FLOAT *pDataIn,
120 LVM_FLOAT *pDataOut,
121 LVM_INT32 BlockLength)
122 {
123
124 LVM_FLOAT Sample; /* Input samples */
125 LVM_INT32 SampleNo; /* Sample index */
126 LVM_FLOAT Temp;
127
128
129 /*
130 * Process a block of samples
131 */
132 for(SampleNo = 0; SampleNo < BlockLength; SampleNo++)
133 {
134 /*
135 * Read the input
136 */
137 Sample = *pDataIn;
138 pDataIn++;
139
140
141 /*
142 * Apply the compander, this compresses the signal at the expense of
143 * harmonic distortion. The amount of compression is control by the
144 * gain factor
145 */
146 if (Sample != -1.0f)
147 {
148 Temp = ((Sample * Sample));
149 if(Sample > 0)
150 {
151 Sample = (Sample + ((Gain * (Sample - Temp)) ));
152 }
153 else
154 {
155 Sample = (Sample + ((Gain * (Sample + Temp)) ));
156 }
157 }
158
159
160 /*
161 * Save the output
162 */
163 *pDataOut = Sample;
164 pDataOut++;
165 }
166 }
167 #endif
168