00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "libavutil/attributes.h"
00023 #include "aacpsdsp.h"
00024
00025 static void ps_add_squares_c(float *dst, const float (*src)[2], int n)
00026 {
00027 int i;
00028 for (i = 0; i < n; i++)
00029 dst[i] += src[i][0] * src[i][0] + src[i][1] * src[i][1];
00030 }
00031
00032 static void ps_mul_pair_single_c(float (*dst)[2], float (*src0)[2], float *src1,
00033 int n)
00034 {
00035 int i;
00036 for (i = 0; i < n; i++) {
00037 dst[i][0] = src0[i][0] * src1[i];
00038 dst[i][1] = src0[i][1] * src1[i];
00039 }
00040 }
00041
00042 static void ps_hybrid_analysis_c(float (*out)[2], float (*in)[2],
00043 const float (*filter)[8][2],
00044 int stride, int n)
00045 {
00046 int i, j;
00047
00048 for (i = 0; i < n; i++) {
00049 float sum_re = filter[i][6][0] * in[6][0];
00050 float sum_im = filter[i][6][0] * in[6][1];
00051
00052 for (j = 0; j < 6; j++) {
00053 float in0_re = in[j][0];
00054 float in0_im = in[j][1];
00055 float in1_re = in[12-j][0];
00056 float in1_im = in[12-j][1];
00057 sum_re += filter[i][j][0] * (in0_re + in1_re) -
00058 filter[i][j][1] * (in0_im - in1_im);
00059 sum_im += filter[i][j][0] * (in0_im + in1_im) +
00060 filter[i][j][1] * (in0_re - in1_re);
00061 }
00062 out[i * stride][0] = sum_re;
00063 out[i * stride][1] = sum_im;
00064 }
00065 }
00066
00067 static void ps_hybrid_analysis_ileave_c(float (*out)[32][2], float L[2][38][64],
00068 int i, int len)
00069 {
00070 int j;
00071
00072 for (; i < 64; i++) {
00073 for (j = 0; j < len; j++) {
00074 out[i][j][0] = L[0][j][i];
00075 out[i][j][1] = L[1][j][i];
00076 }
00077 }
00078 }
00079
00080 static void ps_hybrid_synthesis_deint_c(float out[2][38][64],
00081 float (*in)[32][2],
00082 int i, int len)
00083 {
00084 int n;
00085
00086 for (; i < 64; i++) {
00087 for (n = 0; n < len; n++) {
00088 out[0][n][i] = in[i][n][0];
00089 out[1][n][i] = in[i][n][1];
00090 }
00091 }
00092 }
00093
00094 static void ps_decorrelate_c(float (*out)[2], float (*delay)[2],
00095 float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
00096 const float phi_fract[2], float (*Q_fract)[2],
00097 const float *transient_gain,
00098 float g_decay_slope,
00099 int len)
00100 {
00101 static const float a[] = { 0.65143905753106f,
00102 0.56471812200776f,
00103 0.48954165955695f };
00104 float ag[PS_AP_LINKS];
00105 int m, n;
00106
00107 for (m = 0; m < PS_AP_LINKS; m++)
00108 ag[m] = a[m] * g_decay_slope;
00109
00110 for (n = 0; n < len; n++) {
00111 float in_re = delay[n][0] * phi_fract[0] - delay[n][1] * phi_fract[1];
00112 float in_im = delay[n][0] * phi_fract[1] + delay[n][1] * phi_fract[0];
00113 for (m = 0; m < PS_AP_LINKS; m++) {
00114 float a_re = ag[m] * in_re;
00115 float a_im = ag[m] * in_im;
00116 float link_delay_re = ap_delay[m][n+2-m][0];
00117 float link_delay_im = ap_delay[m][n+2-m][1];
00118 float fractional_delay_re = Q_fract[m][0];
00119 float fractional_delay_im = Q_fract[m][1];
00120 float apd_re = in_re;
00121 float apd_im = in_im;
00122 in_re = link_delay_re * fractional_delay_re -
00123 link_delay_im * fractional_delay_im - a_re;
00124 in_im = link_delay_re * fractional_delay_im +
00125 link_delay_im * fractional_delay_re - a_im;
00126 ap_delay[m][n+5][0] = apd_re + ag[m] * in_re;
00127 ap_delay[m][n+5][1] = apd_im + ag[m] * in_im;
00128 }
00129 out[n][0] = transient_gain[n] * in_re;
00130 out[n][1] = transient_gain[n] * in_im;
00131 }
00132 }
00133
00134 static void ps_stereo_interpolate_c(float (*l)[2], float (*r)[2],
00135 float h[2][4], float h_step[2][4],
00136 int len)
00137 {
00138 float h0 = h[0][0];
00139 float h1 = h[0][1];
00140 float h2 = h[0][2];
00141 float h3 = h[0][3];
00142 float hs0 = h_step[0][0];
00143 float hs1 = h_step[0][1];
00144 float hs2 = h_step[0][2];
00145 float hs3 = h_step[0][3];
00146 int n;
00147
00148 for (n = 0; n < len; n++) {
00149
00150 float l_re = l[n][0];
00151 float l_im = l[n][1];
00152 float r_re = r[n][0];
00153 float r_im = r[n][1];
00154 h0 += hs0;
00155 h1 += hs1;
00156 h2 += hs2;
00157 h3 += hs3;
00158 l[n][0] = h0 * l_re + h2 * r_re;
00159 l[n][1] = h0 * l_im + h2 * r_im;
00160 r[n][0] = h1 * l_re + h3 * r_re;
00161 r[n][1] = h1 * l_im + h3 * r_im;
00162 }
00163 }
00164
00165 static void ps_stereo_interpolate_ipdopd_c(float (*l)[2], float (*r)[2],
00166 float h[2][4], float h_step[2][4],
00167 int len)
00168 {
00169 float h00 = h[0][0], h10 = h[1][0];
00170 float h01 = h[0][1], h11 = h[1][1];
00171 float h02 = h[0][2], h12 = h[1][2];
00172 float h03 = h[0][3], h13 = h[1][3];
00173 float hs00 = h_step[0][0], hs10 = h_step[1][0];
00174 float hs01 = h_step[0][1], hs11 = h_step[1][1];
00175 float hs02 = h_step[0][2], hs12 = h_step[1][2];
00176 float hs03 = h_step[0][3], hs13 = h_step[1][3];
00177 int n;
00178
00179 for (n = 0; n < len; n++) {
00180
00181 float l_re = l[n][0];
00182 float l_im = l[n][1];
00183 float r_re = r[n][0];
00184 float r_im = r[n][1];
00185 h00 += hs00;
00186 h01 += hs01;
00187 h02 += hs02;
00188 h03 += hs03;
00189 h10 += hs10;
00190 h11 += hs11;
00191 h12 += hs12;
00192 h13 += hs13;
00193
00194 l[n][0] = h00 * l_re + h02 * r_re - h10 * l_im - h12 * r_im;
00195 l[n][1] = h00 * l_im + h02 * r_im + h10 * l_re + h12 * r_re;
00196 r[n][0] = h01 * l_re + h03 * r_re - h11 * l_im - h13 * r_im;
00197 r[n][1] = h01 * l_im + h03 * r_im + h11 * l_re + h13 * r_re;
00198 }
00199 }
00200
00201 av_cold void ff_psdsp_init(PSDSPContext *s)
00202 {
00203 s->add_squares = ps_add_squares_c;
00204 s->mul_pair_single = ps_mul_pair_single_c;
00205 s->hybrid_analysis = ps_hybrid_analysis_c;
00206 s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c;
00207 s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c;
00208 s->decorrelate = ps_decorrelate_c;
00209 s->stereo_interpolate[0] = ps_stereo_interpolate_c;
00210 s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c;
00211
00212 if (ARCH_ARM)
00213 ff_psdsp_init_arm(s);
00214 }