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