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/d8_31pf.c
35 Functions:
36
37
38     Date: 01/28/2002
39
40------------------------------------------------------------------------------
41 REVISION HISTORY
42
43 Description: Modified to pass overflow flag through to basic math function.
44 The flag is passed back to the calling function by pointer reference.
45
46 Description: Per review comments...
47 (1) Removed include of "count.h" and "basic_op.h"
48 (2) Added includes of mult.h, shl.h, shr.h, add.h, sub.h, negate.h,
49     L_mult.h, and L_shr.h
50
51 Description:  Replaced "int" and/or "char" with OSCL defined types.
52
53 Description:
54
55------------------------------------------------------------------------------
56 MODULE DESCRIPTION
57*/
58
59/*----------------------------------------------------------------------------
60; INCLUDES
61----------------------------------------------------------------------------*/
62#include "d8_31pf.h"
63#include "typedef.h"
64#include "basic_op.h"
65#include "cnst.h"
66
67
68/*----------------------------------------------------------------------------
69; MACROS
70; Define module specific macros here
71----------------------------------------------------------------------------*/
72
73/*----------------------------------------------------------------------------
74; DEFINES
75; Include all pre-processor statements here. Include conditional
76; compile variables also.
77----------------------------------------------------------------------------*/
78#define NB_PULSE  8           /* number of pulses  */
79
80/* define values/representation for output codevector and sign */
81#define POS_CODE  8191
82#define NEG_CODE  8191
83
84
85/*----------------------------------------------------------------------------
86; LOCAL FUNCTION DEFINITIONS
87; Function Prototype declaration
88----------------------------------------------------------------------------*/
89
90/*----------------------------------------------------------------------------
91; LOCAL VARIABLE DEFINITIONS
92; Variable declaration - defined here and used outside this module
93----------------------------------------------------------------------------*/
94
95/*
96------------------------------------------------------------------------------
97 FUNCTION NAME: decompress10
98------------------------------------------------------------------------------
99 INPUT AND OUTPUT DEFINITIONS
100
101 Inputs:
102   MSBs -- Word16 -- MSB part of the index
103   LSBs -- Word16 -- LSB part of the index
104   index1 -- Word16 -- index for first pos in pos_index[]
105   index2 -- Word16 -- index for second pos in pos_index[]
106   index3 -- Word16 -- index for third pos in pos_index[]
107
108 Outputs:
109   pos_indx[] -- array of type Word16 -- position of 3 pulses (decompressed)
110
111   pOverflow  Flag set when overflow occurs, pointer of type Flag *
112
113 Returns:
114    None
115
116 Global Variables Used:
117    None
118
119 Local Variables Needed:
120    None
121
122------------------------------------------------------------------------------
123 FUNCTION DESCRIPTION
124
125
126------------------------------------------------------------------------------
127 REQUIREMENTS
128
129 None
130
131------------------------------------------------------------------------------
132 REFERENCES
133
134 d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
135
136------------------------------------------------------------------------------
137 PSEUDO-CODE
138
139
140------------------------------------------------------------------------------
141 RESOURCES USED [optional]
142
143 When the code is written for a specific target processor the
144 the resources used should be documented below.
145
146 HEAP MEMORY USED: x bytes
147
148 STACK MEMORY USED: x bytes
149
150 CLOCK CYCLES: (cycle count equation for this function) + (variable
151                used to represent cycle count for each subroutine
152                called)
153     where: (cycle count variable) = cycle count for [subroutine
154                                     name]
155
156------------------------------------------------------------------------------
157 CAUTION [optional]
158 [State any special notes, constraints or cautions for users of this function]
159
160------------------------------------------------------------------------------
161*/
162
163static void decompress10(
164    Word16 MSBs,        /* i : MSB part of the index                 */
165    Word16 LSBs,        /* i : LSB part of the index                 */
166    Word16 index1,      /* i : index for first pos in pos_index[]    */
167    Word16 index2,      /* i : index for second pos in pos_index[]   */
168    Word16 index3,      /* i : index for third pos in pos_index[]    */
169    Word16 pos_indx[],  /* o : position of 3 pulses (decompressed)   */
170    Flag  *pOverflow)   /* o : Flag set when overflow occurs         */
171{
172    Word16 ia;
173    Word16 ib;
174    Word16 ic;
175    Word32 tempWord32;
176
177    /*
178      pos_indx[index1] = ((MSBs-25*(MSBs/25))%5)*2 + (LSBs-4*(LSBs/4))%2;
179      pos_indx[index2] = ((MSBs-25*(MSBs/25))/5)*2 + (LSBs-4*(LSBs/4))/2;
180      pos_indx[index3] = (MSBs/25)*2 + LSBs/4;
181    */
182
183    if (MSBs > 124)
184    {
185        MSBs = 124;
186    }
187
188    ia =
189        mult(
190            MSBs,
191            1311,
192            pOverflow);
193
194    tempWord32 =
195        L_mult(
196            ia,
197            25,
198            pOverflow);
199
200
201    ia = (Word16)(MSBs - (tempWord32 >> 1));
202    ib =
203        mult(
204            ia,
205            6554,
206            pOverflow);
207
208    tempWord32 =
209        L_mult(
210            ib,
211            5,
212            pOverflow);
213
214    ib = ia - (Word16)(tempWord32 >> 1);
215
216    ib =
217        shl(
218            ib,
219            1,
220            pOverflow);
221
222
223    ic = LSBs - ((LSBs >> 2) << 2);
224
225
226    pos_indx[index1] = ib + (ic & 1);
227
228
229    ib =
230        mult(
231            ia,
232            6554,
233            pOverflow);
234
235    ib =
236        shl(
237            ib,
238            1,
239            pOverflow);
240
241
242    pos_indx[index2] = ib + (ic >> 1);
243
244
245    ib = LSBs >> 2;
246
247    ic =
248        mult(
249            MSBs,
250            1311,
251            pOverflow);
252
253    ic =
254        shl(
255            ic,
256            1,
257            pOverflow);
258
259    pos_indx[index3] =
260        add(
261            ib,
262            ic,
263            pOverflow);
264
265    return;
266}
267
268
269/*
270------------------------------------------------------------------------------
271 FUNCTION NAME: decompress_code
272------------------------------------------------------------------------------
273 INPUT AND OUTPUT DEFINITIONS
274
275 Inputs:
276    indx[] -- array of type Word16 -- position and sign of
277                                      8 pulses (compressed)
278
279 Outputs:
280    sign_indx[] -- array of type Word16 -- signs of 4 pulses (signs only)
281    pos_indx[]  -- array of type Word16 -- position index of 8 pulses
282                                           (position only)
283    pOverflow pointer to type Flag -- Flag set when overflow occurs
284
285 Returns:
286    None
287
288 Global Variables Used:
289    None
290
291 Local Variables Needed:
292    None
293
294------------------------------------------------------------------------------
295 FUNCTION DESCRIPTION
296
297    PURPOSE: decompression of the linear codewords to 4+three indeces
298             one bit from each pulse is made robust to errors by
299             minimizing the phase shift of a bit error.
300             4 signs (one for each track)
301             i0,i4,i1 => one index (7+3) bits, 3   LSBs more robust
302             i2,i6,i5 => one index (7+3) bits, 3   LSBs more robust
303             i3,i7    => one index (5+2) bits, 2-3 LSbs more robust
304
305------------------------------------------------------------------------------
306 REQUIREMENTS
307
308 None
309
310------------------------------------------------------------------------------
311 REFERENCES
312
313 d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
314
315------------------------------------------------------------------------------
316 PSEUDO-CODE
317
318
319------------------------------------------------------------------------------
320 RESOURCES USED [optional]
321
322 When the code is written for a specific target processor the
323 the resources used should be documented below.
324
325 HEAP MEMORY USED: x bytes
326
327 STACK MEMORY USED: x bytes
328
329 CLOCK CYCLES: (cycle count equation for this function) + (variable
330                used to represent cycle count for each subroutine
331                called)
332     where: (cycle count variable) = cycle count for [subroutine
333                                     name]
334
335------------------------------------------------------------------------------
336 CAUTION [optional]
337 [State any special notes, constraints or cautions for users of this function]
338
339------------------------------------------------------------------------------
340*/
341
342static void decompress_code(
343    Word16 indx[],      /* i : position and sign of 8 pulses (compressed) */
344    Word16 sign_indx[], /* o : signs of 4 pulses (signs only)             */
345    Word16 pos_indx[],  /* o : position index of 8 pulses (position only) */
346    Flag  *pOverflow    /* o : Flag set when overflow occurs              */
347)
348{
349    Word16 i;
350    Word16 ia;
351    Word16 ib;
352    Word16 MSBs;
353    Word16 LSBs;
354    Word16 MSBs0_24;
355    Word32 tempWord32;
356
357    for (i = 0; i < NB_TRACK_MR102; i++)
358    {
359        sign_indx[i] = indx[i];
360    }
361
362    /*
363      First index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits
364      MSBs = indx[NB_TRACK]/8;
365      LSBs = indx[NB_TRACK]%8;
366      */
367    MSBs = indx[NB_TRACK_MR102] >> 3;
368
369    LSBs = indx[NB_TRACK_MR102] & 0x7;
370
371    decompress10(
372        MSBs,
373        LSBs,
374        0,
375        4,
376        1,
377        pos_indx,
378        pOverflow);
379
380    /*
381      Second index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits
382      MSBs = indx[NB_TRACK+1]/8;
383      LSBs = indx[NB_TRACK+1]%8;
384      */
385    MSBs = indx[NB_TRACK_MR102+1] >> 3;
386
387    LSBs = indx[NB_TRACK_MR102+1] & 0x7;
388
389    decompress10(
390        MSBs,
391        LSBs,
392        2,
393        6,
394        5,
395        pos_indx,
396        pOverflow);
397
398    /*
399      Third index: 10x10 -> 2x5x2x5-> 25x2x2 -> 5+1x2 bits
400      MSBs = indx[NB_TRACK+2]/4;
401      LSBs = indx[NB_TRACK+2]%4;
402      MSBs0_24 = (MSBs*25+12)/32;
403      if ((MSBs0_24/5)%2==1)
404         pos_indx[3] = (4-(MSBs0_24%5))*2 + LSBs%2;
405      else
406         pos_indx[3] = (MSBs0_24%5)*2 + LSBs%2;
407      pos_indx[7] = (MSBs0_24/5)*2 + LSBs/2;
408      */
409
410    MSBs = indx[NB_TRACK_MR102+2] >> 2;
411
412    LSBs = indx[NB_TRACK_MR102+2] & 0x3;
413
414    tempWord32 =
415        L_mult(
416            MSBs,
417            25,
418            pOverflow);
419
420    ia =
421        (Word16)
422        L_shr(
423            tempWord32,
424            1,
425            pOverflow);
426
427    ia += 12;
428
429    MSBs0_24 = ia >> 5;
430
431
432    ia =
433        mult(
434            MSBs0_24,
435            6554,
436            pOverflow);
437
438    ia &= 1;
439
440
441    ib =
442        mult(
443            MSBs0_24,
444            6554,
445            pOverflow);
446
447    tempWord32 =
448        L_mult(
449            ib,
450            5,
451            pOverflow);
452
453
454    ib = MSBs0_24 - (Word16)(tempWord32 >> 1);
455
456    if (ia == 1)
457    {
458        ib = 4 - ib;
459
460    }
461
462
463    ib =
464        shl(
465            ib,
466            1,
467            pOverflow);
468
469    ia = LSBs & 0x1;
470
471    pos_indx[3] =
472        add(
473            ib,
474            ia,
475            pOverflow);
476
477    ia =
478        mult(
479            MSBs0_24,
480            6554,
481            pOverflow);
482
483    ia =
484        shl(
485            ia,
486            1,
487            pOverflow);
488
489    pos_indx[7] = ia + (LSBs >> 1);
490
491}
492
493/*
494------------------------------------------------------------------------------
495 FUNCTION NAME: dec_8i40_31bits
496------------------------------------------------------------------------------
497 INPUT AND OUTPUT DEFINITIONS
498
499 Inputs:
500    index   array of type Word16 --  index of 8 pulses (sign+position)
501
502 Outputs:
503    cod     array of type Word16 --  algebraic (fixed) codebook excitation
504    pOverflow pointer to type Flag -- Flag set when overflow occurs
505
506 Returns:
507    None
508
509 Global Variables Used:
510    None
511
512 Local Variables Needed:
513    None
514
515------------------------------------------------------------------------------
516 FUNCTION DESCRIPTION
517
518 PURPOSE:  Builds the innovative codevector from the received
519           index of algebraic codebook.
520
521------------------------------------------------------------------------------
522 REQUIREMENTS
523
524 None
525
526------------------------------------------------------------------------------
527 REFERENCES
528
529 d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
530
531------------------------------------------------------------------------------
532 PSEUDO-CODE
533
534
535------------------------------------------------------------------------------
536 RESOURCES USED [optional]
537
538 When the code is written for a specific target processor the
539 the resources used should be documented below.
540
541 HEAP MEMORY USED: x bytes
542
543 STACK MEMORY USED: x bytes
544
545 CLOCK CYCLES: (cycle count equation for this function) + (variable
546                used to represent cycle count for each subroutine
547                called)
548     where: (cycle count variable) = cycle count for [subroutine
549                                     name]
550
551------------------------------------------------------------------------------
552 CAUTION [optional]
553 [State any special notes, constraints or cautions for users of this function]
554
555------------------------------------------------------------------------------
556*/
557
558void dec_8i40_31bits(
559    Word16 index[],    /* i : index of 8 pulses (sign+position)         */
560    Word16 cod[],      /* o : algebraic (fixed) codebook excitation     */
561    Flag  *pOverflow   /* o : Flag set when overflow occurs             */
562)
563{
564    Word16 i;
565    Word16 j;
566    Word16 pos1;
567    Word16 pos2;
568    Word16 sign;
569
570    Word16 linear_signs[NB_TRACK_MR102];
571    Word16 linear_codewords[NB_PULSE];
572
573    for (i = 0; i < L_CODE; i++)
574    {
575        cod[i] = 0;
576    }
577
578    decompress_code(
579        index,
580        linear_signs,
581        linear_codewords,
582        pOverflow);
583
584    /* decode the positions and signs of pulses and build the codeword */
585    for (j = 0; j < NB_TRACK_MR102; j++)    /* NB_TRACK_MR102 = 4 */
586    {
587        /* position of pulse "j" */
588
589        pos1 = (linear_codewords[j] << 2) + j;
590
591
592        if (linear_signs[j] == 0)
593        {
594            sign = POS_CODE; /* +1.0 */
595        }
596        else
597        {
598            sign = -NEG_CODE; /* -1.0 */
599        }
600
601        if (pos1 < L_SUBFR)
602        {
603            cod[pos1] = sign;    /* avoid buffer overflow */
604        }
605
606        /* compute index i */
607        /* position of pulse "j+4" */
608
609        pos2 = (linear_codewords[j + 4] << 2) + j;
610
611
612        if (pos2 < pos1)
613        {
614            sign = negate(sign);
615        }
616
617        if (pos2 < L_SUBFR)
618        {
619            cod[pos2] += sign;     /* avoid buffer overflow */
620        }
621
622
623    } /* for (j = 0; j < NB_TRACK_MR102; j++) */
624
625    return;
626}
627