1
/*********************************************************************************
2
** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
3
** > Software Release 2.1 (2008-06)
4
** (Simple repackaging; no change from 2005-05 Release 2.0 code)
6
** � 2004 Polycom, Inc.
8
** All rights reserved.
10
*********************************************************************************/
12
/*********************************************************************************
13
* Filename: dct_type_iv_a.c
15
* Purpose: Discrete Cosine Transform, Type IV used for MLT
17
* The basis functions are
19
* cos(PI*(t+0.5)*(k+0.5)/block_length)
21
* for time t and basis function number k. Due to the symmetry of the expression
22
* in t and k, it is clear that the forward and inverse transforms are the same.
24
*********************************************************************************/
26
/*********************************************************************************
28
*********************************************************************************/
33
/*********************************************************************************
34
External variable declarations
35
*********************************************************************************/
36
extern Word16 anal_bias[DCT_LENGTH];
37
extern Word16 dct_core_a[DCT_LENGTH_DIV_32][DCT_LENGTH_DIV_32];
38
extern cos_msin_t a_cos_msin_2 [DCT_LENGTH_DIV_32];
39
extern cos_msin_t a_cos_msin_4 [DCT_LENGTH_DIV_16];
40
extern cos_msin_t a_cos_msin_8 [DCT_LENGTH_DIV_8];
41
extern cos_msin_t a_cos_msin_16[DCT_LENGTH_DIV_4];
42
extern cos_msin_t a_cos_msin_32[DCT_LENGTH_DIV_2];
43
extern cos_msin_t a_cos_msin_64[DCT_LENGTH];
44
extern cos_msin_t *a_cos_msin_table[];
46
/*********************************************************************************
47
Function: dct_type_iv_a
49
Syntax: void dct_type_iv_a (input, output, dct_length)
50
Word16 input[], output[], dct_length;
52
Description: Discrete Cosine Transform, Type IV used for MLT
56
WMOPS: | 24kbit | 32kbit
57
-------|--------------|----------------
59
-------|--------------|----------------
61
-------|--------------|----------------
63
14kHz | 24kbit | 32kbit | 48kbit
64
-------|--------------|----------------|----------------
65
AVG | 2.57 | 2.57 | 2.57
66
-------|--------------|----------------|----------------
67
MAX | 2.57 | 2.57 | 2.57
68
-------|--------------|----------------|----------------
70
*********************************************************************************/
72
void dct_type_iv_a (Word16 *input,Word16 *output,Word16 dct_length)
74
Word16 buffer_a[MAX_DCT_LENGTH], buffer_b[MAX_DCT_LENGTH], buffer_c[MAX_DCT_LENGTH];
75
Word16 *in_ptr, *in_ptr_low, *in_ptr_high, *next_in_base;
76
Word16 *out_ptr_low, *out_ptr_high, *next_out_base;
77
Word16 *out_buffer, *in_buffer, *buffer_swap;
78
Word16 in_val_low, in_val_high;
79
Word16 out_val_low, out_val_high;
80
Word16 in_low_even, in_low_odd;
81
Word16 in_high_even, in_high_odd;
82
Word16 out_low_even, out_low_odd;
83
Word16 out_high_even, out_high_odd;
85
Word16 cos_even, cos_odd, msin_even, msin_odd;
89
Word16 set_span, set_count, set_count_log, pairs_left, sets_left;
92
cos_msin_t **table_ptr_ptr, *cos_msin_ptr;
97
Word16 dct_length_log;
100
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
101
/* Do the sum/difference butterflies, the first part of */
102
/* converting one N-point transform into N/2 two-point */
103
/* transforms, where N = 1 << DCT_LENGTH_LOG. = 64/128 */
104
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
106
if (dct_length==DCT_LENGTH)
108
dct_length_log = DCT_LENGTH_LOG;
110
/* Add bias offsets */
111
for (i=0;i<dct_length;i++)
113
input[i] = add(input[i],anal_bias[i]);
118
dct_length_log = MAX_DCT_LENGTH_LOG;
126
out_buffer = buffer_a;
129
temp = sub(dct_length_log,2);
130
for (set_count_log=0;set_count_log<=temp;set_count_log++)
133
/*===========================================================*/
134
/* Initialization for the loop over sets at the current size */
135
/*===========================================================*/
137
/* set_span = 1 << (DCT_LENGTH_LOG - set_count_log); */
138
set_span = shr_nocheck(dct_length,set_count_log);
140
set_count = shl_nocheck(1,set_count_log);
145
next_out_base = out_buffer;
148
/*=====================================*/
149
/* Loop over all the sets of this size */
150
/*=====================================*/
152
for (sets_left=set_count;sets_left>0;sets_left--)
155
/*||||||||||||||||||||||||||||||||||||||||||||*/
156
/* Set up output pointers for the current set */
157
/*||||||||||||||||||||||||||||||||||||||||||||*/
159
out_ptr_low = next_out_base;
160
next_out_base = next_out_base + set_span;
161
out_ptr_high = next_out_base;
163
/*||||||||||||||||||||||||||||||||||||||||||||||||||*/
164
/* Loop over all the butterflies in the current set */
165
/*||||||||||||||||||||||||||||||||||||||||||||||||||*/
169
in_val_low = *in_ptr++;
170
in_val_high = *in_ptr++;
171
// blp: addition of two 16bits vars, there's no way
172
// they'll overflow a 32bit var
173
//acca = L_add(in_val_low,in_val_high);
174
acca = (in_val_low + in_val_high);
175
acca = L_shr_nocheck(acca,1);
176
out_val_low = extract_l(acca);
178
acca = L_sub(in_val_low,in_val_high);
179
acca = L_shr_nocheck(acca,1);
180
out_val_high = extract_l(acca);
182
*out_ptr_low++ = out_val_low;
183
*--out_ptr_high = out_val_high;
186
} while (out_ptr_low < out_ptr_high);
188
} /* End of loop over sets of the current size */
190
/*============================================================*/
191
/* Decide which buffers to use as input and output next time. */
192
/* Except for the first time (when the input buffer is the */
193
/* subroutine input) we just alternate the local buffers. */
194
/*============================================================*/
196
in_buffer = out_buffer;
198
if (out_buffer == buffer_a)
199
out_buffer = buffer_b;
201
out_buffer = buffer_a;
202
index = add(index,1);
204
} /* End of loop over set sizes */
207
/*++++++++++++++++++++++++++++++++*/
208
/* Do N/2 two-point transforms, */
209
/* where N = 1 << DCT_LENGTH_LOG */
210
/*++++++++++++++++++++++++++++++++*/
212
pair_ptr = in_buffer;
215
buffer_swap = buffer_c;
218
temp = sub(dct_length_log,1);
219
temp = shl_nocheck(1,temp);
221
for (pairs_left=temp; pairs_left > 0; pairs_left--)
223
for ( k=0; k<CORE_SIZE; k++ )
226
/* blp: danger danger! not really compatible but faster */
230
for ( i=0; i<CORE_SIZE; i++ )
232
sum64 += L_mult(pair_ptr[i], dct_core_a[i][k]);
234
sum = L_saturate(sum64);
238
for ( i=0; i<CORE_SIZE; i++ )
240
sum = L_mac(sum, pair_ptr[i],dct_core_a[i][k]);
243
buffer_swap[k] = itu_round(sum);
245
/* address arithmetic */
246
pair_ptr += CORE_SIZE;
247
buffer_swap += CORE_SIZE;
250
for (i=0;i<dct_length;i++)
252
in_buffer[i] = buffer_c[i];
256
table_ptr_ptr = a_cos_msin_table;
258
/*++++++++++++++++++++++++++++++*/
259
/* Perform rotation butterflies */
260
/*++++++++++++++++++++++++++++++*/
261
temp = sub(dct_length_log,2);
262
for (set_count_log = temp; set_count_log >= 0; set_count_log--)
264
/*===========================================================*/
265
/* Initialization for the loop over sets at the current size */
266
/*===========================================================*/
267
/* set_span = 1 << (DCT_LENGTH_LOG - set_count_log); */
268
set_span = shr_nocheck(dct_length,set_count_log);
270
set_count = shl_nocheck(1,set_count_log);
271
next_in_base = in_buffer;
275
if (set_count_log == 0)
277
next_out_base = output;
281
next_out_base = out_buffer;
285
/*=====================================*/
286
/* Loop over all the sets of this size */
287
/*=====================================*/
288
for (sets_left = set_count; sets_left > 0;sets_left--)
290
/*|||||||||||||||||||||||||||||||||||||||||*/
291
/* Set up the pointers for the current set */
292
/*|||||||||||||||||||||||||||||||||||||||||*/
293
in_ptr_low = next_in_base;
295
temp = shr_nocheck(set_span,1);
297
/* address arithmetic */
298
in_ptr_high = in_ptr_low + temp;
299
next_in_base += set_span;
300
out_ptr_low = next_out_base;
301
next_out_base += set_span;
302
out_ptr_high = next_out_base;
303
cos_msin_ptr = *table_ptr_ptr;
305
/*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
306
/* Loop over all the butterfly pairs in the current set */
307
/*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
311
/* address arithmetic */
312
in_low_even = *in_ptr_low++;
313
in_low_odd = *in_ptr_low++;
314
in_high_even = *in_ptr_high++;
315
in_high_odd = *in_ptr_high++;
316
cos_even = cos_msin_ptr[0].cosine;
318
msin_even = cos_msin_ptr[0].minus_sine;
320
cos_odd = cos_msin_ptr[1].cosine;
322
msin_odd = cos_msin_ptr[1].minus_sine;
327
sum=L_mac(sum,cos_even,in_low_even);
328
neg_msin_even = negate(msin_even);
329
sum=L_mac(sum,neg_msin_even,in_high_even);
330
out_low_even = itu_round(sum);
333
sum=L_mac(sum,msin_even,in_low_even);
334
sum=L_mac(sum,cos_even,in_high_even);
335
out_high_even= itu_round(sum);
338
sum=L_mac(sum,cos_odd,in_low_odd);
339
sum=L_mac(sum,msin_odd,in_high_odd);
340
out_low_odd= itu_round(sum);
343
sum=L_mac(sum,msin_odd,in_low_odd);
344
neg_cos_odd = negate(cos_odd);
345
sum=L_mac(sum,neg_cos_odd,in_high_odd);
346
out_high_odd= itu_round(sum);
348
*out_ptr_low++ = out_low_even;
349
*--out_ptr_high = out_high_even;
350
*out_ptr_low++ = out_low_odd;
351
*--out_ptr_high = out_high_odd;
353
} while (out_ptr_low < out_ptr_high);
355
} /* End of loop over sets of the current size */
357
/*=============================================*/
358
/* Swap input and output buffers for next time */
359
/*=============================================*/
361
buffer_swap = in_buffer;
362
in_buffer = out_buffer;
363
out_buffer = buffer_swap;