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 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];
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 for (i = 5; i <= filter_length; i += 2) {
00137 old_out3 = out[-i];
00138 val = filter_coeffs[i-1];
00139
00140 out0 -= val * old_out3;
00141 out1 -= val * old_out0;
00142 out2 -= val * old_out1;
00143 out3 -= val * old_out2;
00144
00145 old_out2 = out[-i-1];
00146
00147 val = filter_coeffs[i];
00148
00149 out0 -= val * old_out2;
00150 out1 -= val * old_out3;
00151 out2 -= val * old_out0;
00152 out3 -= val * old_out1;
00153
00154 FFSWAP(float, old_out0, old_out2);
00155 old_out1 = old_out3;
00156 }
00157
00158 tmp0 = out0;
00159 tmp1 = out1;
00160 tmp2 = out2;
00161
00162 out3 -= a * tmp2;
00163 out2 -= a * tmp1;
00164 out1 -= a * tmp0;
00165
00166 out3 -= b * tmp1;
00167 out2 -= b * tmp0;
00168
00169 out3 -= c * tmp0;
00170
00171
00172 out[0] = out0;
00173 out[1] = out1;
00174 out[2] = out2;
00175 out[3] = out3;
00176
00177 old_out0 = out0;
00178 old_out1 = out1;
00179 old_out2 = out2;
00180 old_out3 = out3;
00181
00182 out += 4;
00183 in += 4;
00184 }
00185
00186 out -= n;
00187 in -= n;
00188 for (; n < buffer_length; n++) {
00189 out[n] = in[n];
00190 for (i = 1; i <= filter_length; i++)
00191 out[n] -= filter_coeffs[i-1] * out[n-i];
00192 }
00193 #endif
00194 }
00195
00196 void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs,
00197 const float *in, int buffer_length,
00198 int filter_length)
00199 {
00200 int i,n;
00201
00202 for (n = 0; n < buffer_length; n++) {
00203 out[n] = in[n];
00204 for (i = 1; i <= filter_length; i++)
00205 out[n] += filter_coeffs[i-1] * in[n-i];
00206 }
00207 }