Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * AAC Spectral Band Replication decoding functions
  3.  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
  4.  * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  *
  22.  * Note: Rounding-to-nearest used unless otherwise stated
  23.  *
  24.  */
  25.  
  26. #define USE_FIXED 1
  27.  
  28. #include "aac.h"
  29. #include "config.h"
  30. #include "libavutil/attributes.h"
  31. #include "libavutil/intfloat.h"
  32. #include "sbrdsp.h"
  33.  
  34. static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
  35. {
  36.     SoftFloat ret;
  37.     int64_t accu = 0;
  38.     int i, nz, round;
  39.  
  40.     for (i = 0; i < n; i += 2) {
  41.         // Larger values are inavlid and could cause overflows of accu.
  42.         av_assert2(FFABS(x[i + 0][0]) >> 29 == 0);
  43.         accu += (int64_t)x[i + 0][0] * x[i + 0][0];
  44.         av_assert2(FFABS(x[i + 0][1]) >> 29 == 0);
  45.         accu += (int64_t)x[i + 0][1] * x[i + 0][1];
  46.         av_assert2(FFABS(x[i + 1][0]) >> 29 == 0);
  47.         accu += (int64_t)x[i + 1][0] * x[i + 1][0];
  48.         av_assert2(FFABS(x[i + 1][1]) >> 29 == 0);
  49.         accu += (int64_t)x[i + 1][1] * x[i + 1][1];
  50.     }
  51.  
  52.     i = (int)(accu >> 32);
  53.     if (i == 0) {
  54.         nz = 1;
  55.     } else {
  56.         nz = 0;
  57.         while (FFABS(i) < 0x40000000) {
  58.             i <<= 1;
  59.             nz++;
  60.         }
  61.         nz = 32 - nz;
  62.     }
  63.  
  64.     round = 1 << (nz-1);
  65.     i = (int)((accu + round) >> nz);
  66.     i >>= 1;
  67.     ret = av_int2sf(i, 15 - nz);
  68.  
  69.     return ret;
  70. }
  71.  
  72. static void sbr_neg_odd_64_c(int *x)
  73. {
  74.     int i;
  75.     for (i = 1; i < 64; i += 2)
  76.         x[i] = -x[i];
  77. }
  78.  
  79. static void sbr_qmf_pre_shuffle_c(int *z)
  80. {
  81.     int k;
  82.     z[64] = z[0];
  83.     z[65] = z[1];
  84.     for (k = 1; k < 32; k++) {
  85.         z[64+2*k  ] = -z[64 - k];
  86.         z[64+2*k+1] =  z[ k + 1];
  87.     }
  88. }
  89.  
  90. static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
  91. {
  92.     int k;
  93.     for (k = 0; k < 32; k++) {
  94.         W[k][0] = -z[63-k];
  95.         W[k][1] = z[k];
  96.     }
  97. }
  98.  
  99. static void sbr_qmf_deint_neg_c(int *v, const int *src)
  100. {
  101.     int i;
  102.     for (i = 0; i < 32; i++) {
  103.         v[     i] = ( src[63 - 2*i    ] + 0x10) >> 5;
  104.         v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5;
  105.     }
  106. }
  107.  
  108. static av_always_inline SoftFloat autocorr_calc(int64_t accu)
  109. {
  110.         int nz, mant, expo, round;
  111.         int i = (int)(accu >> 32);
  112.         if (i == 0) {
  113.             nz = 1;
  114.         } else {
  115.             nz = 0;
  116.             while (FFABS(i) < 0x40000000) {
  117.                 i <<= 1;
  118.                 nz++;
  119.             }
  120.             nz = 32-nz;
  121.         }
  122.  
  123.         round = 1 << (nz-1);
  124.         mant = (int)((accu + round) >> nz);
  125.         mant = (mant + 0x40)>>7;
  126.         mant <<= 6;
  127.         expo = nz + 15;
  128.         return av_int2sf(mant, 30 - expo);
  129. }
  130.  
  131. static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
  132. {
  133.     int i;
  134.     int64_t real_sum, imag_sum;
  135.     int64_t accu_re = 0, accu_im = 0;
  136.  
  137.     if (lag) {
  138.         for (i = 1; i < 38; i++) {
  139.             accu_re += (int64_t)x[i][0] * x[i+lag][0];
  140.             accu_re += (int64_t)x[i][1] * x[i+lag][1];
  141.             accu_im += (int64_t)x[i][0] * x[i+lag][1];
  142.             accu_im -= (int64_t)x[i][1] * x[i+lag][0];
  143.         }
  144.  
  145.         real_sum = accu_re;
  146.         imag_sum = accu_im;
  147.  
  148.         accu_re += (int64_t)x[ 0][0] * x[lag][0];
  149.         accu_re += (int64_t)x[ 0][1] * x[lag][1];
  150.         accu_im += (int64_t)x[ 0][0] * x[lag][1];
  151.         accu_im -= (int64_t)x[ 0][1] * x[lag][0];
  152.  
  153.         phi[2-lag][1][0] = autocorr_calc(accu_re);
  154.         phi[2-lag][1][1] = autocorr_calc(accu_im);
  155.  
  156.         if (lag == 1) {
  157.             accu_re = real_sum;
  158.             accu_im = imag_sum;
  159.             accu_re += (int64_t)x[38][0] * x[39][0];
  160.             accu_re += (int64_t)x[38][1] * x[39][1];
  161.             accu_im += (int64_t)x[38][0] * x[39][1];
  162.             accu_im -= (int64_t)x[38][1] * x[39][0];
  163.  
  164.             phi[0][0][0] = autocorr_calc(accu_re);
  165.             phi[0][0][1] = autocorr_calc(accu_im);
  166.         }
  167.     } else {
  168.         for (i = 1; i < 38; i++) {
  169.             accu_re += (int64_t)x[i][0] * x[i][0];
  170.             accu_re += (int64_t)x[i][1] * x[i][1];
  171.         }
  172.         real_sum = accu_re;
  173.         accu_re += (int64_t)x[ 0][0] * x[ 0][0];
  174.         accu_re += (int64_t)x[ 0][1] * x[ 0][1];
  175.  
  176.         phi[2][1][0] = autocorr_calc(accu_re);
  177.  
  178.         accu_re = real_sum;
  179.         accu_re += (int64_t)x[38][0] * x[38][0];
  180.         accu_re += (int64_t)x[38][1] * x[38][1];
  181.  
  182.         phi[1][0][0] = autocorr_calc(accu_re);
  183.     }
  184. }
  185.  
  186. static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
  187. {
  188.     autocorrelate(x, phi, 0);
  189.     autocorrelate(x, phi, 1);
  190.     autocorrelate(x, phi, 2);
  191. }
  192.  
  193. static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
  194.                        const int alpha0[2], const int alpha1[2],
  195.                        int bw, int start, int end)
  196. {
  197.     int alpha[4];
  198.     int i;
  199.     int64_t accu;
  200.  
  201.     accu = (int64_t)alpha0[0] * bw;
  202.     alpha[2] = (int)((accu + 0x40000000) >> 31);
  203.     accu = (int64_t)alpha0[1] * bw;
  204.     alpha[3] = (int)((accu + 0x40000000) >> 31);
  205.     accu = (int64_t)bw * bw;
  206.     bw = (int)((accu + 0x40000000) >> 31);
  207.     accu = (int64_t)alpha1[0] * bw;
  208.     alpha[0] = (int)((accu + 0x40000000) >> 31);
  209.     accu = (int64_t)alpha1[1] * bw;
  210.     alpha[1] = (int)((accu + 0x40000000) >> 31);
  211.  
  212.     for (i = start; i < end; i++) {
  213.         accu  = (int64_t)X_low[i][0] * 0x20000000;
  214.         accu += (int64_t)X_low[i - 2][0] * alpha[0];
  215.         accu -= (int64_t)X_low[i - 2][1] * alpha[1];
  216.         accu += (int64_t)X_low[i - 1][0] * alpha[2];
  217.         accu -= (int64_t)X_low[i - 1][1] * alpha[3];
  218.         X_high[i][0] = (int)((accu + 0x10000000) >> 29);
  219.  
  220.         accu  = (int64_t)X_low[i][1] * 0x20000000;
  221.         accu += (int64_t)X_low[i - 2][1] * alpha[0];
  222.         accu += (int64_t)X_low[i - 2][0] * alpha[1];
  223.         accu += (int64_t)X_low[i - 1][1] * alpha[2];
  224.         accu += (int64_t)X_low[i - 1][0] * alpha[3];
  225.         X_high[i][1] = (int)((accu + 0x10000000) >> 29);
  226.     }
  227. }
  228.  
  229. static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
  230.                           const SoftFloat *g_filt, int m_max, intptr_t ixh)
  231. {
  232.     int m, r;
  233.     int64_t accu;
  234.  
  235.     for (m = 0; m < m_max; m++) {
  236.         r = 1 << (22-g_filt[m].exp);
  237.         accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
  238.         Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
  239.  
  240.         accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
  241.         Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
  242.     }
  243. }
  244.  
  245. static av_always_inline void sbr_hf_apply_noise(int (*Y)[2],
  246.                                                 const SoftFloat *s_m,
  247.                                                 const SoftFloat *q_filt,
  248.                                                 int noise,
  249.                                                 int phi_sign0,
  250.                                                 int phi_sign1,
  251.                                                 int m_max)
  252. {
  253.     int m;
  254.  
  255.     for (m = 0; m < m_max; m++) {
  256.         int y0 = Y[m][0];
  257.         int y1 = Y[m][1];
  258.         noise = (noise + 1) & 0x1ff;
  259.         if (s_m[m].mant) {
  260.             int shift, round;
  261.  
  262.             shift = 22 - s_m[m].exp;
  263.             if (shift < 30) {
  264.                 round = 1 << (shift-1);
  265.                 y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
  266.                 y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
  267.             }
  268.         } else {
  269.             int shift, round, tmp;
  270.             int64_t accu;
  271.  
  272.             shift = 22 - q_filt[m].exp;
  273.             if (shift < 30) {
  274.                 round = 1 << (shift-1);
  275.  
  276.                 accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
  277.                 tmp = (int)((accu + 0x40000000) >> 31);
  278.                 y0 += (tmp + round) >> shift;
  279.  
  280.                 accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
  281.                 tmp = (int)((accu + 0x40000000) >> 31);
  282.                 y1 += (tmp + round) >> shift;
  283.             }
  284.         }
  285.         Y[m][0] = y0;
  286.         Y[m][1] = y1;
  287.         phi_sign1 = -phi_sign1;
  288.     }
  289. }
  290.  
  291. #include "sbrdsp_template.c"
  292.