blob: 3dd5b7666038b4d0f201c48cf3637ac5856946e2 [file] [log] [blame]
Nanang Izzuddin57b88572009-04-01 12:05:34 +00001/******************************************************************************
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: samples_to_rmlt_coefs.c
15*
16* Purpose: Convert Samples to Reversed MLT (Modulated Lapped Transform)
17* Coefficients
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: samples_to_rmlt_coefs
38
39 Syntax: Word16 samples_to_rmlt_coefs(new_samples,
40 old_samples,
41 coefs,
42 dct_length)
43 Word16 *new_samples;
44 Word16 *old_samples;
45 Word16 *coefs;
46 Word16 dct_length;
47
48 Description: Convert samples to MLT coefficients
49
50 Design Notes:
51
52 WMOPS: 7kHz | 24kbit | 32kbit
53 -------|--------------|----------------
54 AVG | 1.40 | 1.40
55 -------|--------------|----------------
56 MAX | 1.40 | 1.40
57 -------|--------------|----------------
58
59 14kHz | 24kbit | 32kbit | 48kbit
60 -------|--------------|----------------|----------------
61 AVG | 3.07 | 3.07 | 3.07
62 -------|--------------|----------------|----------------
63 MAX | 3.10 | 3.10 | 3.10
64 -------|--------------|----------------|----------------
65
66***************************************************************************/
67
Benny Prijono8496b932009-04-20 14:19:11 +000068Word16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length)
Nanang Izzuddin57b88572009-04-01 12:05:34 +000069{
70
71 Word16 index, vals_left,mag_shift,n;
72 Word16 windowed_data[MAX_DCT_LENGTH];
Benny Prijono8496b932009-04-20 14:19:11 +000073 Word16 *old_ptr;
74 const Word16 *new_ptr, *sam_low, *sam_high;
Nanang Izzuddin57b88572009-04-01 12:05:34 +000075 Word16 *win_low, *win_high;
76 Word16 *dst_ptr;
77 Word16 neg_win_low;
78 Word16 samp_high;
79 Word16 half_dct_size;
80
81 Word32 acca;
82 Word32 accb;
83 Word16 temp;
84 Word16 temp1;
85 Word16 temp2;
86 Word16 temp5;
87
Benny Prijono3594ab32009-04-18 14:29:28 +000088 half_dct_size = shr_nocheck(dct_length,1);
Nanang Izzuddin57b88572009-04-01 12:05:34 +000089
90 /*++++++++++++++++++++++++++++++++++++++++++++*/
91 /* Get the first half of the windowed samples */
92 /*++++++++++++++++++++++++++++++++++++++++++++*/
93
94 dst_ptr = windowed_data;
95 move16();
96
97 /* address arithmetic */
98 test();
99 if (dct_length==DCT_LENGTH)
100 {
101 win_high = samples_to_rmlt_window + half_dct_size;
102 }
103 else
104 {
105 win_high = max_samples_to_rmlt_window + half_dct_size;
106 }
107
108 win_low = win_high;
109 move16();
110
111 /* address arithmetic */
112 sam_high = old_samples + half_dct_size;
113
114 sam_low = sam_high;
115 move16();
116
117 for (vals_left = half_dct_size;vals_left > 0;vals_left--)
118 {
119 acca = 0L;
120 move32();
121
122 acca = L_mac(acca,*--win_low, *--sam_low);
123 acca = L_mac(acca,*win_high++, *sam_high++);
Nanang Izzuddin56e380a2009-04-15 14:45:41 +0000124 temp = itu_round(acca);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000125
126 *dst_ptr++ = temp;
127 move16();
128 }
129
130 /*+++++++++++++++++++++++++++++++++++++++++++++*/
131 /* Get the second half of the windowed samples */
132 /*+++++++++++++++++++++++++++++++++++++++++++++*/
133
134 sam_low = new_samples;
135 move16();
136
137 /* address arithmetic */
138 sam_high = new_samples + dct_length;
139
140 for (vals_left = half_dct_size; vals_left > 0; vals_left--)
141 {
142 acca = 0L;
143 move32();
144
145 acca = L_mac(acca,*--win_high, *sam_low++);
146 neg_win_low = negate(*win_low++);
147 samp_high = *--sam_high;
148 acca = L_mac(acca, neg_win_low, samp_high);
Nanang Izzuddin56e380a2009-04-15 14:45:41 +0000149 temp = itu_round(acca);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000150
151 *dst_ptr++=temp;
152 move16();
153 }
154
155 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
156 /* Save the new samples for next time, when they will be the old samples */
157 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
158
159 new_ptr = new_samples;
160 move16();
161
162 old_ptr = old_samples;
163 move16();
164
165 for (vals_left = dct_length;vals_left > 0;vals_left--)
166 {
167 *old_ptr++ = *new_ptr++;
168 move16();
169 }
170
171 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
172 /* Calculate how many bits to shift up the input to the DCT. */
173 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
174
175 temp1=0;
176 move16();
177
178 for(index=0;index<dct_length;index++)
179 {
180 temp2 = abs_s(windowed_data[index]);
181 temp = sub(temp2,temp1);
182 test();
183 if(temp > 0)
184 {
185 move16();
186 temp1 = temp2;
187 }
188 }
189
190 mag_shift=0;
191 move16();
192
193 temp = sub(temp1,14000);
194 test();
195 if (temp >= 0)
196 {
197 mag_shift = 0;
198 move16();
199 }
200 else
201 {
202 temp = sub(temp1,438);
203 test();
204 if(temp < 0)
205 temp = add(temp1,1);
206 else
207 {
208 temp = temp1;
209 move16();
210 }
211 accb = L_mult(temp,9587);
Benny Prijono3594ab32009-04-18 14:29:28 +0000212 acca = L_shr_nocheck(accb,20);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000213 temp5 = extract_l(acca);
214 temp = norm_s(temp5);
215 test();
216 if (temp == 0)
217 {
218 mag_shift = 9;
219 move16();
220 }
221 else
222 mag_shift = sub(temp,6);
223
224 }
225
226 acca = 0L;
227 move32();
228 for(index=0; index<dct_length; index++)
229 {
230 temp = abs_s( windowed_data[index]);
231 acca = L_add(acca,temp);
232 }
233
Benny Prijono3594ab32009-04-18 14:29:28 +0000234 acca = L_shr_nocheck(acca,7);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000235
236 test();
237 if (temp1 < acca)
238 {
239 mag_shift = sub(mag_shift,1);
240 }
241
242 test();
243 if (mag_shift > 0)
244 {
245 for(index=0;index<dct_length;index++)
246 {
Benny Prijono3594ab32009-04-18 14:29:28 +0000247 windowed_data[index] = shl_nocheck(windowed_data[index],mag_shift);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000248 }
249 }
250 else
251 {
252 test();
253 if (mag_shift < 0)
254 {
255 n = negate(mag_shift);
256 for(index=0;index<dct_length;index++)
257 {
Benny Prijono3594ab32009-04-18 14:29:28 +0000258 windowed_data[index] = shr_nocheck(windowed_data[index],n);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000259 move16();
260 }
261 }
262 }
263
264 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
265 /* Perform a Type IV DCT on the windowed data to get the coefficients */
266 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
267
268 dct_type_iv_a(windowed_data, coefs, dct_length);
269
270 return(mag_shift);
271}