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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms listed above has been obtained from the copyright holder.
28****************************************************************************************/
29/*
30------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/b_cn_cod.c
35 Functions: pseudonoise
36            build_CN_code
37            build_CN_param
38
39     Date: 09/28/2000
40
41------------------------------------------------------------------------------
42 REVISION HISTORY
43
44 Description: Updated template. Cleaned up code. Passing in a pointer to
45              overflow flag for build_CN_code() and build_CN_param() functions.
46              Removed unnecessary header files.
47 Description: Make chnages per formal review. Fix error introduced during
48              optimization in pseudonoise().
49
50 Description:
51
52------------------------------------------------------------------------------
53 MODULE DESCRIPTION
54
55 This module contains functions for comfort noise(CN) generation.
56
57------------------------------------------------------------------------------
58*/
59
60
61/*----------------------------------------------------------------------------
62; INCLUDES
63----------------------------------------------------------------------------*/
64#include "b_cn_cod.h"
65#include "basic_op.h"
66#include "cnst.h"
67
68/*----------------------------------------------------------------------------
69; MACROS
70; [Define module specific macros here]
71----------------------------------------------------------------------------*/
72
73
74/*----------------------------------------------------------------------------
75; DEFINES
76; [Include all pre-processor statements here. Include conditional
77; compile variables also.]
78----------------------------------------------------------------------------*/
79#define  NB_PULSE 10        /* number of random pulses in DTX operation   */
80
81/*----------------------------------------------------------------------------
82; LOCAL FUNCTION DEFINITIONS
83; [List function prototypes here]
84----------------------------------------------------------------------------*/
85
86/*----------------------------------------------------------------------------
87; LOCAL VARIABLE DEFINITIONS
88; [Variable declaration - defined here and used outside this module]
89----------------------------------------------------------------------------*/
90
91/*
92------------------------------------------------------------------------------
93 FUNCTION NAME: pseudonoise
94------------------------------------------------------------------------------
95 INPUT AND OUTPUT DEFINITIONS
96
97 Inputs:
98    pShift_reg = pointer to Old CN generator shift register state (Word32)
99    no_bits = Number of bits (Word16)
100
101 Outputs:
102    pShift_reg -> Updated CN generator shift register state
103
104 Returns:
105    noise_bits = Generated random integer value (Word16)
106
107 Global Variables Used:
108    None
109
110 Local Variables Needed:
111    None
112
113------------------------------------------------------------------------------
114 FUNCTION DESCRIPTION
115
116 Generate a random integer value to use in comfort noise generation. The
117 algorithm uses polynomial x^31 + x^3 + 1. Length of the PN sequence
118 is 2^31 - 1
119
120------------------------------------------------------------------------------
121 REQUIREMENTS
122
123 None
124
125------------------------------------------------------------------------------
126 REFERENCES
127
128 b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
129
130------------------------------------------------------------------------------
131 PSEUDO-CODE
132
133Word16 pseudonoise (
134    Word32 *shift_reg, // i/o : Old CN generator shift register state
135    Word16 no_bits     // i   : Number of bits
136)
137{
138   Word16 noise_bits, Sn, i;
139
140   noise_bits = 0;
141   for (i = 0; i < no_bits; i++)
142   {
143      // State n == 31
144      if ((*shift_reg & 0x00000001L) != 0)
145      {
146         Sn = 1;
147      }
148      else
149      {
150         Sn = 0;
151      }
152
153      // State n == 3
154      if ((*shift_reg & 0x10000000L) != 0)
155      {
156         Sn = Sn ^ 1;
157      }
158      else
159      {
160         Sn = Sn ^ 0;
161      }
162
163      noise_bits = shl (noise_bits, 1);
164      noise_bits = noise_bits | (extract_l (*shift_reg) & 1);
165
166      *shift_reg = L_shr (*shift_reg, 1);
167      if (Sn & 1)
168      {
169         *shift_reg = *shift_reg | 0x40000000L;
170      }
171   }
172   return noise_bits;
173}
174
175------------------------------------------------------------------------------
176 RESOURCES USED [optional]
177
178 When the code is written for a specific target processor the
179 the resources used should be documented below.
180
181 HEAP MEMORY USED: x bytes
182
183 STACK MEMORY USED: x bytes
184
185 CLOCK CYCLES: (cycle count equation for this function) + (variable
186                used to represent cycle count for each subroutine
187                called)
188     where: (cycle count variable) = cycle count for [subroutine
189                                     name]
190
191------------------------------------------------------------------------------
192 CAUTION [optional]
193 [State any special notes, constraints or cautions for users of this function]
194
195------------------------------------------------------------------------------
196*/
197
198/*----------------------------------------------------------------------------
199; FUNCTION CODE
200----------------------------------------------------------------------------*/
201
202Word16 pseudonoise(
203    Word32 *pShift_reg,     /* i/o : Old CN generator shift register state */
204    Word16 no_bits          /* i   : Number of bits                        */
205)
206{
207    Word16 noise_bits;
208    Word16 Sn;
209    Word16 i;
210    Word16 temp;
211
212    noise_bits = 0;
213
214    for (i = 0; i < no_bits; i++)
215    {
216        /* State n == 31 */
217        if ((*pShift_reg & 0x00000001L) != 0)
218        {
219            Sn = 1;
220        }
221        else
222        {
223            Sn = 0;
224        }
225
226        /* State n == 3 */
227        if ((*pShift_reg & 0x10000000L) != 0)
228        {
229            Sn ^= 1;
230        }
231        else
232        {
233            Sn ^= 0;
234        }
235
236        noise_bits <<= 1;
237
238        temp = (Word16)((*pShift_reg) & 1);
239        noise_bits |= temp;
240
241        *pShift_reg >>= 1;
242        if (Sn & 1)
243        {
244            *pShift_reg |= 0x40000000L;
245        }
246    }
247    return noise_bits;
248}
249
250/*
251------------------------------------------------------------------------------
252 FUNCTION NAME: build_CN_code
253------------------------------------------------------------------------------
254 INPUT AND OUTPUT DEFINITIONS
255
256 Inputs:
257    pSeed = pointer to the Old CN generator shift register state (Word32)
258    cod[] = array to hold the generated CN fixed code vector (Word16)
259    pOverflow = pointer to overflow flag (Flag)
260
261 Outputs:
262    cod[] = generated CN fixed code vector (Word16)
263    pSeed = Updated CN generator shift register state (Word16)
264    pOverflow -> 1 if overflow occured
265
266 Returns:
267    None
268
269 Global Variables Used:
270    None
271
272 Local Variables Needed:
273    None
274
275------------------------------------------------------------------------------
276 FUNCTION DESCRIPTION
277
278This function computes the comfort noise fixed codebook excitation. The gains
279of the pulses are always +/-1.
280
281------------------------------------------------------------------------------
282 REQUIREMENTS
283
284 None
285
286------------------------------------------------------------------------------
287 REFERENCES
288
289 b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
290
291------------------------------------------------------------------------------
292 PSEUDO-CODE
293
294void build_CN_code (
295    Word32 *seed,         // i/o : Old CN generator shift register state
296    Word16 cod[]          // o   : Generated CN fixed codebook vector
297)
298{
299   Word16 i, j, k;
300
301   for (i = 0; i < L_SUBFR; i++)
302   {
303      cod[i] = 0;
304   }
305
306// The reference ETSI code uses a global flag for Overflow. However in the
307// actual implementation a pointer to the overflow flag is passed into the
308// function so that it can be passed into the basic math functions L_mult()
309// and add()
310
311   for (k = 0; k < NB_PULSE; k++)
312   {
313      i = pseudonoise (seed, 2);      // generate pulse position
314      i = shr (extract_l (L_mult (i, 10)), 1);
315      i = add (i, k);
316
317      j = pseudonoise (seed, 1);      // generate sign
318
319      if (j > 0)
320      {
321         cod[i] = 4096;
322      }
323      else
324      {
325         cod[i] = -4096;
326      }
327   }
328
329   return;
330}
331------------------------------------------------------------------------------
332 RESOURCES USED [optional]
333
334 When the code is written for a specific target processor the
335 the resources used should be documented below.
336
337 HEAP MEMORY USED: x bytes
338
339 STACK MEMORY USED: x bytes
340
341 CLOCK CYCLES: (cycle count equation for this function) + (variable
342                used to represent cycle count for each subroutine
343                called)
344     where: (cycle count variable) = cycle count for [subroutine
345                                     name]
346
347------------------------------------------------------------------------------
348 CAUTION [optional]
349 [State any special notes, constraints or cautions for users of this function]
350
351------------------------------------------------------------------------------
352*/
353
354/*----------------------------------------------------------------------------
355; FUNCTION CODE
356----------------------------------------------------------------------------*/
357void build_CN_code(
358    Word32 *pSeed,          /* i/o : Old CN generator shift register state  */
359    Word16 cod[],           /* o   : Generated CN fixed codebook vector     */
360    Flag   *pOverflow       /* i/o : Overflow flag                          */
361)
362{
363    Word16 i, j, k;
364    Word16 temp;
365
366    for (i = 0; i < L_SUBFR; i++)
367    {
368        cod[i] = 0;
369    }
370
371    for (k = 0; k < NB_PULSE; k++)
372    {
373        i = pseudonoise(pSeed, 2);       /* generate pulse position */
374
375        temp = (Word16)(L_mult(i, 10, pOverflow));
376        i = temp >> 1;
377        i = add(i, k, pOverflow);
378
379        j = pseudonoise(pSeed, 1);       /* generate sign */
380
381        if (j > 0)
382        {
383            cod[i] = 4096;
384        }
385        else
386        {
387            cod[i] = -4096;
388        }
389    }
390
391    return;
392}
393
394/*
395------------------------------------------------------------------------------
396 FUNCTION NAME: build_CN_param
397------------------------------------------------------------------------------
398 INPUT AND OUTPUT DEFINITIONS
399
400 Inputs:
401    pSeed = pointer to the Old CN generator shift register state (Word32)
402    n_param = Number of parameters to randomize (Word16)
403    param_size_table = table holding paameter sizes (Word16)
404    param[] = array to hold CN generated paramters (Word16)
405    pOverflow = pointer to overflow flag (Flag)
406
407 Outputs:
408    param[] = CN generated parameters (Word16)
409    pSeed = Updated CN generator shift register state (Word16)
410    pOverflow -> 1 if overflow occured
411
412 Returns:
413    None
414
415 Global Variables Used:
416    None
417
418 Local Variables Needed:
419    None
420
421------------------------------------------------------------------------------
422 FUNCTION DESCRIPTION
423
424This function randomizes the speech parameters, so that they do not produce
425tonal artifacts if used by ECU.
426
427------------------------------------------------------------------------------
428 REQUIREMENTS
429
430 None
431
432------------------------------------------------------------------------------
433 REFERENCES
434
435 b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
436
437------------------------------------------------------------------------------
438 PSEUDO-CODE
439void build_CN_param (
440    Word16 *seed,             // i/o : Old CN generator shift register state
441    const Word16 n_param,           // i  : number of params
442    const Word16 param_size_table[],// i : size of params
443    Word16 parm[]                   // o : CN Generated params
444    )
445{
446   Word16 i;
447   const Word16 *p;
448
449// The reference ETSI code uses a global flag for Overflow. However in the
450// actual implementation a pointer to the overflow flag is passed into the
451// function so that it can be passed into the basic math functions L_add()
452// and L_mult()
453
454   *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L));
455
456   p = &window_200_40[*seed & 0x7F];
457   for(i=0; i< n_param;i++){
458     parm[i] = *p++ & ~(0xFFFF<<param_size_table[i]);
459   }
460}
461
462
463------------------------------------------------------------------------------
464 RESOURCES USED [optional]
465
466 When the code is written for a specific target processor the
467 the resources used should be documented below.
468
469 HEAP MEMORY USED: x bytes
470
471 STACK MEMORY USED: x bytes
472
473 CLOCK CYCLES: (cycle count equation for this function) + (variable
474                used to represent cycle count for each subroutine
475                called)
476     where: (cycle count variable) = cycle count for [subroutine
477                                     name]
478
479------------------------------------------------------------------------------
480 CAUTION [optional]
481 [State any special notes, constraints or cautions for users of this function]
482
483------------------------------------------------------------------------------
484*/
485
486/*----------------------------------------------------------------------------
487; FUNCTION CODE
488----------------------------------------------------------------------------*/
489void build_CN_param(
490    Word16 *pSeed,          /* i/o : Old CN generator shift register state  */
491    const Word16 n_param,           /* i  : number of params                */
492    const Word16 param_size_table[],/* i : size of params                   */
493    Word16 parm[],                  /* o : CN Generated params              */
494    Flag  *pOverflow                /* i/o : Overflow Flag                  */
495)
496
497{
498    Word16 i;
499    const Word16 *pTemp;
500    Word32 L_temp;
501    Word16 temp;
502
503    L_temp = L_mult(*pSeed, 31821, pOverflow);
504    L_temp >>= 1;
505
506    *pSeed = (Word16)(L_add(L_temp, 13849L, pOverflow));
507
508    pTemp = &window_200_40[*pSeed & 0x7F];
509
510    for (i = 0; i < n_param; i++)
511    {
512        temp = ~(0xFFFF << param_size_table[i]);
513        parm[i] = *pTemp++ & temp;
514    }
515}
516
517