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