shithub: aacdec

Download patch

ref: 5a3586372506a3bf38f16985f00a5a44aa11c43c
parent: fb9d1d265e8cd35a9ca377a78484bcbe87803405
author: menno <menno>
date: Mon Aug 26 15:08:39 EDT 2002

Added noise shaping options by john33

--- a/aacDECdrop/Script.rc
+++ b/aacDECdrop/Script.rc
@@ -97,7 +97,7 @@
 // Dialog
 //
 
-IDD_VOLUME DIALOGEX 0, 0, 255, 236
+IDD_VOLUME DIALOGEX 0, 0, 255, 257
 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 
     WS_SYSMENU
 CAPTION "Decoder Options V1.2"
@@ -117,7 +117,7 @@
                     WS_DISABLED,15,60,65,10
     CONTROL         "DEC AU",IDC_DECAU,"Button",BS_AUTORADIOBUTTON | 
                     WS_DISABLED,125,60,65,10
-    GROUPBOX        "Output Sample Format Settings",IDC_STATIC,7,82,241,65
+    GROUPBOX        "Output Sample Format Settings",IDC_STATIC,7,82,241,91
     CONTROL         "16 bit PCM",IDC_16BIT,"Button",BS_AUTORADIOBUTTON | 
                     WS_GROUP,15,96,65,10
     CONTROL         "24 bit PCM",IDC_24BIT,"Button",BS_AUTORADIOBUTTON,125,
@@ -128,22 +128,31 @@
                     125,111,65,10
     CONTROL         "16 bit PCM - Dithered",IDC_16BIT_DITHER,"Button",
                     BS_AUTORADIOBUTTON,15,126,83,10
-    GROUPBOX        "Object Type Settings",IDC_STATIC,7,149,241,50
+    CONTROL         "16 bit PCM - Dithered with",IDC_16BIT_L_SHAPE,"Button",
+                    BS_AUTORADIOBUTTON,125,126,98,10
+    CONTROL         "16 bit PCM - Dithered with",IDC_16BIT_M_SHAPE,"Button",
+                    BS_AUTORADIOBUTTON,15,146,98,10
+    CONTROL         "16 bit PCM - Dithered with",IDC_16BIT_H_SHAPE,"Button",
+                    BS_AUTORADIOBUTTON,125,146,98,10
+    LTEXT           "LIGHT Noise Shaping",IDC_STATIC,138,136,70,8
+    LTEXT           "HEAVY Noise Shaping",IDC_STATIC,138,156,73,8
+    LTEXT           "MEDIUM Noise Shaping",IDC_STATIC,28,156,78,8
+    GROUPBOX        "Object Type Settings",IDC_STATIC,7,174,241,50
     CONTROL         "Main",IDC_MAIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
-                    15,163,65,10
+                    15,188,65,10
     CONTROL         "Low Complexity",IDC_LC,"Button",BS_AUTORADIOBUTTON,125,
-                    163,65,10
+                    188,65,10
     CONTROL         "Long Term Prediction",IDC_LTP,"Button",
-                    BS_AUTORADIOBUTTON,15,178,85,10
-    CONTROL         "Low Delay",IDC_LD,"Button",BS_AUTORADIOBUTTON,125,178,
+                    BS_AUTORADIOBUTTON,15,203,85,10
+    CONTROL         "Low Delay",IDC_LD,"Button",BS_AUTORADIOBUTTON,125,203,
                     65,10
-    DEFPUSHBUTTON   "Accept",IDC_BUTTON1,102,210,50,16
+    DEFPUSHBUTTON   "Accept",IDC_BUTTON1,102,233,50,16
 END
 
 IDD_ABOUT DIALOGEX 0, 0, 255, 194
 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 
     WS_SYSMENU
-CAPTION "About aacDECdrop V1.21"
+CAPTION "About aacDECdrop V1.22"
 FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
     GROUPBOX        "",IDC_STATIC,7,5,241,157
@@ -171,6 +180,22 @@
     CONTROL         112,IDC_STATIC,"Static",SS_BITMAP | SS_SUNKEN,12,13,43,
                     40
 END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_VOLUME, DIALOG
+    BEGIN
+        BOTTOMMARGIN, 256
+    END
+END
+#endif    // APSTUDIO_INVOKED
 
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
--- a/aacDECdrop/audio.c
+++ b/aacDECdrop/audio.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: audio.c,v 1.6 2002/08/14 10:55:28 menno Exp $
+** $Id: audio.c,v 1.7 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -39,7 +39,7 @@
 
     aufile->samplerate = samplerate;
     aufile->channels = channels;
-    aufile->samples = 0;
+    aufile->total_samples = 0;
     aufile->fileType = fileType;
 
     switch (outputFormat)
@@ -46,6 +46,9 @@
     {
     case FAAD_FMT_16BIT:
     case FAAD_FMT_16BIT_DITHER:
+    case FAAD_FMT_16BIT_L_SHAPE:
+    case FAAD_FMT_16BIT_M_SHAPE:
+    case FAAD_FMT_16BIT_H_SHAPE:
         aufile->bits_per_sample = 16;
         break;
     case FAAD_FMT_24BIT:
@@ -88,6 +91,9 @@
     {
     case FAAD_FMT_16BIT:
     case FAAD_FMT_16BIT_DITHER:
+    case FAAD_FMT_16BIT_L_SHAPE:
+    case FAAD_FMT_16BIT_M_SHAPE:
+    case FAAD_FMT_16BIT_H_SHAPE:
         return write_audio_16bit(aufile, sample_buffer, samples);
     case FAAD_FMT_24BIT:
         return write_audio_24bit(aufile, sample_buffer, samples);
@@ -121,9 +127,8 @@
     unsigned char header[44];
     unsigned char* p = header;
     unsigned int bytes = (aufile->bits_per_sample + 7) / 8;
-    float data_size = (float)bytes * aufile->samples;
+    float data_size = (float)bytes * aufile->total_samples;
     unsigned long word32;
-    int ret;
 
     *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F';
 
@@ -177,9 +182,7 @@
     *p++ = (unsigned char)(word32 >> 16);
     *p++ = (unsigned char)(word32 >> 24);
 
-    ret = fwrite(header, sizeof(header), 1, aufile->sndfile);
-
-    return ret;
+    return fwrite(header, sizeof(header), 1, aufile->sndfile);
 }
 
 static int write_audio_16bit(audio_file *aufile, void *sample_buffer,
@@ -190,12 +193,12 @@
     short *sample_buffer16 = (short*)sample_buffer;
     char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
 
-    aufile->samples += samples;
+    aufile->total_samples += samples;
 
     for (i = 0; i < samples; i++)
     {
-        data[i*2] = sample_buffer16[i] & 0xFF;
-        data[i*2+1] = (sample_buffer16[i] >> 8) & 0xFF;
+        data[i*2] = (char)(sample_buffer16[i] & 0xFF);
+        data[i*2+1] = (char)((sample_buffer16[i] >> 8) & 0xFF);
     }
 
     ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
@@ -213,13 +216,13 @@
     long *sample_buffer24 = (long*)sample_buffer;
     char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
 
-    aufile->samples += samples;
+    aufile->total_samples += samples;
 
     for (i = 0; i < samples; i++)
     {
-        data[i*3] = sample_buffer24[i] & 0xFF;
-        data[i*3+1] = (sample_buffer24[i] >> 8) & 0xFF;
-        data[i*3+2] = (sample_buffer24[i] >> 16) & 0xFF;
+        data[i*3] = (char)(sample_buffer24[i] & 0xFF);
+        data[i*3+1] = (char)((sample_buffer24[i] >> 8) & 0xFF);
+        data[i*3+2] = (char)((sample_buffer24[i] >> 16) & 0xFF);
     }
 
     ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
@@ -237,14 +240,14 @@
     long *sample_buffer32 = (long*)sample_buffer;
     char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
 
-    aufile->samples += samples;
+    aufile->total_samples += samples;
 
     for (i = 0; i < samples; i++)
     {
-        data[i*4] = sample_buffer32[i] & 0xFF;
-        data[i*4+1] = (sample_buffer32[i] >> 8) & 0xFF;
-        data[i*4+2] = (sample_buffer32[i] >> 16) & 0xFF;
-        data[i*4+3] = (sample_buffer32[i] >> 24) & 0xFF;
+        data[i*4] = (char)(sample_buffer32[i] & 0xFF);
+        data[i*4+1] = (char)((sample_buffer32[i] >> 8) & 0xFF);
+        data[i*4+2] = (char)((sample_buffer32[i] >> 16) & 0xFF);
+        data[i*4+3] = (char)((sample_buffer32[i] >> 24) & 0xFF);
     }
 
     ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
@@ -262,7 +265,7 @@
     float *sample_buffer_f = (float*)sample_buffer;
     unsigned char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
 
-    aufile->samples += samples;
+    aufile->total_samples += samples;
 
     for (i = 0; i < samples; i++)
     {
@@ -278,7 +281,7 @@
             in *= -1.0;
             negative = 1;
         }
-        in = frexp(in, &exponent);
+        in = (float)frexp(in, &exponent);
         exponent += 126;
         in *= (float)0x1000000;
         mantissa = (((int)in) & 0x7FFFFF);
--- a/aacDECdrop/audio.h
+++ b/aacDECdrop/audio.h
@@ -1,22 +1,22 @@
 /*
 ** 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 
+** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: audio.h,v 1.5 2002/08/14 10:55:28 menno Exp $
+** $Id: audio.h,v 1.6 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifndef AUDIO_H_INCLUDED
@@ -41,7 +41,7 @@
     unsigned long samplerate;
     unsigned int bits_per_sample;
     unsigned int channels;
-    unsigned long samples;
+    unsigned long total_samples;
 } audio_file;
 
 audio_file *open_audio_file(char *infile, int samplerate, int channels,
--- a/aacDECdrop/main.c
+++ b/aacDECdrop/main.c
@@ -509,12 +509,21 @@
 				CheckDlgButton(hwndDlg,IDC_PLAYBACK,TRUE);
 				CheckDlgButton(hwndDlg,IDC_WAV,TRUE);
 				if(iniSettings.outputFormat != 1
-					&& iniSettings.outputFormat != 5)
+					&& iniSettings.outputFormat != 5
+					&& iniSettings.outputFormat != 6
+					&& iniSettings.outputFormat != 7
+					&& iniSettings.outputFormat != 8)
 					CheckDlgButton(hwndDlg,IDC_16BIT,TRUE);
 				else if(iniSettings.outputFormat == 1)
 					CheckDlgButton(hwndDlg,IDC_16BIT,TRUE);
 				else if(iniSettings.outputFormat == 5)
 					CheckDlgButton(hwndDlg,IDC_16BIT_DITHER,TRUE);
+				else if(iniSettings.outputFormat == 6)
+					CheckDlgButton(hwndDlg,IDC_16BIT_L_SHAPE,TRUE);
+				else if(iniSettings.outputFormat == 7)
+					CheckDlgButton(hwndDlg,IDC_16BIT_M_SHAPE,TRUE);
+				else if(iniSettings.outputFormat == 8)
+					CheckDlgButton(hwndDlg,IDC_16BIT_H_SHAPE,TRUE);
 				CheckDlgButton(hwndDlg,IDC_WAV,TRUE);
 				EnableWindow(GetDlgItem(hwndDlg, IDC_AIFF), FALSE);
 				EnableWindow(GetDlgItem(hwndDlg, IDC_SUNAU), FALSE);
@@ -538,6 +547,12 @@
 					CheckDlgButton(hwndDlg,IDC_FLOATS,TRUE);
 				else if(iniSettings.outputFormat == 5)
 					CheckDlgButton(hwndDlg,IDC_16BIT_DITHER,TRUE);
+				else if(iniSettings.outputFormat == 6)
+					CheckDlgButton(hwndDlg,IDC_16BIT_L_SHAPE,TRUE);
+				else if(iniSettings.outputFormat == 7)
+					CheckDlgButton(hwndDlg,IDC_16BIT_M_SHAPE,TRUE);
+				else if(iniSettings.outputFormat == 8)
+					CheckDlgButton(hwndDlg,IDC_16BIT_H_SHAPE,TRUE);
 
 				if(iniSettings.fileType == 1)
 					CheckDlgButton(hwndDlg,IDC_WAV,TRUE);
@@ -592,6 +607,12 @@
 						set_outputFormat(4);             // 32 bit floats
 					else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_DITHER) == BST_CHECKED)
 						set_outputFormat(5);             // 16 bit PCM dithered
+					else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_L_SHAPE) == BST_CHECKED)
+						set_outputFormat(6);             // dithered LIGHT noise shaping
+					else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_M_SHAPE) == BST_CHECKED)
+						set_outputFormat(7);             // dithered MEDIUM noise shaping
+					else if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_H_SHAPE) == BST_CHECKED)
+						set_outputFormat(8);             // dithered HEAVY noise shaping
 
 					if (IsDlgButtonChecked(hwndDlg, IDC_MAIN) == BST_CHECKED)
 						set_object_type(0);             // Main
@@ -622,8 +643,13 @@
 					CheckDlgButton(hwndDlg,IDC_FLOATS,FALSE);
 					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT), TRUE);
 					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_DITHER), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_L_SHAPE), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_M_SHAPE), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_H_SHAPE), TRUE);
 					if (IsDlgButtonChecked(hwndDlg, IDC_16BIT_DITHER) != BST_CHECKED
-						&& IsDlgButtonChecked(hwndDlg, IDC_16BIT) != BST_CHECKED)
+						&& IsDlgButtonChecked(hwndDlg, IDC_16BIT_L_SHAPE) != BST_CHECKED
+						&& IsDlgButtonChecked(hwndDlg, IDC_16BIT_M_SHAPE) != BST_CHECKED
+						&& IsDlgButtonChecked(hwndDlg, IDC_16BIT_H_SHAPE) != BST_CHECKED)
 						CheckDlgButton(hwndDlg,IDC_16BIT,TRUE);
 					break;
 				case IDC_DECODE:
@@ -635,6 +661,9 @@
 					EnableWindow(GetDlgItem(hwndDlg, IDC_FLOATS), TRUE);
 					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT), TRUE);
 					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_DITHER), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_L_SHAPE), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_M_SHAPE), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_16BIT_H_SHAPE), TRUE);
 					break;
 				default:
 					break;
--- a/aacDECdrop/resource.h
+++ b/aacDECdrop/resource.h
@@ -30,6 +30,9 @@
 #define IDC_LTP                         1025
 #define IDC_LD                          1026
 #define IDC_16BIT_DITHER                1027
+#define IDC_16BIT_L_SHAPE               1028
+#define IDC_16BIT_M_SHAPE               1029
+#define IDC_16BIT_H_SHAPE               1030
 #define IDC_BUTTON6                     1033
 #define IDM_VOLUME                      40005
 #define IDM_STOP_DEC                    40006
@@ -45,7 +48,7 @@
 #define _APS_NO_MFC                     1
 #define _APS_NEXT_RESOURCE_VALUE        134
 #define _APS_NEXT_COMMAND_VALUE         40018
-#define _APS_NEXT_CONTROL_VALUE         1028
+#define _APS_NEXT_CONTROL_VALUE         1031
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
--- a/frontend/audio.c
+++ b/frontend/audio.c
@@ -1,22 +1,22 @@
 /*
 ** 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
+** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: audio.c,v 1.9 2002/08/21 16:23:15 menno Exp $
+** $Id: audio.c,v 1.10 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -46,6 +46,9 @@
     {
     case FAAD_FMT_16BIT:
     case FAAD_FMT_16BIT_DITHER:
+    case FAAD_FMT_16BIT_L_SHAPE:
+    case FAAD_FMT_16BIT_M_SHAPE:
+    case FAAD_FMT_16BIT_H_SHAPE:
         aufile->bits_per_sample = 16;
         break;
     case FAAD_FMT_24BIT:
@@ -88,6 +91,9 @@
     {
     case FAAD_FMT_16BIT:
     case FAAD_FMT_16BIT_DITHER:
+    case FAAD_FMT_16BIT_L_SHAPE:
+    case FAAD_FMT_16BIT_M_SHAPE:
+    case FAAD_FMT_16BIT_H_SHAPE:
         return write_audio_16bit(aufile, sample_buffer, samples);
     case FAAD_FMT_24BIT:
         return write_audio_24bit(aufile, sample_buffer, samples);
@@ -99,7 +105,7 @@
         return 0;
     }
 
-    return 0;
+	return 0;
 }
 
 void close_audio_file(audio_file *aufile)
--- 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.22 2002/08/14 10:55:28 menno Exp $
+** $Id: main.c,v 1.23 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -134,6 +134,9 @@
     fprintf(stderr, "        3:  32 bit PCM data.\n");
     fprintf(stderr, "        4:  32 bit floating point data.\n");
     fprintf(stderr, "        5:  16 bit PCM data (dithered).\n");
+    fprintf(stderr, "        6:  16 bit PCM data (dithered with LIGHT noise shaping).\n");
+    fprintf(stderr, "        7:  16 bit PCM data (dithered with MEDIUM noise shaping).\n");
+    fprintf(stderr, "        8:  16 bit PCM data (dithered with HEAVY noise shaping).\n");
     fprintf(stderr, " -s X  Force the samplerate to X (for RAW files).\n");
     fprintf(stderr, " -l X  Set object type. Supported object types:\n");
     fprintf(stderr, "        0:  Main object type.\n");
@@ -564,7 +567,7 @@
                     outputFormat = FAAD_FMT_16BIT; /* just use default */
                 } else {
                     outputFormat = atoi(dr);
-                    if ((outputFormat < 1) || (outputFormat > 5))
+                    if ((outputFormat < 1) || (outputFormat > 8))
                         showHelp = 1;
                 }
             }
@@ -613,7 +616,6 @@
 #else
     begin = clock();
 #endif
-
 
     /* Only calculate the path and open the file for writing if
        we are not writing to stdout.
--- a/include/faad.h
+++ b/include/faad.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: faad.h,v 1.12 2002/08/26 18:41:47 menno Exp $
+** $Id: faad.h,v 1.13 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifndef __AACDEC_H__
@@ -53,6 +53,9 @@
 #define FAAD_FMT_32BIT 3
 #define FAAD_FMT_FLOAT 4
 #define FAAD_FMT_16BIT_DITHER 5
+#define FAAD_FMT_16BIT_L_SHAPE 6
+#define FAAD_FMT_16BIT_M_SHAPE 7
+#define FAAD_FMT_16BIT_H_SHAPE 8
 
 /* A decode call can eat up to FAAD_MIN_STREAMSIZE octets per decoded channel,
    so at least so much octets per channel should be available in this stream */
--- 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.21 2002/08/26 18:41:47 menno Exp $
+** $Id: decoder.c,v 1.22 2002/08/26 19:08:39 menno Exp $
 **/
 
 #include <stdlib.h>
@@ -36,6 +36,7 @@
 #include "drc.h"
 #include "error.h"
 #include "output.h"
+#include "dither.h"
 
 #ifdef ANALYSIS
 uint16_t dbg_count;
@@ -245,6 +246,9 @@
     if (can_decode_ot(hDecoder->object_type) < 0)
         return -1;
 
+    if (hDecoder->config.outputFormat > 5)
+        Init_Dither(16, hDecoder->config.outputFormat - 5);
+
     return bits;
 }
 
@@ -291,6 +295,9 @@
     if (hDecoder->object_type == LD)
         hDecoder->frameLength >>= 1;
 #endif
+
+    if (hDecoder->config.outputFormat > 5)
+        Init_Dither(16, hDecoder->config.outputFormat - 5);
 
     return 0;
 }
--- a/libfaad/decoder.h
+++ b/libfaad/decoder.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: decoder.h,v 1.10 2002/08/26 18:41:47 menno Exp $
+** $Id: decoder.h,v 1.11 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -49,6 +49,9 @@
 #define FAAD_FMT_32BIT 3
 #define FAAD_FMT_FLOAT 4
 #define FAAD_FMT_16BIT_DITHER 5
+#define FAAD_FMT_16BIT_L_SHAPE 6
+#define FAAD_FMT_16BIT_M_SHAPE 7
+#define FAAD_FMT_16BIT_H_SHAPE 8
 
 typedef struct faacDecConfiguration
 {
--- a/libfaad/dither.c
+++ b/libfaad/dither.c
@@ -5,11 +5,12 @@
  * mostly lifted from work by Frank Klemm
  * random functions for dithering.
  *
- * last modified: $Id: dither.c,v 1.1 2002/08/13 19:16:07 menno Exp $
+ * last modified: $ID:$
  */
+#include "common.h"
 #include "dither.h"
 
-static const  unsigned char    Parity [256] = {  // parity
+static const  uint8_t    Parity [256] = {  // parity
 	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
 	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
 	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
@@ -20,8 +21,8 @@
 	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
 };
 
-static unsigned int  __r1 = 1;
-static unsigned int  __r2 = 1;
+static uint32_t  __r1 = 1;
+static uint32_t  __r2 = 1;
 
 
 /*
@@ -52,10 +53,10 @@
  */
 
 
-unsigned int
+uint32_t
 random_int ( void )
 {
-	unsigned int  t1, t2, t3, t4;
+	uint32_t  t1, t2, t3, t4;
 
 	t3   = t1 = __r1;   t4   = t2 = __r2;       // Parity calculation is done via table lookup, this is also available
 	t1  &= 0xF5;        t2 >>= 25;              // on CPUs without parity, can be implemented in C and avoid unpredictable
@@ -79,20 +80,104 @@
 	return mult * ( (double) (int) random_int () + (double) (int) random_int () );
 }
 
+/*********************************************************************************************************************/
 
+static const float32_t  F44_0 [16 + 32] = {
+	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
+	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
+
+	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
+	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
+
+	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
+	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0
+};
+
+
+static const float32_t  F44_1 [16 + 32] = {  /* SNR(w) = 4.843163 dB, SNR = -3.192134 dB */
+	(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
+	(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
+	(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
+	(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
+
+	(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
+	(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
+	(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
+	(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
+
+	(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
+	(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
+	(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
+	(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
+};
+
+
+static const float32_t  F44_2 [16 + 32] = {  /* SNR(w) = 10.060213 dB, SNR = -12.766730 dB */
+	(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
+	(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
+	(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
+	(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
+
+	(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
+	(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
+	(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
+	(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
+
+	(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
+	(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
+	(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
+	(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
+};
+
+
+static const float32_t  F44_3 [16 + 32] = {  /* SNR(w) = 15.382598 dB, SNR = -29.402334 dB */
+	(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
+	(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
+	(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
+	(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,
+
+	(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
+	(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
+	(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
+	(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,
+
+	(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
+	(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
+	(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
+	(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099
+};
+
+
 double
-Init_Dither(int bits)
+scalar16 ( const float32_t* x, const float32_t* y )
 {
-	static unsigned char        default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67,  0,  0 };
-	int                         index;
+	return x[ 0]*y[ 0] + x[ 1]*y[ 1] + x[ 2]*y[ 2] + x[ 3]*y[ 3]
+	     + x[ 4]*y[ 4] + x[ 5]*y[ 5] + x[ 6]*y[ 6] + x[ 7]*y[ 7]
+	     + x[ 8]*y[ 8] + x[ 9]*y[ 9] + x[10]*y[10] + x[11]*y[11]
+	     + x[12]*y[12] + x[13]*y[13] + x[14]*y[14] + x[15]*y[15];
+}
 
-	index = bits - 11;
+
+void
+Init_Dither ( unsigned char bits, unsigned char shapingtype )
+{
+	static uint8_t          default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67,  0,  0 };
+	static const float32_t*              F [] = { F44_0, F44_1, F44_2, F44_3 };
+	uint8_t                 index;
+
+	if (shapingtype < 0) shapingtype = 0;
+	if (shapingtype > 3) shapingtype = 3;
+	index = bits - 11 - shapingtype;
 	if (index < 0) index = 0;
 	if (index > 9) index = 9;
 
-	Dither.Add    = 0.5     * ((1L << (32 - bits)) - 1);
+	memset ( Dither.ErrorHistory , 0, sizeof (Dither.ErrorHistory ) );
+	memset ( Dither.DitherHistory, 0, sizeof (Dither.DitherHistory) );
 
-	Dither.Dither = (0.01*default_dither[index]) / (((__int64)1) << bits);
+	Dither.FilterCoeff = F [shapingtype];
+	Dither.Mask   = ((uint64_t)-1) << (32 - bits);
+	Dither.Add    = 0.5     * ((1L << (32 - bits)) - 1);
+	Dither.Dither = 0.01*default_dither[index] / (((int64_t)1) << bits);
 }
 
 
--- a/libfaad/dither.h
+++ b/libfaad/dither.h
@@ -5,9 +5,11 @@
  *
  * rand_t header.
  *
- * last modified: $Id: dither.h,v 1.1 2002/08/13 19:16:07 menno Exp $
+ * last modified: $ID:$
  */
 
+#include "common.h"
+
 #ifndef __RAND_T_H
 #define __RAND_T_H
 
@@ -16,18 +18,23 @@
 #endif 
 
 typedef struct {
-    double                 Add;
-    float                  Dither;
-    int                    LastRandomNumber [2];
+    const float32_t*  FilterCoeff;
+    uint64_t          Mask;
+    double            Add;
+    float32_t         Dither;
+    float32_t         ErrorHistory     [2] [16];       // max. 2 channels, 16th order Noise shaping
+    float32_t         DitherHistory    [2] [16];
+    int32_t           LastRandomNumber [2];
 } dither_t;
 
 extern dither_t            Dither;
 extern double              doubletmp;
-static const unsigned char Parity [256];
-unsigned int               random_int ( void );
+static const uint8_t       Parity [256];
+uint32_t                   random_int ( void );
+extern double              scalar16 ( const float32_t* x, const float32_t* y );
 extern double              Random_Equi ( double mult );
 extern double              Random_Triangular ( double mult );
-extern double              Init_Dither ( int bits );
+void                       Init_Dither ( unsigned char bits, unsigned char shapingtype );
 
 #ifdef __cplusplus
 }
--- /dev/null
+++ b/libfaad/fixed.h
@@ -1,0 +1,99 @@
+/*
+** 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: fixed.h,v 1.1 2002/08/26 19:08:39 menno Exp $
+**/
+
+#ifndef __FIXED_H__
+#define __FIXED_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COEF_1_BITS 31
+#define COEF_1_PRECISION (1 << COEF_1_BITS)
+#define COEF_BITS 28
+#define COEF_PRECISION (1 << COEF_BITS)
+#define REAL_BITS 7
+#define REAL_PRECISION (1 << REAL_BITS)
+
+#define COEF_CONST_1(A) ((real_t)(A*(COEF_1_PRECISION)))
+#define REAL_CONST(A) ((real_t)(A*(REAL_PRECISION)))
+#define COEF_CONST(A) ((real_t)(A*(COEF_PRECISION)))
+
+#if defined(_WIN32)
+
+/* multiply real with real */
+static INLINE MUL(real_t A, real_t B)
+{
+    _asm {
+        mov eax,A
+        imul B
+        shrd eax,edx,REAL_BITS
+    }
+}
+
+/* multiply coef with coef */
+static INLINE MUL_C_C(real_t A, real_t B)
+{
+    _asm {
+        mov eax,A
+        imul B
+        shrd eax,edx,COEF_BITS
+    }
+}
+
+/* multiply real with coef */
+static INLINE MUL_R_C(real_t A, real_t B)
+{
+    _asm {
+        mov eax,A
+        imul B
+        shrd eax,edx,COEF_BITS
+    }
+}
+
+/* multiply real with coef_1 */
+static INLINE MUL_R_1(real_t A, real_t B)
+{
+    _asm {
+        mov eax,A
+        imul B
+        shrd eax,edx,COEF_1_BITS
+    }
+}
+
+#else
+
+  /* multiply real with real */
+  #define MUL(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS)
+  /* multiply coef with coef */
+  #define MUL_C_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)
+  /* multiply real with coef */
+  #define MUL_R_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)
+  /* multiply real with coef_1 */
+  #define MUL_R_1(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_1_BITS-1))) >> COEF_1_BITS)
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- a/libfaad/output.c
+++ b/libfaad/output.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: output.c,v 1.11 2002/08/26 18:41:47 menno Exp $
+** $Id: output.c,v 1.12 2002/08/26 19:08:39 menno Exp $
 **/
 
 #include "common.h"
@@ -46,7 +46,7 @@
                     uint16_t frame_len, uint8_t format)
 {
     uint8_t ch;
-    uint16_t i;
+    uint16_t i, j = 0;
 
     int16_t   *short_sample_buffer = (int16_t*)sample_buffer;
     int32_t   *int_sample_buffer = (int32_t*)sample_buffer;
@@ -71,10 +71,13 @@
     case FAAD_FMT_16BIT_DITHER:
         for (ch = 0; ch < channels; ch++)
         {
-            for(i = 0; i < frame_len; i++)
+            for(i = 0; i < frame_len; i++, j++)
             {
                 double Sum = input[ch][i] * 65535.f;
-                int64_t val = dither_output(1, Sum, ch) / 65536;
+                int64_t val;
+                if(j > 31)
+                   j = 0;
+                val = dither_output(1, 0, j, Sum, ch) / 65536;
                 if (val > (1<<15)-1)
                     val = (1<<15)-1;
                 else if (val < -(1<<15))
@@ -83,6 +86,26 @@
             }
         }
         break;
+    case FAAD_FMT_16BIT_L_SHAPE:
+    case FAAD_FMT_16BIT_M_SHAPE:
+    case FAAD_FMT_16BIT_H_SHAPE:
+        for (ch = 0; ch < channels; ch++)
+        {
+            for(i = 0; i < frame_len; i++, j++)
+            {
+                double Sum = input[ch][i] * 65535.f;
+                int64_t val;
+                if(j > 31)
+                   j = 0;
+                val = dither_output(1, 1, j, Sum, ch) / 65536;
+                if (val > (1<<15)-1)
+                    val = (1<<15)-1;
+                else if (val < -(1<<15))
+                    val = -(1<<15);
+                short_sample_buffer[(i*channels)+ch] = (int16_t)val;
+            }
+        }
+        break;
     case FAAD_FMT_24BIT:
         for (ch = 0; ch < channels; ch++)
         {
@@ -153,18 +176,28 @@
 #endif
 
 /* Dither output */
-static int64_t dither_output(uint8_t dithering, double Sum, uint8_t k)
+static int64_t dither_output(uint8_t dithering, uint8_t shapingtype, uint16_t i, double Sum, uint8_t k)
 {
     double Sum2;
-
+    int64_t val;
     if(dithering)
     {
-        double tmp = Random_Equi(Dither.Dither);
-        Sum2 = tmp - Dither.LastRandomNumber[k];
-        Dither.LastRandomNumber[k] = tmp;
-        Sum2 = Sum += Sum2;
-        return ROUND64(Sum2);
-    } else {
-        return ROUND64(Sum);
+        if(!shapingtype)
+        {
+            double tmp = Random_Equi(Dither.Dither);
+            Sum2 = tmp - Dither.LastRandomNumber[k];
+            Dither.LastRandomNumber[k] = tmp;
+            Sum2 = Sum += Sum2;
+            val = ROUND64(Sum2)&Dither.Mask;
+        } else {
+            Sum2 = Random_Triangular(Dither.Dither) - scalar16(Dither.DitherHistory[k], Dither.FilterCoeff + i);
+            Sum += Dither.DitherHistory[k][(-1-i)&15] = Sum2;
+            Sum2 = Sum + scalar16(Dither.ErrorHistory[k], Dither.FilterCoeff + i );
+            val = ROUND64(Sum2)&Dither.Mask;
+            Dither.ErrorHistory[k][(-1-i)&15] = (float)(Sum - val);
+        }
+        return val;
     }
+    else
+        return ROUND64 (Sum);
 }
--- a/libfaad/output.h
+++ b/libfaad/output.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: output.h,v 1.5 2002/08/13 19:16:07 menno Exp $
+** $Id: output.h,v 1.6 2002/08/26 19:08:39 menno Exp $
 **/
 
 #ifndef __OUTPUT_H__
@@ -32,7 +32,8 @@
                     uint16_t frame_len,
                     uint8_t format);
 
-static int64_t dither_output(uint8_t dithering, double Sum, uint8_t k);
+static int64_t dither_output(uint8_t dithering, uint8_t shapingtype,
+                             uint16_t i, double Sum, uint8_t k);
 
 #ifdef __cplusplus
 }