Alexandre Lision | 8af73cb | 2013-12-10 14:11:20 -0500 | [diff] [blame] | 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: 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 | |
| 68 | Word16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length) |
| 69 | { |
| 70 | |
| 71 | Word16 index, vals_left,mag_shift,n; |
| 72 | Word16 windowed_data[MAX_DCT_LENGTH]; |
| 73 | Word16 *old_ptr; |
| 74 | const Word16 *new_ptr, *sam_low, *sam_high; |
| 75 | 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 | |
| 88 | half_dct_size = shr_nocheck(dct_length,1); |
| 89 | |
| 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++); |
| 124 | temp = itu_round(acca); |
| 125 | |
| 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); |
| 149 | temp = itu_round(acca); |
| 150 | |
| 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); |
| 212 | acca = L_shr_nocheck(accb,20); |
| 213 | 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 | |
| 234 | acca = L_shr_nocheck(acca,7); |
| 235 | |
| 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 | { |
| 247 | windowed_data[index] = shl_nocheck(windowed_data[index],mag_shift); |
| 248 | } |
| 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 | { |
| 258 | windowed_data[index] = shr_nocheck(windowed_data[index],n); |
| 259 | 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 | } |