1 /*****************************************************************************
2 **
3 **   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
4 **   > Software Release 2.1 (2008-06)
5 **     (Simple repackaging; no change from 2005-05 Release 2.0 code)
6 **
7 **   � 2004 Polycom, Inc.
8 **
9 **   All rights reserved.
10 **
11 *****************************************************************************/
12 
13 /*****************************************************************************
14 * Filename: rmlt_coefs_to_samples.c
15 *
16 * Purpose:  Convert Reversed MLT (Modulated Lapped Transform)
17 *           Coefficients to Samples
18 *
19 *     The "Reversed MLT" is an overlapped block transform which uses
20 *     even symmetry * on the left, odd symmetry on the right and a
21 *     Type IV DCT as the block transform.  * It is thus similar to a
22 *     MLT which uses odd symmetry on the left, even symmetry * on the
23 *     right and a Type IV DST as the block transform.  In fact, it is
24 *     equivalent * to reversing the order of the samples, performing
25 *     an MLT and then negating all * the even-numbered coefficients.
26 *
27 *****************************************************************************/
28 
29 /***************************************************************************
30  Include files
31 ***************************************************************************/
32 #include "defs.h"
33 #include "tables.h"
34 #include "count.h"
35 
36 /***************************************************************************
37  Function:     rmlt_coefs_to_samples
38 
39  Syntax:       void rmlt_coefs_to_samples(Word16 *coefs,
40                                           Word16 *old_samples,
41                                           Word16 *out_samples,
42                                           Word16 dct_length,
43                                           Word16 mag_shift)
44 
45                inputs:    Word16 *coefs
46                           Word16 *old_samples
47                           Word16 dct_length
48                           Word16 mag_shift
49 
50 
51                outputs:   Word16 *out_samples
52 
53  Description:  Converts the mlt_coefs to samples
54 
55  Design Notes:
56 
57  WMOPS:     7kHz |    24kbit    |    32kbit
58           -------|--------------|----------------
59             AVG  |     1.91     |    1.91
60           -------|--------------|----------------
61             MAX  |     1.91     |    1.91
62           -------|--------------|----------------
63 
64            14kHz |    24kbit    |    32kbit      |     48kbit
65           -------|--------------|----------------|----------------
66             AVG  |     3.97     |    3.97        |     3.97
67           -------|--------------|----------------|----------------
68             MAX  |     3.97     |    3.97        |     3.97
69           -------|--------------|----------------|----------------
70 
71 ***************************************************************************/
72 
rmlt_coefs_to_samples(Word16 * coefs,Word16 * old_samples,Word16 * out_samples,Word16 dct_length,Word16 mag_shift)73 void rmlt_coefs_to_samples(Word16 *coefs,
74                            Word16 *old_samples,
75                            Word16 *out_samples,
76                            Word16 dct_length,
77                            Word16 mag_shift)
78 {
79 
80 
81     Word16	index, vals_left;
82     Word16	new_samples[MAX_DCT_LENGTH];
83     Word16	*new_ptr, *old_ptr;
84     Word16	*win_new, *win_old;
85     Word16	*out_ptr;
86     Word16  half_dct_size;
87     Word32  sum;
88 
89 
90 
91     half_dct_size = shr_nocheck(dct_length,1);
92 
93     /* Perform a Type IV (inverse) DCT on the coefficients */
94     dct_type_iv_s(coefs, new_samples, dct_length);
95 
96     test();
97     if (mag_shift > 0)
98     {
99         for(index=0;index<dct_length;index++)
100         {
101             new_samples[index] = shr_nocheck(new_samples[index],mag_shift);
102             move16();
103         }
104     }
105     else
106     {
107         test();
108         if (mag_shift < 0)
109         {
110             mag_shift = negate(mag_shift);
111             for(index=0;index<dct_length;index++)
112             {
113                 new_samples[index] = shl_nocheck(new_samples[index],mag_shift);
114                 move16();
115             }
116         }
117 
118     }
119 
120     /* Get the first half of the windowed samples */
121 
122     out_ptr = out_samples;
123     move16();
124     test();
125     if (dct_length==DCT_LENGTH)
126     {
127         win_new = rmlt_to_samples_window;
128         move16();
129         win_old = rmlt_to_samples_window + dct_length;
130         move16();
131     }
132     else
133     {
134         win_new = max_rmlt_to_samples_window;
135         move16();
136         win_old = max_rmlt_to_samples_window + dct_length;
137         move16();
138     }
139     old_ptr = old_samples;
140     move16();
141     new_ptr = new_samples + half_dct_size;
142     move16();
143 
144     for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)
145     {
146         sum = 0L;
147         move32();
148         sum = L_mac(sum,*win_new++, *--new_ptr);
149         sum = L_mac(sum,*--win_old, *old_ptr++);
150         *out_ptr++ = itu_round(L_shl_nocheck(sum,2));
151         move16();
152 
153     }
154 
155     /* Get the second half of the windowed samples */
156 
157     for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)
158     {
159         sum = 0L;
160         move32();
161         sum = L_mac(sum,*win_new++, *new_ptr++);
162         sum = L_mac(sum,negate(*--win_old), *--old_ptr);
163         *out_ptr++ = itu_round(L_shl_nocheck(sum,2));
164         move16();
165     }
166 
167     /* Save the second half of the new samples for   */
168     /* next time, when they will be the old samples. */
169 
170     /* pointer arithmetic */
171     new_ptr = new_samples + half_dct_size;
172     move16();
173     old_ptr = old_samples;
174     move16();
175     for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)
176     {
177         *old_ptr++ = *new_ptr++;
178         move16();
179     }
180 }
181