00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <inttypes.h>
00024
00025 #include "avcodec.h"
00026 #include "celp_filters.h"
00027
00028 void ff_celp_convolve_circ(int16_t* fc_out, const int16_t* fc_in,
00029 const int16_t* filter, int len)
00030 {
00031 int i, k;
00032
00033 memset(fc_out, 0, len * sizeof(int16_t));
00034
00035
00036
00037 for (i = 0; i < len; i++) {
00038 if (fc_in[i]) {
00039 for (k = 0; k < i; k++)
00040 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
00041
00042 for (k = i; k < len; k++)
00043 fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
00044 }
00045 }
00046 }
00047
00048 void ff_celp_circ_addf(float *out, const float *in,
00049 const float *lagged, int lag, float fac, int n)
00050 {
00051 int k;
00052 for (k = 0; k < lag; k++)
00053 out[k] = in[k] + fac * lagged[n + k - lag];
00054 for (; k < n; k++)
00055 out[k] = in[k] + fac * lagged[ k - lag];
00056 }
00057
00058 int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs,
00059 const int16_t *in, int buffer_length,
00060 int filter_length, int stop_on_overflow,
00061 int shift, int rounder)
00062 {
00063 int i,n;
00064
00065 for (n = 0; n < buffer_length; n++) {
00066 int sum = rounder;
00067 for (i = 1; i <= filter_length; i++)
00068 sum -= filter_coeffs[i-1] * out[n-i];
00069
00070 sum = ((sum >> 12) + in[n]) >> shift;
00071
00072 if (sum + 0x8000 > 0xFFFFU) {
00073 if (stop_on_overflow)
00074 return 1;
00075 sum = (sum >> 31) ^ 32767;
00076 }
00077 out[n] = sum;
00078 }
00079
00080 return 0;
00081 }
00082
00083 void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
00084 const float* in, int buffer_length,
00085 int filter_length)
00086 {
00087 int i,n;
00088
00089 #if 0 // Unoptimized code path for improved readability
00090 for (n = 0; n < buffer_length; n++) {
00091 out[n] = in[n];
00092 for (i = 1; i <= filter_length; i++)
00093 out[n] -= filter_coeffs[i-1] * out[n-i];
00094 }
00095 #else
00096 float out0, out1, out2, out3;
00097 float old_out0, old_out1, old_out2, old_out3;
00098 float a,b,c;
00099
00100 a = filter_coeffs[0];
00101 b = filter_coeffs[1];
00102 c = filter_coeffs[2];
00103 b -= filter_coeffs[0] * filter_coeffs[0];
00104 c -= filter_coeffs[1] * filter_coeffs[0];
00105 c -= filter_coeffs[0] * b;
00106
00107 old_out0 = out[-4];
00108 old_out1 = out[-3];
00109 old_out2 = out[-2];
00110 old_out3 = out[-1];
00111 for (n = 0; n <= buffer_length - 4; n+=4) {
00112 float tmp0,tmp1,tmp2;
00113 float val;
00114
00115 out0 = in[0];
00116 out1 = in[1];
00117 out2 = in[2];
00118 out3 = in[3];
00119
00120 out0 -= filter_coeffs[2] * old_out1;
00121 out1 -= filter_coeffs[2] * old_out2;
00122 out2 -= filter_coeffs[2] * old_out3;
00123
00124 out0 -= filter_coeffs[1] * old_out2;
00125 out1 -= filter_coeffs[1] * old_out3;
00126
00127 out0 -= filter_coeffs[0] * old_out3;
00128
00129 val = filter_coeffs[3];
00130
00131 out0 -= val * old_out0;
00132 out1 -= val * old_out1;
00133 out2 -= val * old_out2;
00134 out3 -= val * old_out3;
00135
00136 old_out3 = out[-5];
00137
00138 for (i = 5; i <= filter_length; i += 2) {
00139 val = filter_coeffs[i-1];
00140
00141 out0 -= val * old_out3;
00142 out1 -= val * old_out0;
00143 out2 -= val * old_out1;
00144 out3 -= val * old_out2;
00145
00146 old_out2 = out[-i-1];
00147
00148 val = filter_coeffs[i];
00149
00150 out0 -= val * old_out2;
00151 out1 -= val * old_out3;
00152 out2 -= val * old_out0;
00153 out3 -= val * old_out1;
00154
00155 FFSWAP(float, old_out0, old_out2);
00156 old_out1 = old_out3;
00157 old_out3 = out[-i-2];
00158 }
00159
00160 tmp0 = out0;
00161 tmp1 = out1;
00162 tmp2 = out2;
00163
00164 out3 -= a * tmp2;
00165 out2 -= a * tmp1;
00166 out1 -= a * tmp0;
00167
00168 out3 -= b * tmp1;
00169 out2 -= b * tmp0;
00170
00171 out3 -= c * tmp0;
00172
00173
00174 out[0] = out0;
00175 out[1] = out1;
00176 out[2] = out2;
00177 out[3] = out3;
00178
00179 old_out0 = out0;
00180 old_out1 = out1;
00181 old_out2 = out2;
00182 old_out3 = out3;
00183
00184 out += 4;
00185 in += 4;
00186 }
00187
00188 out -= n;
00189 in -= n;
00190 for (; n < buffer_length; n++) {
00191 out[n] = in[n];
00192 for (i = 1; i <= filter_length; i++)
00193 out[n] -= filter_coeffs[i-1] * out[n-i];
00194 }
00195 #endif
00196 }
00197
00198 void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs,
00199 const float *in, int buffer_length,
00200 int filter_length)
00201 {
00202 int i,n;
00203
00204 for (n = 0; n < buffer_length; n++) {
00205 out[n] = in[n];
00206 for (i = 1; i <= filter_length; i++)
00207 out[n] += filter_coeffs[i-1] * in[n-i];
00208 }
00209 }