The following patchset adds TNS support to the AAC encoder.

It's not 100% ready to be integrated.

Patch 0 adds PARCOR code from Flake and doesn't have much to do with AAC.
Patch 1 moves some AAC stuff around but doesn't ahev much to do with encoding.
Patch 2 adds TNS support.
Patch 3 adds a TNS coefficient compressor that shouldn't effect the
output of the file after encoding and decoding but does for reasons
taht stump me at the moment. Any help on this one would be greatly
appreciated.

Regards,

Alex Converse
commit 29d7da8631fe99ab89aae6a20770d309108298f6
Author: Alex Converse <[email protected]>
Date:   Tue Apr 28 01:40:56 2009 -0400

    Move some tables from aacdectab to aactab

diff --git a/libavcodec/aac.c b/libavcodec/aac.c
index 50429cf..7b3ae51 100644
--- a/libavcodec/aac.c
+++ b/libavcodec/aac.c
@@ -565,14 +565,14 @@ static int decode_ics_info(AACContext * ac, IndividualChannelStream * ics, GetBi
             }
         }
         ics->num_windows   = 8;
-        ics->swb_offset    =      swb_offset_128[ac->m4ac.sampling_index];
+        ics->swb_offset    =   ff_swb_offset_128[ac->m4ac.sampling_index];
         ics->num_swb       =  ff_aac_num_swb_128[ac->m4ac.sampling_index];
         ics->tns_max_bands =   tns_max_bands_128[ac->m4ac.sampling_index];
         ics->predictor_present = 0;
     } else {
         ics->max_sfb       = get_bits(gb, 6);
         ics->num_windows   = 1;
-        ics->swb_offset    =     swb_offset_1024[ac->m4ac.sampling_index];
+        ics->swb_offset    =  ff_swb_offset_1024[ac->m4ac.sampling_index];
         ics->num_swb       = ff_aac_num_swb_1024[ac->m4ac.sampling_index];
         ics->tns_max_bands =  tns_max_bands_1024[ac->m4ac.sampling_index];
         ics->predictor_present = get_bits1(gb);
diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h
index 34b0abe..b6d80f2 100644
--- a/libavcodec/aacdectab.h
+++ b/libavcodec/aacdectab.h
@@ -34,145 +34,6 @@
 
 #include <stdint.h>
 
-/* @name swb_offsets
- * Sample offset into the window indicating the beginning of a scalefactor
- * window band
- *
- * scalefactor window band - term for scalefactor bands within a window,
- * given in Table 4.110 to Table 4.128.
- *
- * scalefactor band - a set of spectral coefficients which are scaled by one
- * scalefactor. In case of EIGHT_SHORT_SEQUENCE and grouping a scalefactor band
- * may contain several scalefactor window bands of corresponding frequency. For
- * all other window_sequences scalefactor bands and scalefactor window bands are
- * identical.
- * @{
- */
-
-static const uint16_t swb_offset_1024_96[] = {
-      0,   4,   8,  12,  16,  20,  24,  28,
-     32,  36,  40,  44,  48,  52,  56,  64,
-     72,  80,  88,  96, 108, 120, 132, 144,
-    156, 172, 188, 212, 240, 276, 320, 384,
-    448, 512, 576, 640, 704, 768, 832, 896,
-    960, 1024
-};
-
-static const uint16_t swb_offset_128_96[] = {
-    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
-};
-
-static const uint16_t swb_offset_1024_64[] = {
-      0,   4,   8,  12,  16,  20,  24,  28,
-     32,  36,  40,  44,  48,  52,  56,  64,
-     72,  80,  88, 100, 112, 124, 140, 156,
-    172, 192, 216, 240, 268, 304, 344, 384,
-    424, 464, 504, 544, 584, 624, 664, 704,
-    744, 784, 824, 864, 904, 944, 984, 1024
-};
-
-static const uint16_t swb_offset_1024_48[] = {
-      0,   4,   8,  12,  16,  20,  24,  28,
-     32,  36,  40,  48,  56,  64,  72,  80,
-     88,  96, 108, 120, 132, 144, 160, 176,
-    196, 216, 240, 264, 292, 320, 352, 384,
-    416, 448, 480, 512, 544, 576, 608, 640,
-    672, 704, 736, 768, 800, 832, 864, 896,
-    928, 1024
-};
-
-static const uint16_t swb_offset_128_48[] = {
-     0,   4,   8,  12,  16,  20,  28,  36,
-    44,  56,  68,  80,  96, 112, 128
-};
-
-static const uint16_t swb_offset_1024_32[] = {
-      0,   4,   8,  12,  16,  20,  24,  28,
-     32,  36,  40,  48,  56,  64,  72,  80,
-     88,  96, 108, 120, 132, 144, 160, 176,
-    196, 216, 240, 264, 292, 320, 352, 384,
-    416, 448, 480, 512, 544, 576, 608, 640,
-    672, 704, 736, 768, 800, 832, 864, 896,
-    928, 960, 992, 1024
-};
-
-static const uint16_t swb_offset_1024_24[] = {
-      0,   4,   8,  12,  16,  20,  24,  28,
-     32,  36,  40,  44,  52,  60,  68,  76,
-     84,  92, 100, 108, 116, 124, 136, 148,
-    160, 172, 188, 204, 220, 240, 260, 284,
-    308, 336, 364, 396, 432, 468, 508, 552,
-    600, 652, 704, 768, 832, 896, 960, 1024
-};
-
-static const uint16_t swb_offset_128_24[] = {
-     0,   4,   8,  12,  16,  20,  24,  28,
-    36,  44,  52,  64,  76,  92, 108, 128
-};
-
-static const uint16_t swb_offset_1024_16[] = {
-      0,   8,  16,  24,  32,  40,  48,  56,
-     64,  72,  80,  88, 100, 112, 124, 136,
-    148, 160, 172, 184, 196, 212, 228, 244,
-    260, 280, 300, 320, 344, 368, 396, 424,
-    456, 492, 532, 572, 616, 664, 716, 772,
-    832, 896, 960, 1024
-};
-
-static const uint16_t swb_offset_128_16[] = {
-     0,   4,   8,  12,  16,  20,  24,  28,
-    32,  40,  48,  60,  72,  88, 108, 128
-};
-
-static const uint16_t swb_offset_1024_8[] = {
-      0,  12,  24,  36,  48,  60,  72,  84,
-     96, 108, 120, 132, 144, 156, 172, 188,
-    204, 220, 236, 252, 268, 288, 308, 328,
-    348, 372, 396, 420, 448, 476, 508, 544,
-    580, 620, 664, 712, 764, 820, 880, 944,
-    1024
-};
-
-static const uint16_t swb_offset_128_8[] = {
-     0,   4,   8,  12,  16,  20,  24,  28,
-    36,  44,  52,  60,  72,  88, 108, 128
-};
-
-static const uint16_t *swb_offset_1024[] = {
-    swb_offset_1024_96, swb_offset_1024_96, swb_offset_1024_64,
-    swb_offset_1024_48, swb_offset_1024_48, swb_offset_1024_32,
-    swb_offset_1024_24, swb_offset_1024_24, swb_offset_1024_16,
-    swb_offset_1024_16, swb_offset_1024_16, swb_offset_1024_8,
-    swb_offset_1024_8
-};
-
-static const uint16_t *swb_offset_128[] = {
-    /* The last entry on the following row is swb_offset_128_64 but is a
-       duplicate of swb_offset_128_96. */
-    swb_offset_128_96, swb_offset_128_96, swb_offset_128_96,
-    swb_offset_128_48, swb_offset_128_48, swb_offset_128_48,
-    swb_offset_128_24, swb_offset_128_24, swb_offset_128_16,
-    swb_offset_128_16, swb_offset_128_16, swb_offset_128_8,
-    swb_offset_128_8
-};
-
-// @}
-
-/* @name tns_max_bands
- * The maximum number of scalefactor bands on which TNS can operate for the long
- * and short transforms respectively. The index to these tables is related to
- * the sample rate of the audio.
- * @{
- */
-static const uint8_t tns_max_bands_1024[] = {
-    31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, 39
-};
-
-static const uint8_t tns_max_bands_128[] = {
-    9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14
-};
-// @}
-
 /* @name tns_tmp2_map
  * Tables of the tmp2[] arrays of LPC coefficients used for TNS.
  * The suffix _M_N[] indicate the values of coef_compress and coef_res
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index b14b395..6d055eb 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -899,6 +899,131 @@ const float * const ff_aac_codebook_vectors[] = {
     codebook_vector8, codebook_vector10,
 };
 
+/* @name swb_offsets
+ * Sample offset into the window indicating the beginning of a scalefactor
+ * window band
+ *
+ * scalefactor window band - term for scalefactor bands within a window,
+ * given in Table 4.110 to Table 4.128.
+ *
+ * scalefactor band - a set of spectral coefficients which are scaled by one
+ * scalefactor. In case of EIGHT_SHORT_SEQUENCE and grouping a scalefactor band
+ * may contain several scalefactor window bands of corresponding frequency. For
+ * all other window_sequences scalefactor bands and scalefactor window bands are
+ * identical.
+ * @{
+ */
+
+static const uint16_t swb_offset_1024_96[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  44,  48,  52,  56,  64,
+     72,  80,  88,  96, 108, 120, 132, 144,
+    156, 172, 188, 212, 240, 276, 320, 384,
+    448, 512, 576, 640, 704, 768, 832, 896,
+    960, 1024
+};
+
+static const uint16_t swb_offset_128_96[] = {
+    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+static const uint16_t swb_offset_1024_64[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  44,  48,  52,  56,  64,
+     72,  80,  88, 100, 112, 124, 140, 156,
+    172, 192, 216, 240, 268, 304, 344, 384,
+    424, 464, 504, 544, 584, 624, 664, 704,
+    744, 784, 824, 864, 904, 944, 984, 1024
+};
+
+static const uint16_t swb_offset_1024_48[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  48,  56,  64,  72,  80,
+     88,  96, 108, 120, 132, 144, 160, 176,
+    196, 216, 240, 264, 292, 320, 352, 384,
+    416, 448, 480, 512, 544, 576, 608, 640,
+    672, 704, 736, 768, 800, 832, 864, 896,
+    928, 1024
+};
+
+static const uint16_t swb_offset_128_48[] = {
+     0,   4,   8,  12,  16,  20,  28,  36,
+    44,  56,  68,  80,  96, 112, 128
+};
+
+static const uint16_t swb_offset_1024_32[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  48,  56,  64,  72,  80,
+     88,  96, 108, 120, 132, 144, 160, 176,
+    196, 216, 240, 264, 292, 320, 352, 384,
+    416, 448, 480, 512, 544, 576, 608, 640,
+    672, 704, 736, 768, 800, 832, 864, 896,
+    928, 960, 992, 1024
+};
+
+static const uint16_t swb_offset_1024_24[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  44,  52,  60,  68,  76,
+     84,  92, 100, 108, 116, 124, 136, 148,
+    160, 172, 188, 204, 220, 240, 260, 284,
+    308, 336, 364, 396, 432, 468, 508, 552,
+    600, 652, 704, 768, 832, 896, 960, 1024
+};
+
+static const uint16_t swb_offset_128_24[] = {
+     0,   4,   8,  12,  16,  20,  24,  28,
+    36,  44,  52,  64,  76,  92, 108, 128
+};
+
+static const uint16_t swb_offset_1024_16[] = {
+      0,   8,  16,  24,  32,  40,  48,  56,
+     64,  72,  80,  88, 100, 112, 124, 136,
+    148, 160, 172, 184, 196, 212, 228, 244,
+    260, 280, 300, 320, 344, 368, 396, 424,
+    456, 492, 532, 572, 616, 664, 716, 772,
+    832, 896, 960, 1024
+};
+
+static const uint16_t swb_offset_128_16[] = {
+     0,   4,   8,  12,  16,  20,  24,  28,
+    32,  40,  48,  60,  72,  88, 108, 128
+};
+
+static const uint16_t swb_offset_1024_8[] = {
+      0,  12,  24,  36,  48,  60,  72,  84,
+     96, 108, 120, 132, 144, 156, 172, 188,
+    204, 220, 236, 252, 268, 288, 308, 328,
+    348, 372, 396, 420, 448, 476, 508, 544,
+    580, 620, 664, 712, 764, 820, 880, 944,
+    1024
+};
+
+static const uint16_t swb_offset_128_8[] = {
+     0,   4,   8,  12,  16,  20,  24,  28,
+    36,  44,  52,  60,  72,  88, 108, 128
+};
+
+const uint16_t *ff_swb_offset_1024[] = {
+    swb_offset_1024_96, swb_offset_1024_96, swb_offset_1024_64,
+    swb_offset_1024_48, swb_offset_1024_48, swb_offset_1024_32,
+    swb_offset_1024_24, swb_offset_1024_24, swb_offset_1024_16,
+    swb_offset_1024_16, swb_offset_1024_16, swb_offset_1024_8,
+    swb_offset_1024_8
+};
+
+const uint16_t *ff_swb_offset_128[] = {
+    /* The last entry on the following row is swb_offset_128_64 but is a
+       duplicate of swb_offset_128_96. */
+    swb_offset_128_96, swb_offset_128_96, swb_offset_128_96,
+    swb_offset_128_48, swb_offset_128_48, swb_offset_128_48,
+    swb_offset_128_24, swb_offset_128_24, swb_offset_128_16,
+    swb_offset_128_16, swb_offset_128_16, swb_offset_128_8,
+    swb_offset_128_8
+};
+
+// @}
+
+
 #if CONFIG_HARDCODED_TABLES
 
 /**
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index f1036b5..b7b54c6 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -65,6 +65,24 @@ extern const uint16_t  ff_aac_spectral_sizes[11];
 
 extern const float *ff_aac_codebook_vectors[];
 
+/* @name tns_max_bands
+ * The maximum number of scalefactor bands on which TNS can operate for the long
+ * and short transforms respectively. The index to these tables is related to
+ * the sample rate of the audio.
+ * @{
+ */
+static const uint8_t tns_max_bands_1024[] = {
+    31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, 39
+};
+
+static const uint8_t tns_max_bands_128[] = {
+    9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14
+};
+// @}
+
+extern const uint16_t *ff_swb_offset_1024[13];
+extern const uint16_t *ff_swb_offset_128 [13];
+
 #if CONFIG_HARDCODED_TABLES
 extern const float ff_aac_pow2sf_tab[428];
 #else
commit 92ccfad0386234f08961e0c11b52e6e10233450a
Author: Alex Converse <[email protected]>
Date:   Fri Jun 12 10:48:13 2009 -0400

    Routine to calculate PARCOR reflection coefficients and prediction gain.
    Ported from Flake, written by Justin Ruggles.

diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index 05a1dee..078ebea 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -99,4 +99,34 @@ static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order,
     return 0;
 }
 
+/**
+ * Schur recursion.
+ * Produces LPC coefficients from autocorrelation data.
+ * @return prediction gain
+ */
+static float
+compute_parcor_coefs(const float *autoc, int max_order,
+                      float *ref)
+{
+    int i, j;
+    double error;
+    double gen[2][MAX_LPC_ORDER];
+ 
+    // Schur recursion
+    for(i=0; i<max_order; i++) gen[0][i] = gen[1][i] = autoc[i+1];
+    error = autoc[0];
+    ref[0] = -gen[1][0] / error;
+    error += gen[1][0] * ref[0];
+    for(i=1; i<max_order; i++) {
+        for(j=0; j<max_order-i; j++) {
+            gen[1][j] = gen[1][j+1] + ref[i-1] * gen[0][j];
+            gen[0][j] = gen[1][j+1] * ref[i-1] + gen[0][j];
+        }
+        ref[i] = -gen[1][0] / error;
+        error += gen[1][0] * ref[i];
+    }
+ 
+    return autoc[0]/error;
+}
+
 #endif /* AVCODEC_LPC_H */
commit e0f30ee366f721da763d764ed6e09e408d14fa66
Author: Alex Converse <[email protected]>
Date:   Fri Jun 12 11:00:31 2009 -0400

    Rudimentary TNS support based on ISO 13818-7 Annex C

diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index cd9eb8a..177ab08 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -152,6 +152,9 @@ typedef struct {
     int direction[8][4];
     int order[8][4];
     float coef[8][4][TNS_MAX_ORDER];
+    uint8_t coef_res[8];
+    uint8_t coef_compress[8][4];
+    int8_t icoef[8][4][TNS_MAX_ORDER];
 } TemporalNoiseShaping;
 
 /**
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index a4ed743..4a74e23 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -1,6 +1,7 @@
 /*
  * AAC coefficients encoder
  * Copyright (C) 2008-2009 Konstantin Shishkov
+ * Copyright (C) 2009 Alex Converse
  *
  * This file is part of FFmpeg.
  *
@@ -35,6 +36,7 @@
 #include "aac.h"
 #include "aacenc.h"
 #include "aactab.h"
+#include "lpc.h"
 
 /** bits needed to code codebook run value for long windows */
 static const uint8_t run_value_bits_long[64] = {
@@ -1242,29 +1244,158 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lam
     }
 }
 
+static const uint8_t tns_start_band_1024[12] =
+{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 };
+static const uint8_t tns_start_band_128[12] =
+{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 };
+
+static void autocorr(float * out, const float * in, int in_size, int out_size)
+{
+    int i, j;
+    float tmp;
+
+    for (i = 0; i < out_size; i++) {
+        tmp = 0.0f;
+        for (j = 0; j < in_size-i; j++) {
+            tmp += in[j]*in[i+j];
+        }
+        out[i] = tmp;
+    }
+}
+
+static void tns_quantize(int coef_res, int8_t* index, float* r, int order)
+{
+    const double iqfac = ((1 << (coef_res-1)) - 0.5) / (M_PI/2.0);
+    const double iqfac_m = ((1 << (coef_res-1)) + 0.5) / (M_PI/2.0);
+    int i;
+
+    /* Reflection coefficient quantization */
+    for (i = 0; i < order; i++) {
+        index[i] = (int)((asin( r[i] ) * ((r[i] >= 0) ? iqfac : iqfac_m))+0.5);
+        r[i] = sin(index[i] / ((index[i] >= 0) ? iqfac : iqfac_m));
+    }
+}
+
+static int tns_truncate_order(float* rq, int order)
+{
+    int i;
+    const float TRUNC_THRESH = 0.1f;
+
+    for (i = order-1; i >= 0; i--) {
+         rq[i] = (fabsf(rq[i]) > TRUNC_THRESH) ? rq[i]: 0.0f;
+         if (rq[i] != 0.0f)
+             return i+1;
+    }
+    return 0;
+}
+
+static void tns_step_up(int order, float* a, const float *ref)
+{
+    float b[TNS_MAX_ORDER+2];
+    int i, m;
+
+    a[0] = b[0] = 1.0f;
+    for (m = 1; m <= order; m++) {
+        for (i = 1; i < m; i++) {
+            b[i] = a[i] + ref[m-1] * a[m-i];
+        }
+        for (i = 1; i < m; i++) {
+            a[i] = b[i];
+        }
+        a[m] = ref[m-1];
+    }
+}
+
+static void tns_ma_filter(float * coef, const float * a, int len, int order)
+{
+    int i, m;
+    const int RING = 31;
+    float buf[RING+1];
+
+    for (m = 0; m < len; m++) {
+        buf[m&RING] = coef[m];
+        for (i = 1; i <= FFMIN(order, m); i++)
+            coef[m] += buf[(m - i)&RING] * a[i];
+    }
+}
+
+static void tns_encode_annex_c(AVCodecContext *avctx, AACEncContext *s,
+                               SingleChannelElement * sce)
+{
+
+    int max_bands, start_band, stop_band, order, coef_res, w;
+    float gain;
+    float ref[TNS_MAX_ORDER];
+    float   a[TNS_MAX_ORDER+1];
+    const float GAIN_THRESH = 1.4f;
+    TemporalNoiseShaping    * tns = &sce->tns;
+    IndividualChannelStream * ics = &sce->ics;
+
+    tns->present = 0;
+
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        max_bands  =  tns_max_bands_128[s->samplerate_index];
+        order      =  7;
+        start_band =  tns_start_band_128[s->samplerate_index];
+    } else {
+        max_bands  = tns_max_bands_1024[s->samplerate_index];
+        order      = 12;
+        start_band = tns_start_band_1024[s->samplerate_index];
+    }
+    stop_band  = ics->num_swb;
+    start_band = FFMAX(start_band, stop_band - max_bands);
+
+    for (w = 0; w < ics->num_windows; w++) {
+        int idx = w * 128 + ics->swb_offset[start_band];
+        int len = ics->swb_offset[stop_band] - ics->swb_offset[start_band];
+        autocorr(a, &sce->coeffs[idx], len, order+1);
+        gain = compute_parcor_coefs(a, order, ref);
+
+        if (gain > GAIN_THRESH) {
+            coef_res = 4;
+            tns->present = 1;
+            tns->n_filt[w] = 1;
+            tns->coef_res[w] = coef_res;
+            tns->length[w][0] = stop_band - start_band;
+            tns->direction[w][0] = 0;
+            tns_quantize(coef_res, &tns->icoef[w][0][0], ref, order);
+            tns->order[w][0] = tns_truncate_order(ref, order);
+            tns->coef_compress[w][0] = 0;
+            tns_step_up(tns->order[w][0], a, ref);
+            tns_ma_filter(&sce->coeffs[idx], a, len, tns->order[w][0]);
+        } else {
+            tns->n_filt[w] = 0;
+        }
+    }
+}
+
 AACCoefficientsEncoder ff_aac_coders[] = {
     {
         search_for_quantizers_faac,
         encode_window_bands_info_fixed,
         quantize_and_encode_band,
+        tns_encode_annex_c,
 //        search_for_ms,
     },
     {
         search_for_quantizers_anmr,
         encode_window_bands_info,
         quantize_and_encode_band,
+        tns_encode_annex_c,
 //        search_for_ms,
     },
     {
         search_for_quantizers_twoloop,
         encode_window_bands_info,
         quantize_and_encode_band,
+        tns_encode_annex_c,
 //        search_for_ms,
     },
     {
         search_for_quantizers_fast,
         encode_window_bands_info,
         quantize_and_encode_band,
+        tns_encode_annex_c,
 //        search_for_ms,
     },
 };
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index b4fab18..72c25bc 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -360,6 +360,14 @@ static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, in
 }
 
 /**
+ * Encode tns but don't write it to the bitstream.
+ */
+static void encode_tns(AVCodecContext * avctx, AACEncContext *s, SingleChannelElement *sce)
+{
+    s->coder->encode_tns(avctx, s, sce);
+}
+
+/**
  * Encode scalefactor band coding type.
  */
 static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
@@ -435,6 +443,36 @@ static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
     }
 }
 
+static void put_tns(PutBitContext * pb, SingleChannelElement * sce)
+{
+    TemporalNoiseShaping * tns = &sce->tns;
+    const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE;
+    const int num_windows = sce->ics.num_windows;
+    int w, filt, i, coef_len;
+
+    put_bits(pb, 1, tns->present);
+    if (tns->present) {
+        for (w = 0; w < num_windows; w++) {
+            put_bits(pb, 2 - is8, tns->n_filt[w]);
+            if (tns->n_filt[w]) {
+                put_bits(pb, 1, tns->coef_res[w] - 3);
+                for (filt = 0; filt < tns->n_filt[w]; filt++) {
+                    put_bits(pb, 6 - 2 * is8, tns->length[w][filt]);
+                    put_bits(pb, 5 - 2 * is8, tns->order [w][filt]);
+                    if (tns->order[w][filt]) {
+                        put_bits(pb, 1, tns->direction    [w][filt]);
+                        put_bits(pb, 1, tns->coef_compress[w][filt]);
+                        coef_len = tns->coef_res[w] - tns->coef_compress[w][filt];
+                        for (i = 0; i < tns->order[w][filt]; i++) {
+                            put_sbits(pb, coef_len, tns->icoef[w][filt][i]);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
 /**
  * Encode one channel of audio data.
  */
@@ -443,9 +481,10 @@ static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, Si
     put_bits(&s->pb, 8, sce->sf_idx[0]);
     if(!common_window) put_ics_info(s, &sce->ics);
     encode_band_info(s, sce);
+    encode_tns(avctx, s, sce);
     encode_scale_factors(avctx, s, sce);
     encode_pulses(s, &sce->pulse);
-    put_bits(&s->pb, 1, 0); //tns
+    put_tns(&s->pb, sce);
     put_bits(&s->pb, 1, 0); //ssr
     encode_spectral_coeffs(s, sce);
     return 0;
@@ -527,6 +566,9 @@ static int aac_encode_frame(AVCodecContext *avctx,
             ics->num_windows        = wi[j].num_windows;
             ics->swb_sizes          = s->psy.bands    [ics->num_windows == 8];
             ics->num_swb            = s->psy.num_bands[ics->num_windows == 8];
+            ics->swb_offset         = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ?
+                                      ff_swb_offset_128 [s->samplerate_index] :
+                                      ff_swb_offset_1024[s->samplerate_index];
             for(k = 0; k < ics->num_windows; k++)
                 ics->group_len[k] = wi[j].grouping[k];
 
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 9dc1c78..580934c 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -39,6 +39,8 @@ typedef struct AACCoefficientsEncoder{
                                      int win, int group_len, const float lambda);
     void (*quantize_and_encode_band)(PutBitContext *pb, const float *in, int size,
                                      int scale_idx, int cb, const float lambda);
+    void (*encode_tns)(AVCodecContext *avctx, struct AACEncContext *s,
+                                  SingleChannelElement *sce);
     void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda);
 }AACCoefficientsEncoder;
 
commit 84b30a38755715ed293adc3a835716de7009e4aa
Author: Alex Converse <[email protected]>
Date:   Fri Jun 12 12:58:45 2009 -0400

    TNS coefficient compressor

diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index 4a74e23..ac20f8d 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -1289,6 +1289,19 @@ static int tns_truncate_order(float* rq, int order)
     return 0;
 }
 
+static int tns_compress(int coef_res, int8_t* index, int order)
+{
+    int i;
+    int shift = coef_res - 2;
+    int head;
+    for (i = 0; i < order; i++) {
+        head = index[i] >> shift;
+        if (head > 0 || head < -1)
+            return 0;
+    }
+    return 1;
+}
+
 static void tns_step_up(int order, float* a, const float *ref)
 {
     float b[TNS_MAX_ORDER+2];
@@ -1360,7 +1373,7 @@ static void tns_encode_annex_c(AVCodecContext *avctx, AACEncContext *s,
             tns->direction[w][0] = 0;
             tns_quantize(coef_res, &tns->icoef[w][0][0], ref, order);
             tns->order[w][0] = tns_truncate_order(ref, order);
-            tns->coef_compress[w][0] = 0;
+            tns->coef_compress[w][0] = tns_compress(coef_res, &tns->icoef[w][0][0], tns->order[w][0]);
             tns_step_up(tns->order[w][0], a, ref);
             tns_ma_filter(&sce->coeffs[idx], a, len, tns->order[w][0]);
         } else {
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to