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 
pseudonoise(Word32 * pShift_reg,Word16 no_bits)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 ----------------------------------------------------------------------------*/
build_CN_code(Word32 * pSeed,Word16 cod[],Flag * pOverflow)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 ----------------------------------------------------------------------------*/
build_CN_param(Word16 * pSeed,const Word16 n_param,const Word16 param_size_table[],Word16 parm[],const Word16 * window_200_40_ptr,Flag * pOverflow)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 
457