annotate ffmpeg/libavcodec/sbrdsp.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * AAC Spectral Band Replication decoding functions
yading@10 3 * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
yading@10 4 * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
yading@10 5 *
yading@10 6 * This file is part of Libav.
yading@10 7 *
yading@10 8 * Libav is free software; you can redistribute it and/or
yading@10 9 * modify it under the terms of the GNU Lesser General Public
yading@10 10 * License as published by the Free Software Foundation; either
yading@10 11 * version 2.1 of the License, or (at your option) any later version.
yading@10 12 *
yading@10 13 * Libav is distributed in the hope that it will be useful,
yading@10 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 16 * Lesser General Public License for more details.
yading@10 17 *
yading@10 18 * You should have received a copy of the GNU Lesser General Public
yading@10 19 * License along with Libav; if not, write to the Free Software
yading@10 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 21 */
yading@10 22
yading@10 23 #include "config.h"
yading@10 24 #include "libavutil/attributes.h"
yading@10 25 #include "libavutil/intfloat.h"
yading@10 26 #include "sbrdsp.h"
yading@10 27
yading@10 28 static void sbr_sum64x5_c(float *z)
yading@10 29 {
yading@10 30 int k;
yading@10 31 for (k = 0; k < 64; k++) {
yading@10 32 float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
yading@10 33 z[k] = f;
yading@10 34 }
yading@10 35 }
yading@10 36
yading@10 37 static float sbr_sum_square_c(float (*x)[2], int n)
yading@10 38 {
yading@10 39 float sum0 = 0.0f, sum1 = 0.0f;
yading@10 40 int i;
yading@10 41
yading@10 42 for (i = 0; i < n; i += 2)
yading@10 43 {
yading@10 44 sum0 += x[i + 0][0] * x[i + 0][0];
yading@10 45 sum1 += x[i + 0][1] * x[i + 0][1];
yading@10 46 sum0 += x[i + 1][0] * x[i + 1][0];
yading@10 47 sum1 += x[i + 1][1] * x[i + 1][1];
yading@10 48 }
yading@10 49
yading@10 50 return sum0 + sum1;
yading@10 51 }
yading@10 52
yading@10 53 static void sbr_neg_odd_64_c(float *x)
yading@10 54 {
yading@10 55 union av_intfloat32 *xi = (union av_intfloat32*)x;
yading@10 56 int i;
yading@10 57 for (i = 1; i < 64; i += 4)
yading@10 58 {
yading@10 59 xi[i+0].i ^= 1U<<31;
yading@10 60 xi[i+2].i ^= 1U<<31;
yading@10 61 }
yading@10 62 }
yading@10 63
yading@10 64 static void sbr_qmf_pre_shuffle_c(float *z)
yading@10 65 {
yading@10 66 union av_intfloat32 *zi = (union av_intfloat32*)z;
yading@10 67 int k;
yading@10 68 zi[64].i = zi[0].i;
yading@10 69 zi[65].i = zi[1].i;
yading@10 70 for (k = 1; k < 31; k+=2) {
yading@10 71 zi[64+2*k+0].i = zi[64 - k].i ^ (1U<<31);
yading@10 72 zi[64+2*k+1].i = zi[ k + 1].i;
yading@10 73 zi[64+2*k+2].i = zi[63 - k].i ^ (1U<<31);
yading@10 74 zi[64+2*k+3].i = zi[ k + 2].i;
yading@10 75 }
yading@10 76 zi[64+2*31+0].i = zi[64 - 31].i ^ (1U<<31);
yading@10 77 zi[64+2*31+1].i = zi[31 + 1].i;
yading@10 78 }
yading@10 79
yading@10 80 static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z)
yading@10 81 {
yading@10 82 const union av_intfloat32 *zi = (const union av_intfloat32*)z;
yading@10 83 union av_intfloat32 *Wi = (union av_intfloat32*)W;
yading@10 84 int k;
yading@10 85 for (k = 0; k < 32; k+=2) {
yading@10 86 Wi[2*k+0].i = zi[63-k].i ^ (1U<<31);
yading@10 87 Wi[2*k+1].i = zi[k+0].i;
yading@10 88 Wi[2*k+2].i = zi[62-k].i ^ (1U<<31);
yading@10 89 Wi[2*k+3].i = zi[k+1].i;
yading@10 90 }
yading@10 91 }
yading@10 92
yading@10 93 static void sbr_qmf_deint_neg_c(float *v, const float *src)
yading@10 94 {
yading@10 95 const union av_intfloat32 *si = (const union av_intfloat32*)src;
yading@10 96 union av_intfloat32 *vi = (union av_intfloat32*)v;
yading@10 97 int i;
yading@10 98 for (i = 0; i < 32; i++) {
yading@10 99 vi[ i].i = si[63 - 2*i ].i;
yading@10 100 vi[63 - i].i = si[63 - 2*i - 1].i ^ (1U<<31);
yading@10 101 }
yading@10 102 }
yading@10 103
yading@10 104 static void sbr_qmf_deint_bfly_c(float *v, const float *src0, const float *src1)
yading@10 105 {
yading@10 106 int i;
yading@10 107 for (i = 0; i < 64; i++) {
yading@10 108 v[ i] = src0[i] - src1[63 - i];
yading@10 109 v[127 - i] = src0[i] + src1[63 - i];
yading@10 110 }
yading@10 111 }
yading@10 112
yading@10 113 static av_always_inline void autocorrelate(const float x[40][2],
yading@10 114 float phi[3][2][2], int lag)
yading@10 115 {
yading@10 116 int i;
yading@10 117 float real_sum = 0.0f;
yading@10 118 float imag_sum = 0.0f;
yading@10 119 if (lag) {
yading@10 120 for (i = 1; i < 38; i++) {
yading@10 121 real_sum += x[i][0] * x[i+lag][0] + x[i][1] * x[i+lag][1];
yading@10 122 imag_sum += x[i][0] * x[i+lag][1] - x[i][1] * x[i+lag][0];
yading@10 123 }
yading@10 124 phi[2-lag][1][0] = real_sum + x[ 0][0] * x[lag][0] + x[ 0][1] * x[lag][1];
yading@10 125 phi[2-lag][1][1] = imag_sum + x[ 0][0] * x[lag][1] - x[ 0][1] * x[lag][0];
yading@10 126 if (lag == 1) {
yading@10 127 phi[0][0][0] = real_sum + x[38][0] * x[39][0] + x[38][1] * x[39][1];
yading@10 128 phi[0][0][1] = imag_sum + x[38][0] * x[39][1] - x[38][1] * x[39][0];
yading@10 129 }
yading@10 130 } else {
yading@10 131 for (i = 1; i < 38; i++) {
yading@10 132 real_sum += x[i][0] * x[i][0] + x[i][1] * x[i][1];
yading@10 133 }
yading@10 134 phi[2][1][0] = real_sum + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
yading@10 135 phi[1][0][0] = real_sum + x[38][0] * x[38][0] + x[38][1] * x[38][1];
yading@10 136 }
yading@10 137 }
yading@10 138
yading@10 139 static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2])
yading@10 140 {
yading@10 141 #if 0
yading@10 142 // This code is slower because it multiplies memory accesses.
yading@10 143 // It is left as eucational purpose and because it may offer
yading@10 144 // a better reference for writing arch-specific dsp functions.
yading@10 145 autocorrelate(x, phi, 0);
yading@10 146 autocorrelate(x, phi, 1);
yading@10 147 autocorrelate(x, phi, 2);
yading@10 148 #else
yading@10 149 float real_sum2 = x[ 0][0] * x[ 2][0] + x[ 0][1] * x[ 2][1];
yading@10 150 float imag_sum2 = x[ 0][0] * x[ 2][1] - x[ 0][1] * x[ 2][0];
yading@10 151 float real_sum1 = 0.f, imag_sum1 = 0.f, real_sum0 = 0.0f;
yading@10 152 int i;
yading@10 153 for (i = 1; i < 38; i++) {
yading@10 154 real_sum0 += x[i][0] * x[i ][0] + x[i][1] * x[i ][1];
yading@10 155 real_sum1 += x[i][0] * x[i+1][0] + x[i][1] * x[i+1][1];
yading@10 156 imag_sum1 += x[i][0] * x[i+1][1] - x[i][1] * x[i+1][0];
yading@10 157 real_sum2 += x[i][0] * x[i+2][0] + x[i][1] * x[i+2][1];
yading@10 158 imag_sum2 += x[i][0] * x[i+2][1] - x[i][1] * x[i+2][0];
yading@10 159 }
yading@10 160 phi[2-2][1][0] = real_sum2;
yading@10 161 phi[2-2][1][1] = imag_sum2;
yading@10 162 phi[2 ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
yading@10 163 phi[1 ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1];
yading@10 164 phi[2-1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1];
yading@10 165 phi[2-1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0];
yading@10 166 phi[0 ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1];
yading@10 167 phi[0 ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0];
yading@10 168 #endif
yading@10 169 }
yading@10 170
yading@10 171 static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
yading@10 172 const float alpha0[2], const float alpha1[2],
yading@10 173 float bw, int start, int end)
yading@10 174 {
yading@10 175 float alpha[4];
yading@10 176 int i;
yading@10 177
yading@10 178 alpha[0] = alpha1[0] * bw * bw;
yading@10 179 alpha[1] = alpha1[1] * bw * bw;
yading@10 180 alpha[2] = alpha0[0] * bw;
yading@10 181 alpha[3] = alpha0[1] * bw;
yading@10 182
yading@10 183 for (i = start; i < end; i++) {
yading@10 184 X_high[i][0] =
yading@10 185 X_low[i - 2][0] * alpha[0] -
yading@10 186 X_low[i - 2][1] * alpha[1] +
yading@10 187 X_low[i - 1][0] * alpha[2] -
yading@10 188 X_low[i - 1][1] * alpha[3] +
yading@10 189 X_low[i][0];
yading@10 190 X_high[i][1] =
yading@10 191 X_low[i - 2][1] * alpha[0] +
yading@10 192 X_low[i - 2][0] * alpha[1] +
yading@10 193 X_low[i - 1][1] * alpha[2] +
yading@10 194 X_low[i - 1][0] * alpha[3] +
yading@10 195 X_low[i][1];
yading@10 196 }
yading@10 197 }
yading@10 198
yading@10 199 static void sbr_hf_g_filt_c(float (*Y)[2], const float (*X_high)[40][2],
yading@10 200 const float *g_filt, int m_max, intptr_t ixh)
yading@10 201 {
yading@10 202 int m;
yading@10 203
yading@10 204 for (m = 0; m < m_max; m++) {
yading@10 205 Y[m][0] = X_high[m][ixh][0] * g_filt[m];
yading@10 206 Y[m][1] = X_high[m][ixh][1] * g_filt[m];
yading@10 207 }
yading@10 208 }
yading@10 209
yading@10 210 static av_always_inline void sbr_hf_apply_noise(float (*Y)[2],
yading@10 211 const float *s_m,
yading@10 212 const float *q_filt,
yading@10 213 int noise,
yading@10 214 float phi_sign0,
yading@10 215 float phi_sign1,
yading@10 216 int m_max)
yading@10 217 {
yading@10 218 int m;
yading@10 219
yading@10 220 for (m = 0; m < m_max; m++) {
yading@10 221 float y0 = Y[m][0];
yading@10 222 float y1 = Y[m][1];
yading@10 223 noise = (noise + 1) & 0x1ff;
yading@10 224 if (s_m[m]) {
yading@10 225 y0 += s_m[m] * phi_sign0;
yading@10 226 y1 += s_m[m] * phi_sign1;
yading@10 227 } else {
yading@10 228 y0 += q_filt[m] * ff_sbr_noise_table[noise][0];
yading@10 229 y1 += q_filt[m] * ff_sbr_noise_table[noise][1];
yading@10 230 }
yading@10 231 Y[m][0] = y0;
yading@10 232 Y[m][1] = y1;
yading@10 233 phi_sign1 = -phi_sign1;
yading@10 234 }
yading@10 235 }
yading@10 236
yading@10 237 static void sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m,
yading@10 238 const float *q_filt, int noise,
yading@10 239 int kx, int m_max)
yading@10 240 {
yading@10 241 sbr_hf_apply_noise(Y, s_m, q_filt, noise, 1.0, 0.0, m_max);
yading@10 242 }
yading@10 243
yading@10 244 static void sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m,
yading@10 245 const float *q_filt, int noise,
yading@10 246 int kx, int m_max)
yading@10 247 {
yading@10 248 float phi_sign = 1 - 2 * (kx & 1);
yading@10 249 sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, phi_sign, m_max);
yading@10 250 }
yading@10 251
yading@10 252 static void sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m,
yading@10 253 const float *q_filt, int noise,
yading@10 254 int kx, int m_max)
yading@10 255 {
yading@10 256 sbr_hf_apply_noise(Y, s_m, q_filt, noise, -1.0, 0.0, m_max);
yading@10 257 }
yading@10 258
yading@10 259 static void sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m,
yading@10 260 const float *q_filt, int noise,
yading@10 261 int kx, int m_max)
yading@10 262 {
yading@10 263 float phi_sign = 1 - 2 * (kx & 1);
yading@10 264 sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, -phi_sign, m_max);
yading@10 265 }
yading@10 266
yading@10 267 av_cold void ff_sbrdsp_init(SBRDSPContext *s)
yading@10 268 {
yading@10 269 s->sum64x5 = sbr_sum64x5_c;
yading@10 270 s->sum_square = sbr_sum_square_c;
yading@10 271 s->neg_odd_64 = sbr_neg_odd_64_c;
yading@10 272 s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_c;
yading@10 273 s->qmf_post_shuffle = sbr_qmf_post_shuffle_c;
yading@10 274 s->qmf_deint_neg = sbr_qmf_deint_neg_c;
yading@10 275 s->qmf_deint_bfly = sbr_qmf_deint_bfly_c;
yading@10 276 s->autocorrelate = sbr_autocorrelate_c;
yading@10 277 s->hf_gen = sbr_hf_gen_c;
yading@10 278 s->hf_g_filt = sbr_hf_g_filt_c;
yading@10 279
yading@10 280 s->hf_apply_noise[0] = sbr_hf_apply_noise_0;
yading@10 281 s->hf_apply_noise[1] = sbr_hf_apply_noise_1;
yading@10 282 s->hf_apply_noise[2] = sbr_hf_apply_noise_2;
yading@10 283 s->hf_apply_noise[3] = sbr_hf_apply_noise_3;
yading@10 284
yading@10 285 if (ARCH_ARM)
yading@10 286 ff_sbrdsp_init_arm(s);
yading@10 287 if (ARCH_X86)
yading@10 288 ff_sbrdsp_init_x86(s);
yading@10 289 if (ARCH_MIPS)
yading@10 290 ff_sbrdsp_init_mips(s);
yading@10 291 }