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 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
133 Word16 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
pseudonoise(Word32 * pShift_reg,Word16 no_bits)202 Word16 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
278 This function computes the comfort noise fixed codebook excitation. The gains
279 of 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
294 void 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 ----------------------------------------------------------------------------*/
build_CN_code(Word32 * pSeed,Word16 cod[],Flag * pOverflow)357 void 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
424 This function randomizes the speech parameters, so that they do not produce
425 tonal 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
439 void 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 ----------------------------------------------------------------------------*/
build_CN_param(Word16 * pSeed,const Word16 n_param,const Word16 param_size_table[],Word16 parm[],Flag * pOverflow)489 void 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