Correct pulse amplitude application - a negative or 0 coefficient implies the
[ffmpeg.git] / libavcodec / aac.c
index 7459f4f..cc069ed 100644 (file)
@@ -79,6 +79,7 @@
 #include "avcodec.h"
 #include "bitstream.h"
 #include "dsputil.h"
+#include "lpc.h"
 
 #include "aac.h"
 #include "aactab.h"
@@ -752,7 +753,9 @@ static int decode_spectrum_and_dequant(AACContext * ac, float coef[1024], GetBit
     if (pulse_present) {
         for(i = 0; i < pulse->num_pulse; i++){
             float co  = coef_base[ pulse->pos[i] ];
-            float ico = co / sqrtf(sqrtf(fabsf(co))) + pulse->amp[i];
+            float ico = -pulse->amp[i];
+            if (co)
+                ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico);
             coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico;
         }
     }
@@ -1124,20 +1127,8 @@ static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualCh
             if (order == 0)
                 continue;
 
-            /* tns_decode_coef
-             * FIXME: This duplicates the functionality of some double code in lpc.c.
-             */
-            for (m = 0; m < order; m++) {
-                float tmp;
-                lpc[m] = tns->coef[w][filt][m];
-                for (i = 0; i < m/2; i++) {
-                    tmp = lpc[i];
-                    lpc[i]     += lpc[m] * lpc[m-1-i];
-                    lpc[m-1-i] += lpc[m] * tmp;
-                }
-                if(m & 1)
-                    lpc[i]     += lpc[m] * lpc[i];
-            }
+            // tns_decode_coef
+            compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0);
 
             start = ics->swb_offset[FFMIN(bottom, mmm)];
             end   = ics->swb_offset[FFMIN(   top, mmm)];
@@ -1166,60 +1157,65 @@ static void imdct_and_windowing(AACContext * ac, SingleChannelElement * sce) {
     float * in = sce->coeffs;
     float * out = sce->ret;
     float * saved = sce->saved;
-    const float * lwindow      = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
     const float * swindow      = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
     const float * lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
     const float * swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
     float * buf = ac->buf_mdct;
+    DECLARE_ALIGNED(16, float, temp[128]);
     int i;
 
+    // imdct
     if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
         if (ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE)
             av_log(ac->avccontext, AV_LOG_WARNING,
                    "Transition from an ONLY_LONG or LONG_STOP to an EIGHT_SHORT sequence detected. "
                    "If you heard an audible artifact, please submit the sample to the FFmpeg developers.\n");
-        for (i = 0; i < 2048; i += 256) {
-            ff_imdct_calc(&ac->mdct_small, buf + i, in + i/2);
-            ac->dsp.vector_fmul_reverse(ac->revers + i/2, buf + i + 128, swindow, 128);
-        }
-        for (i = 0; i < 448; i++)   out[i] = saved[i] + ac->add_bias;
-
-        ac->dsp.vector_fmul_add_add(out + 448 + 0*128, buf + 0*128, swindow_prev, saved + 448 ,       ac->add_bias, 128, 1);
-        ac->dsp.vector_fmul_add_add(out + 448 + 1*128, buf + 2*128, swindow,      ac->revers + 0*128, ac->add_bias, 128, 1);
-        ac->dsp.vector_fmul_add_add(out + 448 + 2*128, buf + 4*128, swindow,      ac->revers + 1*128, ac->add_bias, 128, 1);
-        ac->dsp.vector_fmul_add_add(out + 448 + 3*128, buf + 6*128, swindow,      ac->revers + 2*128, ac->add_bias, 128, 1);
-        ac->dsp.vector_fmul_add_add(out + 448 + 4*128, buf + 8*128, swindow,      ac->revers + 3*128, ac->add_bias,  64, 1);
-
-#if 0
-        vector_fmul_add_add_add(&ac->dsp, out + 448 + 1*128, buf + 2*128, swindow,      saved + 448 + 1*128, ac->revers + 0*128, ac->add_bias, 128);
-        vector_fmul_add_add_add(&ac->dsp, out + 448 + 2*128, buf + 4*128, swindow,      saved + 448 + 2*128, ac->revers + 1*128, ac->add_bias, 128);
-        vector_fmul_add_add_add(&ac->dsp, out + 448 + 3*128, buf + 6*128, swindow,      saved + 448 + 3*128, ac->revers + 2*128, ac->add_bias, 128);
-        vector_fmul_add_add_add(&ac->dsp, out + 448 + 4*128, buf + 8*128, swindow,      saved + 448 + 4*128, ac->revers + 3*128, ac->add_bias, 64);
-#endif
-
-        ac->dsp.vector_fmul_add_add(saved,       buf + 1024 + 64,    swindow + 64, ac->revers + 3*128+64,  0, 64, 1);
-        ac->dsp.vector_fmul_add_add(saved + 64,  buf + 1024 + 2*128, swindow,      ac->revers + 4*128,     0, 128, 1);
-        ac->dsp.vector_fmul_add_add(saved + 192, buf + 1024 + 4*128, swindow,      ac->revers + 5*128,     0, 128, 1);
-        ac->dsp.vector_fmul_add_add(saved + 320, buf + 1024 + 6*128, swindow,      ac->revers + 6*128,     0, 128, 1);
-        memcpy(                     saved + 448, ac->revers + 7*128, 128 * sizeof(float));
-        memset(                     saved + 576, 0,                  448 * sizeof(float));
+        for (i = 0; i < 1024; i += 128)
+            ff_imdct_half(&ac->mdct_small, buf + i, in + i);
+    } else
+        ff_imdct_half(&ac->mdct, buf, in);
+
+    /* window overlapping
+     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
+     * and long to short transitions are considered to be short to short
+     * transitions. This leaves just two cases (long to long and short to short)
+     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
+     */
+    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
+        (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
+        ac->dsp.vector_fmul_window(    out,               saved,            buf,         lwindow_prev, ac->add_bias, 512);
     } else {
-        ff_imdct_calc(&ac->mdct, buf, in);
-        if (ics->window_sequence[0] == LONG_STOP_SEQUENCE) {
-            for (i = 0;   i < 448;  i++)   out[i] =          saved[i] + ac->add_bias;
-            ac->dsp.vector_fmul_add_add(out + 448, buf + 448, swindow_prev, saved + 448, ac->add_bias, 128, 1);
-            for (i = 576; i < 1024; i++)   out[i] = buf[i] + saved[i] + ac->add_bias;
+        for (i = 0; i < 448; i++)
+            out[i] = saved[i] + ac->add_bias;
+
+        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+            ac->dsp.vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, ac->add_bias, 64);
+            ac->dsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      ac->add_bias, 64);
+            ac->dsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      ac->add_bias, 64);
+            ac->dsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      ac->add_bias, 64);
+            ac->dsp.vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      ac->add_bias, 64);
+            memcpy(                    out + 448 + 4*128, temp, 64 * sizeof(float));
         } else {
-            ac->dsp.vector_fmul_add_add(out, buf, lwindow_prev, saved, ac->add_bias, 1024, 1);
-        }
-        if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
-            memcpy(saved, buf + 1024, 448 * sizeof(float));
-            ac->dsp.vector_fmul_reverse(saved + 448, buf + 1024 + 448, swindow, 128);
-            memset(saved + 576, 0, 448 * sizeof(float));
-        } else {
-            ac->dsp.vector_fmul_reverse(saved, buf + 1024, lwindow, 1024);
+            ac->dsp.vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, ac->add_bias, 64);
+            for (i = 576; i < 1024; i++)
+                out[i] = buf[i-512] + ac->add_bias;
         }
     }
+
+    // buffer update
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        for (i = 0; i < 64; i++)
+            saved[i] = temp[64 + i] - ac->add_bias;
+        ac->dsp.vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 0, 64);
+        ac->dsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 0, 64);
+        ac->dsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 0, 64);
+        memcpy(                    saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
+    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+        memcpy(                    saved,       buf + 512,        448 * sizeof(float));
+        memcpy(                    saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
+    } else { // LONG_STOP or ONLY_LONG
+        memcpy(                    saved,       buf + 512,        512 * sizeof(float));
+    }
 }
 
 /**
@@ -1343,7 +1339,7 @@ static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data
             ac->che[TYPE_SCE][elem_id] = ac->che[TYPE_LFE][0];
             ac->che[TYPE_LFE][0] = NULL;
         }
-        if(elem_type && elem_type < TYPE_DSE) {
+        if(elem_type < TYPE_DSE) {
             if(!ac->che[elem_type][elem_id])
                 return -1;
             if(elem_type != TYPE_CCE)
@@ -1361,7 +1357,7 @@ static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data
             break;
 
         case TYPE_CCE:
-            err = decode_cce(ac, &gb, ac->che[TYPE_SCE][elem_id]);
+            err = decode_cce(ac, &gb, ac->che[TYPE_CCE][elem_id]);
             break;
 
         case TYPE_LFE: