Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / b_cn_cod.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: b_cn_cod.cpp
35  Functions: pseudonoise
36             build_CN_code
37             build_CN_param
38
39 ------------------------------------------------------------------------------
40  MODULE DESCRIPTION
41
42  This module contains functions for comfort noise(CN) generation.
43
44 ------------------------------------------------------------------------------
45 */
46
47
48 /*----------------------------------------------------------------------------
49 ; INCLUDES
50 ----------------------------------------------------------------------------*/
51 #include "b_cn_cod.h"
52 #include "basic_op.h"
53 #include "cnst.h"
54
55 /*----------------------------------------------------------------------------
56 ; MACROS
57 ; [Define module specific macros here]
58 ----------------------------------------------------------------------------*/
59
60
61 /*----------------------------------------------------------------------------
62 ; DEFINES
63 ; [Include all pre-processor statements here. Include conditional
64 ; compile variables also.]
65 ----------------------------------------------------------------------------*/
66 #define  NB_PULSE 10        /* number of random pulses in DTX operation   */
67
68 /*----------------------------------------------------------------------------
69 ; LOCAL FUNCTION DEFINITIONS
70 ; [List function prototypes here]
71 ----------------------------------------------------------------------------*/
72
73 /*----------------------------------------------------------------------------
74 ; LOCAL VARIABLE DEFINITIONS
75 ; [Variable declaration - defined here and used outside this module]
76 ----------------------------------------------------------------------------*/
77
78 /*
79 ------------------------------------------------------------------------------
80  FUNCTION NAME: pseudonoise
81 ------------------------------------------------------------------------------
82  INPUT AND OUTPUT DEFINITIONS
83
84  Inputs:
85     pShift_reg = pointer to Old CN generator shift register state (Word32)
86     no_bits = Number of bits (Word16)
87
88  Outputs:
89     pShift_reg -> Updated CN generator shift register state
90
91  Returns:
92     noise_bits = Generated random integer value (Word16)
93
94  Global Variables Used:
95     None
96
97  Local Variables Needed:
98     None
99
100 ------------------------------------------------------------------------------
101  FUNCTION DESCRIPTION
102
103  Generate a random integer value to use in comfort noise generation. The
104  algorithm uses polynomial x^31 + x^3 + 1. Length of the PN sequence
105  is 2^31 - 1
106
107 ------------------------------------------------------------------------------
108  REQUIREMENTS
109
110  None
111
112 ------------------------------------------------------------------------------
113  REFERENCES
114
115  b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
116
117 ------------------------------------------------------------------------------
118  PSEUDO-CODE
119
120 Word16 pseudonoise (
121     Word32 *shift_reg, // i/o : Old CN generator shift register state
122     Word16 no_bits     // i   : Number of bits
123 )
124 {
125    Word16 noise_bits, Sn, i;
126
127    noise_bits = 0;
128    for (i = 0; i < no_bits; i++)
129    {
130       // State n == 31
131       if ((*shift_reg & 0x00000001L) != 0)
132       {
133          Sn = 1;
134       }
135       else
136       {
137          Sn = 0;
138       }
139
140       // State n == 3
141       if ((*shift_reg & 0x10000000L) != 0)
142       {
143          Sn = Sn ^ 1;
144       }
145       else
146       {
147          Sn = Sn ^ 0;
148       }
149
150       noise_bits = shl (noise_bits, 1);
151       noise_bits = noise_bits | (extract_l (*shift_reg) & 1);
152
153       *shift_reg = L_shr (*shift_reg, 1);
154       if (Sn & 1)
155       {
156          *shift_reg = *shift_reg | 0x40000000L;
157       }
158    }
159    return noise_bits;
160 }
161
162 ------------------------------------------------------------------------------
163  CAUTION [optional]
164  [State any special notes, constraints or cautions for users of this function]
165
166 ------------------------------------------------------------------------------
167 */
168
169 /*----------------------------------------------------------------------------
170 ; FUNCTION CODE
171 ----------------------------------------------------------------------------*/
172
173 Word16 pseudonoise(
174     Word32 *pShift_reg,     /* i/o : Old CN generator shift register state */
175     Word16 no_bits          /* i   : Number of bits                        */
176 )
177 {
178     Word16 noise_bits;
179     Word16 Sn;
180     Word16 i;
181     Word16 temp;
182
183     noise_bits = 0;
184
185     for (i = 0; i < no_bits; i++)
186     {
187         /* State n == 31 */
188         if ((*pShift_reg & 0x00000001L) != 0)
189         {
190             Sn = 1;
191         }
192         else
193         {
194             Sn = 0;
195         }
196
197         /* State n == 3 */
198         if ((*pShift_reg & 0x10000000L) != 0)
199         {
200             Sn ^= 1;
201         }
202         else
203         {
204             Sn ^= 0;
205         }
206
207         noise_bits <<= 1;
208
209         temp = (Word16)((*pShift_reg) & 1);
210         noise_bits |= temp;
211
212         *pShift_reg >>= 1;
213         if (Sn & 1)
214         {
215             *pShift_reg |= 0x40000000L;
216         }
217     }
218     return noise_bits;
219 }
220
221 /*
222 ------------------------------------------------------------------------------
223  FUNCTION NAME: build_CN_code
224 ------------------------------------------------------------------------------
225  INPUT AND OUTPUT DEFINITIONS
226
227  Inputs:
228     pSeed = pointer to the Old CN generator shift register state (Word32)
229     cod[] = array to hold the generated CN fixed code vector (Word16)
230     pOverflow = pointer to overflow flag (Flag)
231
232  Outputs:
233     cod[] = generated CN fixed code vector (Word16)
234     pSeed = Updated CN generator shift register state (Word16)
235     pOverflow -> 1 if overflow occured
236
237  Returns:
238     None
239
240  Global Variables Used:
241     None
242
243  Local Variables Needed:
244     None
245
246 ------------------------------------------------------------------------------
247  FUNCTION DESCRIPTION
248
249 This function computes the comfort noise fixed codebook excitation. The gains
250 of the pulses are always +/-1.
251
252 ------------------------------------------------------------------------------
253  REQUIREMENTS
254
255  None
256
257 ------------------------------------------------------------------------------
258  REFERENCES
259
260  b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
261
262 ------------------------------------------------------------------------------
263  PSEUDO-CODE
264
265 void build_CN_code (
266     Word32 *seed,         // i/o : Old CN generator shift register state
267     Word16 cod[]          // o   : Generated CN fixed codebook vector
268 )
269 {
270    Word16 i, j, k;
271
272    for (i = 0; i < L_SUBFR; i++)
273    {
274       cod[i] = 0;
275    }
276
277 // The reference ETSI code uses a global flag for Overflow. However in the
278 // actual implementation a pointer to the overflow flag is passed into the
279 // function so that it can be passed into the basic math functions L_mult()
280 // and add()
281
282    for (k = 0; k < NB_PULSE; k++)
283    {
284       i = pseudonoise (seed, 2);      // generate pulse position
285       i = shr (extract_l (L_mult (i, 10)), 1);
286       i = add (i, k);
287
288       j = pseudonoise (seed, 1);      // generate sign
289
290       if (j > 0)
291       {
292          cod[i] = 4096;
293       }
294       else
295       {
296          cod[i] = -4096;
297       }
298    }
299
300    return;
301 }
302 ------------------------------------------------------------------------------
303  CAUTION [optional]
304  [State any special notes, constraints or cautions for users of this function]
305
306 ------------------------------------------------------------------------------
307 */
308
309 /*----------------------------------------------------------------------------
310 ; FUNCTION CODE
311 ----------------------------------------------------------------------------*/
312 void build_CN_code(
313     Word32 *pSeed,          /* i/o : Old CN generator shift register state  */
314     Word16 cod[],           /* o   : Generated CN fixed codebook vector     */
315     Flag   *pOverflow       /* i/o : Overflow flag                          */
316 )
317 {
318     Word16 i, j, k;
319     Word16 temp;
320
321     for (i = 0; i < L_SUBFR; i++)
322     {
323         cod[i] = 0;
324     }
325
326     for (k = 0; k < NB_PULSE; k++)
327     {
328         i = pseudonoise(pSeed, 2);       /* generate pulse position */
329
330         temp = (Word16)(L_mult(i, 10, pOverflow));
331         i = temp >> 1;
332         i = add_16(i, k, pOverflow);
333
334         j = pseudonoise(pSeed, 1);       /* generate sign */
335
336         if (j > 0)
337         {
338             cod[i] = 4096;
339         }
340         else
341         {
342             cod[i] = -4096;
343         }
344     }
345
346     return;
347 }
348
349 /*
350 ------------------------------------------------------------------------------
351  FUNCTION NAME: build_CN_param
352 ------------------------------------------------------------------------------
353  INPUT AND OUTPUT DEFINITIONS
354
355  Inputs:
356     pSeed = pointer to the Old CN generator shift register state (Word32)
357     n_param = Number of parameters to randomize (Word16)
358     param_size_table = table holding paameter sizes (Word16)
359     param[] = array to hold CN generated paramters (Word16)
360     pOverflow = pointer to overflow flag (Flag)
361
362  Outputs:
363     param[] = CN generated parameters (Word16)
364     pSeed = Updated CN generator shift register state (Word16)
365     pOverflow -> 1 if overflow occured
366
367  Returns:
368     None
369
370  Global Variables Used:
371     None
372
373  Local Variables Needed:
374     None
375
376 ------------------------------------------------------------------------------
377  FUNCTION DESCRIPTION
378
379 This function randomizes the speech parameters, so that they do not produce
380 tonal artifacts if used by ECU.
381
382 ------------------------------------------------------------------------------
383  REQUIREMENTS
384
385  None
386
387 ------------------------------------------------------------------------------
388  REFERENCES
389
390  b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
391
392 ------------------------------------------------------------------------------
393  PSEUDO-CODE
394 void build_CN_param (
395     Word16 *seed,             // i/o : Old CN generator shift register state
396     const Word16 n_param,           // i  : number of params
397     const Word16 param_size_table[],// i : size of params
398     Word16 parm[]                   // o : CN Generated params
399     )
400 {
401    Word16 i;
402    const Word16 *p;
403
404 // The reference ETSI code uses a global flag for Overflow. However in the
405 // actual implementation a pointer to the overflow flag is passed into the
406 // function so that it can be passed into the basic math functions L_add()
407 // and L_mult()
408
409    *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L));
410
411    p = &window_200_40[*seed & 0x7F];
412    for(i=0; i< n_param;i++){
413      parm[i] = *p++ & ~(0xFFFF<<param_size_table[i]);
414    }
415 }
416
417
418 ------------------------------------------------------------------------------
419  CAUTION [optional]
420  [State any special notes, constraints or cautions for users of this function]
421
422 ------------------------------------------------------------------------------
423 */
424
425 /*----------------------------------------------------------------------------
426 ; FUNCTION CODE
427 ----------------------------------------------------------------------------*/
428 void build_CN_param(
429     Word16 *pSeed,          /* i/o : Old CN generator shift register state  */
430     const Word16 n_param,           /* i  : number of params                */
431     const Word16 param_size_table[],/* i : size of params                   */
432     Word16 parm[],                  /* o : CN Generated params              */
433     const Word16* window_200_40_ptr, /* i : ptr to read-only table          */
434     Flag  *pOverflow                /* i/o : Overflow Flag                  */
435 )
436
437 {
438     Word16 i;
439     const Word16 *pTemp;
440     Word32 L_temp;
441     Word16 temp;
442
443     L_temp = L_mult(*pSeed, 31821, pOverflow);
444     L_temp >>= 1;
445
446     *pSeed = (Word16)(L_add(L_temp, 13849L, pOverflow));
447
448     pTemp = &window_200_40_ptr[*pSeed & 0x7F];
449
450     for (i = 0; i < n_param; i++)
451     {
452         temp = ~(0xFFFF << param_size_table[i]);
453         parm[i] = *pTemp++ & temp;
454     }
455 }
456