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: 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 | |
| 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 | } |