/* * g722_1 - a library for the G.722.1 and Annex C codecs * * sam2coef.c * * Adapted by Steve Underwood from the reference * code supplied with ITU G.722.1, which is: * * (C) 2004 Polycom, Inc. * All rights reserved. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /*! \file */ #if defined(HAVE_CONFIG_H) #include #endif #include #include #include "g722_1/g722_1.h" #include "defs.h" #include "sam2coef.h" #include "utilities.h" /* Convert Samples to Reversed MLT (Modulated Lapped Transform) Coefficients The "Reversed MLT" is an overlapped block transform which uses even symmetry on the left, odd symmetry on the right and a Type IV DCT as the block transform. It is thus similar to a MLT which uses odd symmetry on the left, even symmetry on the right and a Type IV DST as the block transform. In fact, it is equivalent to reversing the order of the samples, performing an MLT and then negating all the even-numbered coefficients. */ #if defined(G722_1_USE_FIXED_POINT) int16_t samples_to_rmlt_coefs(const int16_t new_samples[], int16_t old_samples[], int16_t coefs[], int dct_length) { int i; int half_dct_length; int last; int16_t mag_shift; int16_t n; int16_t windowed_data[MAX_DCT_LENGTH]; const int16_t *win; int32_t acca; int32_t accb; int16_t temp; int16_t temp1; int16_t temp2; half_dct_length = dct_length >> 1; win = (dct_length == DCT_LENGTH) ? samples_to_rmlt_window : max_samples_to_rmlt_window; /* Get the first half of the windowed samples */ last = half_dct_length - 1; for (i = 0; i < half_dct_length; i++) { acca = L_mult(win[last - i], old_samples[last - i]); acca = L_mac(acca, win[half_dct_length + i], old_samples[half_dct_length + i]); windowed_data[i] = xround(acca); } /* Get the second half of the windowed samples */ last = dct_length - 1; for (i = 0; i < half_dct_length; i++) { acca = L_mult(win[last - i], new_samples[i]); acca = L_mac(acca, negate(win[i]), new_samples[last - i]); windowed_data[half_dct_length + i] = xround(acca); } /* Save the new samples for next time, when they will be the old samples. */ vec_copyi16(old_samples, new_samples, dct_length); /* Calculate how many bits to shift up the input to the DCT. */ temp1 = 0; for (i = 0; i < dct_length; i++) { temp2 = abs_s(windowed_data[i]); temp = sub(temp2, temp1); if (temp > 0) temp1 = temp2; } mag_shift = 0; temp = sub(temp1, 14000); if (temp < 0) { temp = sub(temp1, 438); temp = (temp < 0) ? add(temp1, 1) : temp1; accb = L_mult(temp, 9587); acca = L_shr(accb, 20); temp = norm_s((int16_t) acca); mag_shift = (temp == 0) ? 9 : sub(temp, 6); } acca = 0; for (i = 0; i < dct_length; i++) { temp = abs_s(windowed_data[i]); acca = L_add(acca, temp); } acca = L_shr(acca, 7); if (temp1 < acca) mag_shift = sub(mag_shift, 1); if (mag_shift > 0) { for (i = 0; i < dct_length; i++) windowed_data[i] = shl(windowed_data[i], mag_shift); } else if (mag_shift < 0) { n = negate(mag_shift); for (i = 0; i < dct_length; i++) windowed_data[i] = shr(windowed_data[i], n); } /* Perform a Type IV DCT on the windowed data to get the coefficients */ dct_type_iv_a(windowed_data, coefs, dct_length); return mag_shift; } /*- End of function --------------------------------------------------------*/ #else void samples_to_rmlt_coefs(const float new_samples[], float old_samples[], float coefs[], int dct_length) { int i; int half_dct_length; int last; float sum; float windowed_data[MAX_DCT_LENGTH]; const float *win; half_dct_length = dct_length >> 1; win = (dct_length == DCT_LENGTH) ? samples_to_rmlt_window : max_samples_to_rmlt_window; /* Get the first half of the windowed samples. */ last = half_dct_length - 1; for (i = 0; i < half_dct_length; i++) { sum = win[last - i]*old_samples[last - i]; sum += win[half_dct_length + i]*old_samples[half_dct_length + i]; windowed_data[i] = sum; } /* Get the second half of the windowed samples. */ last = dct_length - 1; for (i = 0; i < half_dct_length; i++) { sum = win[last - i]*new_samples[i]; sum -= win[i]*new_samples[last - i]; windowed_data[half_dct_length + i] = sum; } /* Save the new samples for next time, when they will be the old samples. */ vec_copyf(old_samples, new_samples, dct_length); /* Perform a Type IV DCT on the windowed data to get the coefficients. */ dct_type_iv(windowed_data, coefs, dct_length); } /*- End of function --------------------------------------------------------*/ #endif /*- End of file ------------------------------------------------------------*/