blob: 18a88acdd717d25d5b0c858c3c01226adc41ae10 [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: 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
73void 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(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(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(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++ = round(L_shl(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++ = round(L_shl(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}