shithub: aacdec

Download patch

ref: db2d1012adc7c9391f08aa77a2f05e7beee7548b
parent: 596df37e0820fe8cdafed3c077d9b1bbb2991803
author: menno <menno>
date: Mon Jun 23 11:21:20 EDT 2003

Moved data around a bit in library (no more extern)
Updated frontend to show some info

--- a/common/faad/aacinfo.c
+++ b/common/faad/aacinfo.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: aacinfo.c,v 1.2 2002/01/24 14:30:08 menno Exp $
+** $Id: aacinfo.c,v 1.3 2003/06/23 15:21:19 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -125,13 +125,11 @@
         /* ...and the variable ADTS header */
         if (ID == 0) {
             info->version = 4;
-            frame_length = (((unsigned int)buffer[4]) << 5) |
-                ((unsigned int)buffer[5] >> 3);
         } else { /* MPEG-2 */
             info->version = 2;
-            frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
-            | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
         }
+        frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
+            | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
 
         t_framelength += frame_length;
 
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: main.c,v 1.32 2003/06/07 11:06:37 menno Exp $
+** $Id: main.c,v 1.33 2003/06/23 15:21:19 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -40,75 +40,125 @@
 #endif
 
 #define MAX_CHANNELS 6 /* make this higher to support files with
-                          more channels */
 
+                          more channels */
 /* FAAD file buffering routines */
-/* declare buffering variables */
-#define DEC_BUFF_VARS \
-    int fileread, bytesconsumed, k; \
-    int buffercount = 0, buffer_index = 0; \
-    unsigned char *buffer; \
-    unsigned int bytes_in_buffer = 0;
+typedef struct {
+    long bytes_into_buffer;
+    long bytes_consumed;
+    __int64 file_offset;
+    unsigned char *buffer;
+    int at_eof;
+    FILE *infile;
+} aac_buffer;
 
-/* initialise buffering */
-#define INIT_BUFF(file) \
-    fseek(file, 0, SEEK_END); \
-    fileread = ftell(file); \
-    fseek(file, 0, SEEK_SET); \
-    buffer = (unsigned char*)malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS); \
-    memset(buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS); \
-    bytes_in_buffer = fread(buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, file);
 
-/* skip bytes in buffer */
-#define UPDATE_BUFF_SKIP(bytes) \
-    fseek(infile, bytes, SEEK_SET); \
-    buffer_index += bytes; \
-    buffercount = 0; \
-    bytes_in_buffer = fread(buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, infile);
+int fill_buffer(aac_buffer *b)
+{
+    int bread;
 
-/* update buffer */
-#define UPDATE_BUFF_READ \
-    if (bytesconsumed > 0) { \
-        for (k = 0; k < (FAAD_MIN_STREAMSIZE*MAX_CHANNELS - bytesconsumed); k++) \
-            buffer[k] = buffer[k + bytesconsumed]; \
-        bytes_in_buffer += fread(buffer + (FAAD_MIN_STREAMSIZE*MAX_CHANNELS) - bytesconsumed, 1, bytesconsumed, infile); \
-        bytesconsumed = 0; \
-    }
+    if (b->bytes_consumed > 0)
+    {
+        if (b->bytes_into_buffer)
+        {
+            memmove((void*)b->buffer, (void*)(b->buffer + b->bytes_consumed),
+                b->bytes_into_buffer*sizeof(unsigned char));
+        }
 
-/* update buffer indices after faacDecDecode */
-#define UPDATE_BUFF_IDX(frame) \
-    bytesconsumed += frame.bytesconsumed; \
-    buffer_index += frame.bytesconsumed; \
-    bytes_in_buffer -= frame.bytesconsumed;
+        if (!b->at_eof)
+        {
+            bread = fread((void*)(b->buffer + b->bytes_into_buffer), 1,
+                b->bytes_consumed, b->infile);
 
-/* true if decoding has to stop because of EOF */
-#define IS_FILE_END buffer_index >= fileread
+            if (bread != b->bytes_consumed)
+                b->at_eof = 1;
 
-/* end buffering */
-#define END_BUFF if (buffer) free(buffer);
+            b->bytes_into_buffer += bread;
+        }
 
+        b->bytes_consumed = 0;
 
+        if (b->bytes_into_buffer > 3)
+        {
+            if (memcmp(b->buffer, "TAG", 3) == 0)
+                b->bytes_into_buffer = 0;
+        }
+        if (b->bytes_into_buffer > 11)
+        {
+            if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
+                b->bytes_into_buffer = 0;
+        }
+        if (b->bytes_into_buffer > 8)
+        {
+            if (memcmp(b->buffer, "APETAGEX", 8) == 0)
+                b->bytes_into_buffer = 0;
+        }
+    }
 
-/* globals */
-char *progName;
+    return 1;
+}
 
-int id3v2_tag(unsigned char *buffer)
+void advance_buffer(aac_buffer *b, int bytes)
 {
-    if (strncmp(buffer, "ID3", 3) == 0) {
-        unsigned long tagsize;
+    b->file_offset += bytes;
+    b->bytes_consumed = bytes;
+    b->bytes_into_buffer -= bytes;
+}
 
-        /* high bit is not used */
-        tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
-            (buffer[8] <<  7) | (buffer[9] <<  0);
+int adts_parse(aac_buffer *b, int *bitrate, float *length)
+{
+    static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
+    int frames, frame_length;
+    int t_framelength = 0;
+    int samplerate;
+    float frames_per_sec, bytes_per_frame;
 
-        tagsize += 10;
+    /* Read all frames to ensure correct time and bitrate */
+    for (frames = 0; /* */; frames++)
+    {
+        fill_buffer(b);
 
-        return tagsize;
-    } else {
-        return 0;
+        if (b->bytes_into_buffer > 7)
+        {
+            /* check syncword */
+            if (!((b->buffer[0] == 0xFF)&&((b->buffer[1] & 0xF6) == 0xF0)))
+                break;
+
+            if (frames == 0)
+                samplerate = sample_rates[(b->buffer[2]&0x3c)>>2];
+
+            frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11)
+                | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5);
+
+            t_framelength += frame_length;
+
+            if (frame_length > b->bytes_into_buffer)
+                break;
+
+            advance_buffer(b, frame_length);
+        } else {
+            break;
+        }
     }
+
+    frames_per_sec = (float)samplerate/1024.0;
+    if (frames != 0)
+        bytes_per_frame = (float)t_framelength/(float)(frames*1000);
+    else
+        bytes_per_frame = 0;
+    *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
+    if (frames_per_sec != 0)
+        *length = (float)frames/frames_per_sec;
+    else
+        *length = 1;
+
+    return 1;
 }
 
+
+/* globals */
+char *progName;
+
 char *file_ext[] =
 {
     NULL,
@@ -163,8 +213,6 @@
     unsigned char channels;
     void *sample_buffer;
 
-    FILE *infile;
-
     audio_file *aufile;
 
     faacDecHandle hDecoder;
@@ -173,28 +221,55 @@
 
     char percents[200];
     int percent, old_percent = -1;
+    int bread, fileread;
+    int header_type = 0;
+    int bitrate = 0;
+    float length = 0;
 
     int first_time = 1;
 
+    aac_buffer b;
 
-    /* declare variables for buffering */
-    DEC_BUFF_VARS
+    memset(&b, 0, sizeof(aac_buffer));
 
-
-    infile = fopen(aacfile, "rb");
-    if (infile == NULL)
+    b.infile = fopen(aacfile, "rb");
+    if (b.infile == NULL)
     {
         /* unable to open file */
         fprintf(stderr, "Error opening file: %s\n", aacfile);
         return 1;
     }
-    INIT_BUFF(infile)
 
-    tagsize = id3v2_tag(buffer);
-    if (tagsize) {
-        UPDATE_BUFF_SKIP(tagsize)
+    fseek(b.infile, 0, SEEK_END);
+    fileread = ftell(b.infile);
+    fseek(b.infile, 0, SEEK_SET);
+
+    if (!(b.buffer = (unsigned char*)malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)))
+    {
+        fprintf(stderr, "Memory allocation error\n");
+        return 0;
     }
+    memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
 
+    bread = fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b.infile);
+    b.bytes_into_buffer = bread;
+    b.bytes_consumed = 0;
+    b.file_offset = 0;
+
+    if (bread != 768*6)
+        b.at_eof = 1;
+
+    tagsize = 0;
+    if (!memcmp(b.buffer, "ID3", 3))
+    {
+        /* high bit is not used */
+        tagsize = (b.buffer[6] << 21) | (b.buffer[7] << 14) |
+            (b.buffer[8] <<  7) | (b.buffer[9] <<  0);
+
+        tagsize += 10;
+        advance_buffer(&b, tagsize);
+    }
+
     hDecoder = faacDecOpen();
 
     /* Set the default object type and samplerate */
@@ -207,28 +282,82 @@
 
     faacDecSetConfiguration(hDecoder, config);
 
-    if ((bytesconsumed = faacDecInit(hDecoder, buffer, bytes_in_buffer,
-        &samplerate, &channels)) < 0)
+    /* get AAC infos for printing */
+    header_type = 0;
+    if ((b.buffer[0] == 0xFF) && ((b.buffer[1] & 0xF6) == 0xF0))
     {
+        adts_parse(&b, &bitrate, &length);
+        fseek(b.infile, tagsize, SEEK_SET);
+
+        bread = fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b.infile);
+        if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
+            b.at_eof = 1;
+        else
+            b.at_eof = 0;
+        b.bytes_into_buffer = bread;
+        b.bytes_consumed = 0;
+        b.file_offset = tagsize;
+
+        header_type = 1;
+    } else if (memcmp(b.buffer, "ADIF", 4) == 0) {
+        int skip_size = (b.buffer[4] & 0x80) ? 9 : 0;
+        bitrate = ((unsigned int)(b.buffer[4 + skip_size] & 0x0F)<<19) |
+            ((unsigned int)b.buffer[5 + skip_size]<<11) |
+            ((unsigned int)b.buffer[6 + skip_size]<<3) |
+            ((unsigned int)b.buffer[7 + skip_size] & 0xE0);
+
+        length = (float)fileread;
+        if (length != 0)
+        {
+            length = ((float)length*8.)/((float)bitrate) + 0.5;
+        }
+
+        bitrate = (int)((float)bitrate/1000.0 + 0.5);
+
+        header_type = 2;
+    }
+
+    fill_buffer(&b);
+    if ((bread = faacDecInit(hDecoder, b.buffer,
+        b.bytes_into_buffer, &samplerate, &channels)) < 0)
+    {
         /* If some error initializing occured, skip the file */
         fprintf(stderr, "Error initializing decoder library.\n");
-        END_BUFF
+        if (b.buffer)
+            free(b.buffer);
         faacDecClose(hDecoder);
-        fclose(infile);
+        fclose(b.infile);
         return 1;
     }
-    buffer_index += bytesconsumed;
+    advance_buffer(&b, bread);
 
+    /* print AAC file info */
+    fprintf(stderr, "AAC file info:\n");
+    switch (header_type)
+    {
+    case 0:
+        fprintf(stderr, "RAW\n\n");
+        break;
+    case 1:
+        fprintf(stderr, "ADTS, %.3f sec, %d kbps, %d Hz\n\n",
+            length, bitrate, samplerate);
+        break;
+    case 2:
+        fprintf(stderr, "ADIF, %.3f sec, %d kbps, %d Hz\n\n",
+            length, bitrate, samplerate);
+        break;
+    }
+
     do
     {
-        /* update buffer */
-        UPDATE_BUFF_READ
+        /* fill buffer */
+        fill_buffer(&b);
 
         sample_buffer = faacDecDecode(hDecoder, &frameInfo,
-            buffer, bytes_in_buffer);
+            b.buffer, b.bytes_into_buffer);
 
         /* update buffer indices */
-        UPDATE_BUFF_IDX(frameInfo)
+        advance_buffer(&b, frameInfo.bytesconsumed);
 
         if (frameInfo.error > 0)
         {
@@ -236,7 +365,7 @@
                 faacDecGetErrorMessage(frameInfo.error));
         }
 
-        percent = min((int)(buffer_index*100)/fileread, 100);
+        percent = min((int)(b.file_offset*100)/fileread, 100);
         if (percent > old_percent)
         {
             old_percent = percent;
@@ -250,7 +379,7 @@
         /* open the sound file now that the number of channels are known */
         if (first_time && !frameInfo.error)
         {
-            if(!to_stdout)
+            if (!to_stdout)
             {
                 aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
                     outputFormat, fileType);
@@ -260,9 +389,10 @@
             }
             if (aufile == NULL)
             {
-                END_BUFF
+                if (b.buffer)
+                    free(b.buffer);
                 faacDecClose(hDecoder);
-                fclose(infile);
+                fclose(b.infile);
                 return 0;
             }
             first_time = 0;
@@ -273,7 +403,7 @@
             write_audio_file(aufile, sample_buffer, frameInfo.samples);
         }
 
-        if (buffer_index >= fileread)
+        if (b.bytes_into_buffer == 0)
             sample_buffer = NULL; /* to make sure it stops now */
 
     } while (sample_buffer != NULL);
@@ -281,12 +411,13 @@
 
     faacDecClose(hDecoder);
 
-    fclose(infile);
+    fclose(b.infile);
 
     if (!first_time)
         close_audio_file(aufile);
 
-    END_BUFF
+    if (b.buffer)
+        free(b.buffer);
 
     return frameInfo.error;
 }
@@ -336,6 +467,7 @@
                   int outputFormat, int fileType)
 {
     int track;
+    unsigned int tracks;
     unsigned long samplerate;
     unsigned char channels;
     void *sample_buffer;
@@ -370,6 +502,26 @@
         /* unable to open file */
         fprintf(stderr, "Error opening file: %s\n", mp4file);
         return 1;
+    }
+
+    /* print some mp4 file info */
+    tracks = MP4GetNumberOfTracks(infile, NULL, 0);
+    if (tracks > 0)
+    {
+        char *file_info;
+        unsigned int i;
+
+        fprintf(stderr, "MP4 file info:\n");
+        for (i = 0; i < tracks; i++)
+        {
+            file_info = MP4Info(infile, i+1);
+            if (file_info)
+            {
+                fprintf(stderr, "Track: %s", file_info);
+                free(file_info);
+            }
+        }
+        fprintf(stderr, "\n");
     }
 
     if ((track = GetAACTrack(infile)) < 0)
--- a/libfaad/data.c
+++ /dev/null
@@ -1,268 +1,0 @@
-/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
-**  
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-** 
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software 
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** $Id: data.c,v 1.6 2002/12/22 19:58:31 menno Exp $
-**/
-
-#include "common.h"
-#include "data.h"
-
-#ifdef LD_DEC
-extern uint8_t num_swb_512_window[] =
-{
-    0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0
-};
-extern uint8_t num_swb_480_window[] =
-{
-    0, 0, 0, 35, 35, 37, 30, 30, 0, 0, 0, 0
-};
-#endif
-
-extern uint8_t num_swb_960_window[] =
-{
-    40, 40, 45, 49, 49, 49, 46, 46, 42, 42, 42, 40
-};
-
-extern uint8_t num_swb_1024_window[] =
-{
-    41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
-};
-
-extern uint8_t num_swb_128_window[] =
-{
-    12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15
-};
-
-static 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 uint16_t swb_offset_128_96[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
-};
-
-static 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 uint16_t swb_offset_128_64[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
-};
-
-
-static 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
-};
-
-#ifdef LD_DEC
-static uint16_t swb_offset_512_48[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 68, 76, 84,
-    92, 100, 112, 124, 136, 148, 164, 184, 208, 236, 268, 300, 332, 364, 396,
-    428, 460, 512
-};
-
-static uint16_t swb_offset_480_48[] =
-{
-    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, 272, 304, 336, 368, 400,
-    432, 480
-};
-#endif
-
-static uint16_t swb_offset_128_48[] =
-{
-    0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128
-};
-
-static 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
-};
-
-#ifdef LD_DEC
-static uint16_t swb_offset_512_32[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80,
-    88, 96, 108, 120, 132, 144, 160, 176, 192, 212, 236, 260, 288, 320, 352,
-    384, 416, 448, 480, 512
-};
-
-static uint16_t swb_offset_480_32[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80,
-    88, 96, 104, 112, 124, 136, 148, 164, 180, 200, 224, 256, 288, 320, 352,
-    384, 416, 448, 480
-};
-#endif
-
-static 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
-};
-
-#ifdef LD_DEC
-static uint16_t swb_offset_512_24[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68,
-    80, 92, 104, 120, 140, 164, 192, 224, 256, 288, 320, 352, 384, 416,
-    448, 480, 512
-};
-
-static uint16_t swb_offset_480_24[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 80, 92, 104, 120,
-    140, 164, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480
-};
-#endif
-
-static uint16_t swb_offset_128_24[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128
-};
-
-static 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 uint16_t swb_offset_128_16[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128
-};
-
-static 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 uint16_t swb_offset_128_8[] =
-{
-    0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128
-};
-
-extern uint16_t *swb_offset_1024_window[] =
-{
-    swb_offset_1024_96,      /* 96000 */
-    swb_offset_1024_96,      /* 88200 */
-    swb_offset_1024_64,      /* 64000 */
-    swb_offset_1024_48,      /* 48000 */
-    swb_offset_1024_48,      /* 44100 */
-    swb_offset_1024_32,      /* 32000 */
-    swb_offset_1024_24,      /* 24000 */
-    swb_offset_1024_24,      /* 22050 */
-    swb_offset_1024_16,      /* 16000 */
-    swb_offset_1024_16,      /* 12000 */
-    swb_offset_1024_16,      /* 11025 */
-    swb_offset_1024_8        /* 8000  */
-};
-
-#ifdef LD_DEC
-extern uint16_t *swb_offset_512_window[] =
-{
-    0,                       /* 96000 */
-    0,                       /* 88200 */
-    0,                       /* 64000 */
-    swb_offset_512_48,       /* 48000 */
-    swb_offset_512_48,       /* 44100 */
-    swb_offset_512_32,       /* 32000 */
-    swb_offset_512_24,       /* 24000 */
-    swb_offset_512_24,       /* 22050 */
-    0,                       /* 16000 */
-    0,                       /* 12000 */
-    0,                       /* 11025 */
-    0                        /* 8000  */
-};
-
-extern uint16_t *swb_offset_480_window[] =
-{
-    0,                       /* 96000 */
-    0,                       /* 88200 */
-    0,                       /* 64000 */
-    swb_offset_480_48,       /* 48000 */
-    swb_offset_480_48,       /* 44100 */
-    swb_offset_480_32,       /* 32000 */
-    swb_offset_480_24,       /* 24000 */
-    swb_offset_480_24,       /* 22050 */
-    0,                       /* 16000 */
-    0,                       /* 12000 */
-    0,                       /* 11025 */
-    0                        /* 8000  */
-};
-#endif
-
-extern uint16_t *swb_offset_128_window[] =
-{
-    swb_offset_128_96,       /* 96000 */
-    swb_offset_128_96,       /* 88200 */
-    swb_offset_128_64,       /* 64000 */
-    swb_offset_128_48,       /* 48000 */
-    swb_offset_128_48,       /* 44100 */
-    swb_offset_128_48,       /* 32000 */
-    swb_offset_128_24,       /* 24000 */
-    swb_offset_128_24,       /* 22050 */
-    swb_offset_128_16,       /* 16000 */
-    swb_offset_128_16,       /* 12000 */
-    swb_offset_128_16,       /* 11025 */
-    swb_offset_128_8         /* 8000  */
-};
-
-extern uint8_t pred_sfb_max[] =
-{
-    33,     /* 96000 */
-    33,     /* 88200 */
-    38,     /* 64000 */
-    40,     /* 48000 */
-    40,     /* 44100 */
-    40,     /* 32000 */
-    41,     /* 24000 */
-    41,     /* 22050 */
-    37,     /* 16000 */
-    37,     /* 12000 */
-    37,     /* 11025 */
-    34      /* 8000  */
-};
-
-extern uint32_t sample_rates[] =
-{
-    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000,
-    12000, 11025, 8000
-};
\ No newline at end of file
--- a/libfaad/data.h
+++ /dev/null
@@ -1,48 +1,0 @@
-/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
-**  
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-** 
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software 
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** $Id: data.h,v 1.6 2002/12/22 19:58:31 menno Exp $
-**/
-
-#ifndef __DATA_H__
-#define __DATA_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern uint8_t num_swb_1024_window[];
-extern uint8_t num_swb_960_window[];
-#ifdef LD_DEC
-extern uint8_t num_swb_512_window[];
-extern uint8_t num_swb_480_window[];
-#endif
-extern uint8_t num_swb_128_window[];
-extern uint16_t *swb_offset_1024_window[];
-#ifdef LD_DEC
-extern uint16_t *swb_offset_512_window[];
-extern uint16_t *swb_offset_480_window[];
-#endif
-extern uint16_t *swb_offset_128_window[];
-extern uint8_t pred_sfb_max[];
-extern uint32_t sample_rates[];
-
-#ifdef __cplusplus
-}
-#endif
-#endif
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: decoder.c,v 1.56 2003/05/15 20:58:46 menno Exp $
+** $Id: decoder.c,v 1.57 2003/06/23 15:21:19 menno Exp $
 **/
 
 #include "common.h"
@@ -29,7 +29,6 @@
 #include "mp4.h"
 #include "syntax.h"
 #include "specrec.h"
-#include "data.h"
 #include "tns.h"
 #include "pns.h"
 #include "is.h"
--- a/libfaad/hcr.c
+++ b/libfaad/hcr.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: hcr.c,v 1.3 2003/04/01 16:34:34 menno Exp $
+** $Id: hcr.c,v 1.4 2003/06/23 15:21:19 menno Exp $
 **/
 
 #include "common.h"
@@ -28,7 +28,6 @@
 #include "syntax.h"
 #include "specrec.h"
 #include "bits.h"
-#include "data.h"
 #include "pulse.h"
 #include "analysis.h"
 #include "bits.h"
--- a/libfaad/ic_predict.c
+++ b/libfaad/ic_predict.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: ic_predict.c,v 1.10 2002/11/28 18:48:30 menno Exp $
+** $Id: ic_predict.c,v 1.11 2003/06/23 15:21:19 menno Exp $
 **/
 
 #include "common.h"
@@ -28,6 +28,31 @@
 #include "ic_predict.h"
 #include "pns.h"
 
+static void flt_round(real_t *pf)
+{
+    /* more stable version for clever compilers like gcc 3.x */
+    int32_t flg;
+    uint32_t tmp, tmp1, tmp2;
+
+    tmp = *(uint32_t*)pf;
+    flg = tmp & (uint32_t)0x00008000;
+    tmp &= (uint32_t)0xffff0000;
+    tmp1 = tmp;
+
+    /* round 1/2 lsb toward infinity */
+    if (flg)
+    {
+        tmp &= (uint32_t)0xff800000;       /* extract exponent and sign */
+        tmp |= (uint32_t)0x00010000;       /* insert 1 lsb */
+        tmp2 = tmp;                             /* add 1 lsb and elided one */
+        tmp &= (uint32_t)0xff800000;       /* extract exponent and sign */
+        
+        *pf = *(real_t*)&tmp1+*(real_t*)&tmp2-*(real_t*)&tmp;/* subtract elided one */
+    } else {
+        *pf = *(real_t*)&tmp;
+    }
+}
+
 static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred)
 {
     real_t dr1, predictedvalue;
@@ -42,7 +67,7 @@
     KOR = state->KOR; /* correlations */
     VAR = state->VAR; /* variances */
 
-    if (VAR[0] == 0)
+    if (VAR[0] <= 1)
         k1 = 0;
     else
         k1 = KOR[0]/VAR[0]*B;
@@ -50,12 +75,13 @@
     if (pred)
     {
         /* only needed for the actual predicted value, k1 is always needed */
-        if (VAR[1] == 0)
+        if (VAR[1] <= 1)
             k2 = 0;
         else
             k2 = KOR[1]/VAR[1]*B;
 
         predictedvalue = MUL(k1, r[0]) + MUL(k2, r[1]);
+        flt_round(&predictedvalue);
 
         *output = input + predictedvalue;
     } else {
--- a/libfaad/libfaad.dsp
+++ b/libfaad/libfaad.dsp
@@ -99,10 +99,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=.\data.c
-# End Source File
-# Begin Source File
-
 SOURCE=.\decoder.c
 # End Source File
 # Begin Source File
@@ -268,10 +264,6 @@
 # Begin Source File
 
 SOURCE=.\fftw\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\data.h
 # End Source File
 # Begin Source File
 
--- a/libfaad/mp4.c
+++ b/libfaad/mp4.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: mp4.c,v 1.14 2003/02/09 20:42:49 menno Exp $
+** $Id: mp4.c,v 1.15 2003/06/23 15:21:19 menno Exp $
 **/
 
 #include "common.h"
@@ -26,7 +26,6 @@
 
 #include "bits.h"
 #include "mp4.h"
-#include "data.h"
 #include "syntax.h"
 
 /* defines if an object type can be decoded by this library or not */
--- a/libfaad/specrec.c
+++ b/libfaad/specrec.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: specrec.c,v 1.21 2003/05/16 08:31:14 menno Exp $
+** $Id: specrec.c,v 1.22 2003/06/23 15:21:20 menno Exp $
 **/
 
 /*
@@ -32,10 +32,231 @@
 #include <string.h>
 #include "specrec.h"
 #include "syntax.h"
-#include "data.h"
 #include "iq_table.h"
 
+#ifdef LD_DEC
+static uint8_t num_swb_512_window[] =
+{
+    0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0
+};
+static uint8_t num_swb_480_window[] =
+{
+    0, 0, 0, 35, 35, 37, 30, 30, 0, 0, 0, 0
+};
+#endif
 
+static uint8_t num_swb_960_window[] =
+{
+    40, 40, 45, 49, 49, 49, 46, 46, 42, 42, 42, 40
+};
+
+static uint8_t num_swb_1024_window[] =
+{
+    41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
+};
+
+static uint8_t num_swb_128_window[] =
+{
+    12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15
+};
+
+static 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 uint16_t swb_offset_128_96[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+static 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 uint16_t swb_offset_128_64[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+
+static 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
+};
+
+#ifdef LD_DEC
+static uint16_t swb_offset_512_48[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 68, 76, 84,
+    92, 100, 112, 124, 136, 148, 164, 184, 208, 236, 268, 300, 332, 364, 396,
+    428, 460, 512
+};
+
+static uint16_t swb_offset_480_48[] =
+{
+    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, 272, 304, 336, 368, 400,
+    432, 480
+};
+#endif
+
+static uint16_t swb_offset_128_48[] =
+{
+    0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128
+};
+
+static 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
+};
+
+#ifdef LD_DEC
+static uint16_t swb_offset_512_32[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80,
+    88, 96, 108, 120, 132, 144, 160, 176, 192, 212, 236, 260, 288, 320, 352,
+    384, 416, 448, 480, 512
+};
+
+static uint16_t swb_offset_480_32[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80,
+    88, 96, 104, 112, 124, 136, 148, 164, 180, 200, 224, 256, 288, 320, 352,
+    384, 416, 448, 480
+};
+#endif
+
+static 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
+};
+
+#ifdef LD_DEC
+static uint16_t swb_offset_512_24[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68,
+    80, 92, 104, 120, 140, 164, 192, 224, 256, 288, 320, 352, 384, 416,
+    448, 480, 512
+};
+
+static uint16_t swb_offset_480_24[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 80, 92, 104, 120,
+    140, 164, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480
+};
+#endif
+
+static uint16_t swb_offset_128_24[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128
+};
+
+static 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 uint16_t swb_offset_128_16[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128
+};
+
+static 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 uint16_t swb_offset_128_8[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128
+};
+
+static uint16_t *swb_offset_1024_window[] =
+{
+    swb_offset_1024_96,      /* 96000 */
+    swb_offset_1024_96,      /* 88200 */
+    swb_offset_1024_64,      /* 64000 */
+    swb_offset_1024_48,      /* 48000 */
+    swb_offset_1024_48,      /* 44100 */
+    swb_offset_1024_32,      /* 32000 */
+    swb_offset_1024_24,      /* 24000 */
+    swb_offset_1024_24,      /* 22050 */
+    swb_offset_1024_16,      /* 16000 */
+    swb_offset_1024_16,      /* 12000 */
+    swb_offset_1024_16,      /* 11025 */
+    swb_offset_1024_8        /* 8000  */
+};
+
+#ifdef LD_DEC
+static uint16_t *swb_offset_512_window[] =
+{
+    0,                       /* 96000 */
+    0,                       /* 88200 */
+    0,                       /* 64000 */
+    swb_offset_512_48,       /* 48000 */
+    swb_offset_512_48,       /* 44100 */
+    swb_offset_512_32,       /* 32000 */
+    swb_offset_512_24,       /* 24000 */
+    swb_offset_512_24,       /* 22050 */
+    0,                       /* 16000 */
+    0,                       /* 12000 */
+    0,                       /* 11025 */
+    0                        /* 8000  */
+};
+
+static uint16_t *swb_offset_480_window[] =
+{
+    0,                       /* 96000 */
+    0,                       /* 88200 */
+    0,                       /* 64000 */
+    swb_offset_480_48,       /* 48000 */
+    swb_offset_480_48,       /* 44100 */
+    swb_offset_480_32,       /* 32000 */
+    swb_offset_480_24,       /* 24000 */
+    swb_offset_480_24,       /* 22050 */
+    0,                       /* 16000 */
+    0,                       /* 12000 */
+    0,                       /* 11025 */
+    0                        /* 8000  */
+};
+#endif
+
+static uint16_t *swb_offset_128_window[] =
+{
+    swb_offset_128_96,       /* 96000 */
+    swb_offset_128_96,       /* 88200 */
+    swb_offset_128_64,       /* 64000 */
+    swb_offset_128_48,       /* 48000 */
+    swb_offset_128_48,       /* 44100 */
+    swb_offset_128_48,       /* 32000 */
+    swb_offset_128_24,       /* 24000 */
+    swb_offset_128_24,       /* 22050 */
+    swb_offset_128_16,       /* 16000 */
+    swb_offset_128_16,       /* 12000 */
+    swb_offset_128_16,       /* 11025 */
+    swb_offset_128_8         /* 8000  */
+};
+
 #define bit_set(A, B) ((A) & (1<<(B)))
 
 /* 4.5.2.3.4 */
@@ -350,8 +571,6 @@
             exp = (ics->scale_factors[g][sfb] - 100) / 4;
             frac = (ics->scale_factors[g][sfb] - 100) % 4;
 
-            /* MDCT scaling done here to get values within 16 bit range */
-            /* the extra 3 bit shift is for iq_table[] compensation */
             if (hDecoder->object_type == LD)
             {
                 exp -= 6 /*9*/;
--- a/libfaad/specrec.h
+++ b/libfaad/specrec.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: specrec.h,v 1.11 2003/05/15 20:58:47 menno Exp $
+** $Id: specrec.h,v 1.12 2003/06/23 15:21:20 menno Exp $
 **/
 
 #ifndef __SPECREC_H__
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: syntax.c,v 1.44 2003/04/15 19:53:42 menno Exp $
+** $Id: syntax.c,v 1.45 2003/06/23 15:21:20 menno Exp $
 **/
 
 /*
@@ -34,7 +34,6 @@
 #include "specrec.h"
 #include "huffman.h"
 #include "bits.h"
-#include "data.h"
 #include "pulse.h"
 #include "analysis.h"
 #include "drc.h"
@@ -641,6 +640,22 @@
 
     return 0;
 }
+
+static uint8_t pred_sfb_max[] =
+{
+    33,     /* 96000 */
+    33,     /* 88200 */
+    38,     /* 64000 */
+    40,     /* 48000 */
+    40,     /* 44100 */
+    40,     /* 32000 */
+    41,     /* 24000 */
+    41,     /* 22050 */
+    37,     /* 16000 */
+    37,     /* 12000 */
+    37,     /* 11025 */
+    34      /* 8000  */
+};
 
 /* Table 4.4.6 */
 static uint8_t ics_info(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
--- a/libfaad/syntax.h
+++ b/libfaad/syntax.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: syntax.h,v 1.27 2003/04/13 18:27:10 menno Exp $
+** $Id: syntax.h,v 1.28 2003/06/23 15:21:20 menno Exp $
 **/
 
 #ifndef __SYNTAX_H__
@@ -80,6 +80,11 @@
 #define INTENSITY_HCB2 14
 #define INTENSITY_HCB  15
 
+static uint32_t sample_rates[] =
+{
+    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000,
+    12000, 11025, 8000
+};
 
 int8_t GASpecificConfig(bitfile *ld, mp4AudioSpecificConfig *mp4ASC);
 
--- a/libfaad/tns.c
+++ b/libfaad/tns.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: tns.c,v 1.19 2003/02/14 14:54:24 menno Exp $
+** $Id: tns.c,v 1.20 2003/06/23 15:21:20 menno Exp $
 **/
 
 #include "common.h"
@@ -111,7 +111,8 @@
         {
             top = bottom;
             bottom = max(top - tns->length[w][f], 0);
-            tns_order = min(tns->order[w][f], TNS_MAX_ORDER);
+            tns_order = min(tns->order[w][f], tns_max_order(ics, sr_index,
+                object_type));
             if (!tns_order)
                 continue;
 
@@ -118,8 +119,12 @@
             tns_decode_coef(tns_order, tns->coef_res[w]+3,
                 tns->coef_compress[w][f], tns->coef[w][f], lpc);
 
-            start = ics->swb_offset[min(bottom, ics->max_sfb)];
-            end = ics->swb_offset[min(top, ics->max_sfb)];
+            start = ics->swb_offset[min(bottom,
+                min(tns_max_bands(ics, sr_index, object_type, frame_len),
+                ics->max_sfb))];
+            end = ics->swb_offset[min(top,
+                min(tns_max_bands(ics, sr_index, object_type, frame_len),
+                ics->max_sfb))];
 
             if ((size = end - start) <= 0)
                 continue;
@@ -158,7 +163,8 @@
         {
             top = bottom;
             bottom = max(top - tns->length[w][f], 0);
-            tns_order = min(tns->order[w][f], TNS_MAX_ORDER);
+            tns_order = min(tns->order[w][f], tns_max_order(ics, sr_index,
+                object_type));
             if (!tns_order)
                 continue;
 
@@ -165,8 +171,12 @@
             tns_decode_coef(tns_order, tns->coef_res[w]+3,
                 tns->coef_compress[w][f], tns->coef[w][f], lpc);
 
-            start = ics->swb_offset[min(bottom, ics->max_sfb)];
-            end = ics->swb_offset[min(top, ics->max_sfb)];
+            start = ics->swb_offset[min(bottom,
+                min(tns_max_bands(ics, sr_index, object_type, frame_len),
+                ics->max_sfb))];
+            end = ics->swb_offset[min(top,
+                min(tns_max_bands(ics, sr_index, object_type, frame_len),
+                ics->max_sfb))];
 
             if ((size = end - start) <= 0)
                 continue;
@@ -294,4 +304,84 @@
         *spectrum = y;
         spectrum += inc;
     }
+}
+
+static uint8_t tns_max_bands_table[12][6] =
+{
+    /* entry for each sampling rate
+     * 1    Main/LC long window
+     * 2    Main/LC short window
+     * 3    SSR long window
+     * 4    SSR short window
+     * 5    LD 512 window
+     * 6    LD 480 window
+     */
+    { 31,  9, 28, 7, 0,  0  },       /* 96000 */
+    { 31,  9, 28, 7, 0,  0  },       /* 88200 */
+    { 34, 10, 27, 7, 0,  0  },       /* 64000 */
+    { 40, 14, 26, 6, 31, 31 },       /* 48000 */
+    { 42, 14, 26, 6, 32, 32 },       /* 44100 */
+    { 51, 14, 26, 6, 37, 37 },       /* 32000 */
+    { 46, 14, 29, 7, 31, 30 },       /* 24000 */
+    { 46, 14, 29, 7, 31, 30 },       /* 22050 */
+    { 42, 14, 23, 8, 0,  0  },       /* 16000 */
+    { 42, 14, 23, 8, 0,  0  },       /* 12000 */
+    { 42, 14, 23, 8, 0,  0  },       /* 11025 */
+    { 39, 14, 19, 7, 0,  0  },       /* 8000  */
+};
+
+static uint8_t tns_max_bands(ic_stream *ics, uint8_t sr_index,
+                             uint8_t object_type, uint16_t frame_len)
+{
+    uint8_t i;
+
+    i = (ics->window_sequence == EIGHT_SHORT_SEQUENCE) ? 1 : 0;
+#ifdef LD_DEC
+    if (object_type == LD)
+    {
+        if (frame_len == 512)
+            i = 4;
+        else
+            i = 5;
+    }
+#endif
+
+    return tns_max_bands_table[sr_index][i];
+}
+
+static uint8_t tns_max_order(ic_stream *ics, uint8_t sr_index,
+                             uint8_t object_type)
+{
+    /* Correction in 14496-3 Cor. 1
+       Works like MPEG2-AAC (13818-7) now
+
+       For other object types (scalable) the following goes for tns max order
+       for long windows:
+       if (sr_index <= 5)
+           return 12;
+       else
+           return 20;
+    */
+    if (ics->window_sequence != EIGHT_SHORT_SEQUENCE)
+    {
+        switch (object_type)
+        {
+        case MAIN:
+        case LTP:
+        case ER_LTP:
+#ifdef LD_DEC
+        case LD:
+#endif
+            return 20;
+        case LC:
+        case ER_LC:
+        case DRM_ER_LC:
+        case SSR:
+            return 12;
+        }
+    } else {
+        return 7;
+    }
+
+    return 0;
 }
--- a/libfaad/tns.h
+++ b/libfaad/tns.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: tns.h,v 1.6 2003/02/14 14:54:25 menno Exp $
+** $Id: tns.h,v 1.7 2003/06/23 15:21:20 menno Exp $
 **/
 
 #ifndef __TNS_H__
@@ -41,6 +41,10 @@
                           uint8_t order);
 static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
                           uint8_t order);
+static uint8_t tns_max_bands(ic_stream *ics, uint8_t sr_index,
+                             uint8_t object_type, uint16_t frame_len);
+static uint8_t tns_max_order(ic_stream *ics, uint8_t sr_index,
+                             uint8_t object_type);
 
 
 #ifdef __cplusplus