shithub: aacdec

Download patch

ref: 35f8e224dba9885e99c7e3fff80c9706def70d1d
parent: 86c9aebfb42aa5909ae2eed6b438f16411909789
author: menno <menno>
date: Tue Aug 13 15:16:07 EDT 2002

Added option for dithered output
and some updates to aacDECdrop

--- a/aacDECdrop/Script.rc
+++ b/aacDECdrop/Script.rc
@@ -72,6 +72,7 @@
     BEGIN
         MENUITEM "&Decoder Options",            IDM_VOLUME
         MENUITEM "&Stop Decoding",              IDM_STOP_DEC
+        MENUITEM "&About",                      IDM_ABOUT
         MENUITEM SEPARATOR
         MENUITEM "&Errors to Log File",         IDM_LOGERR
         MENUITEM "&Always on Top",              IDM_ONTOP
@@ -110,12 +111,12 @@
     GROUPBOX        "Output Format Settings",IDC_STATIC,7,31,241,50
     CONTROL         "Microsoft WAV",IDC_WAV,"Button",BS_AUTORADIOBUTTON | 
                     WS_GROUP,15,45,65,10
-    CONTROL         "Apple/SGI AIFF",IDC_AIFF,"Button",BS_AUTORADIOBUTTON,
-                    125,45,65,10
-    CONTROL         "Sun/NeXT AU",IDC_SUNAU,"Button",BS_AUTORADIOBUTTON,15,
-                    60,65,10
-    CONTROL         "DEC AU",IDC_DECAU,"Button",BS_AUTORADIOBUTTON,125,60,65,
-                    10
+    CONTROL         "Apple/SGI AIFF",IDC_AIFF,"Button",BS_AUTORADIOBUTTON | 
+                    WS_DISABLED,125,45,65,10
+    CONTROL         "Sun/NeXT AU",IDC_SUNAU,"Button",BS_AUTORADIOBUTTON | 
+                    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,50
     CONTROL         "16 bit PCM",IDC_16BIT,"Button",BS_AUTORADIOBUTTON | 
                     WS_GROUP,15,96,65,10
@@ -135,6 +136,40 @@
     CONTROL         "Low Delay",IDC_LD,"Button",BS_AUTORADIOBUTTON,125,162,
                     65,10
     DEFPUSHBUTTON   "Accept",IDC_BUTTON1,102,192,50,16
+END
+
+IDD_ABOUT DIALOG  0, 0, 255, 194
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "About aacDECdrop V1.2"
+FONT 8, "MS Sans Serif"
+BEGIN
+    GROUPBOX        "",IDC_STATIC,7,5,241,157
+    CTEXT           "A decoder to decode/playback aac/Mpeg4 files.",
+                    IDC_STATIC,70,13,155,8
+    CTEXT           "Copyright 2002 John Edwards.",IDC_STATIC,70,29,97,8
+    CTEXT           "Utilises standard libfaad from Menno Bakker and",
+                    IDC_STATIC,70,37,153,8
+    CTEXT           "LibSndFile from Erik de Castro Lopo.",IDC_STATIC,70,45,
+                    115,8
+    LTEXT           "This program is free software; you can redistribute it and/or modify it",
+                    IDC_STATIC,13,62,212,8
+    LTEXT           "under the terms of the GNU Public Licence as published by the Free",
+                    IDC_STATIC,13,72,215,8
+    LTEXT           "Software Foundation; either version 2 of the Licence, or (at your option)",
+                    IDC_STATIC,13,82,224,8
+    LTEXT           "any later version.",IDC_STATIC,13,92,54,8
+    LTEXT           "This program is distributed in the hope that it will be useful, but",
+                    IDC_STATIC,13,112,195,8
+    LTEXT           "WITHOUT ANY WARRANTY; without even the implied warranty of",
+                    IDC_STATIC,13,122,213,8
+    LTEXT           "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
+                    IDC_STATIC,13,132,218,8
+    LTEXT           "See the GNU General Public Licence for more details.",
+                    IDC_STATIC,13,142,170,8
+    DEFPUSHBUTTON   "OK",IDC_BUTTON6,102,171,50,16
+    CONTROL         112,IDC_STATIC,"Static",SS_BITMAP | SS_SUNKEN,12,13,43,
+                    40
 END
 
 #endif    // English (U.S.) resources
--- a/aacDECdrop/aacDECdrop/aacDECdrop.dsp
+++ b/aacDECdrop/aacDECdrop/aacDECdrop.dsp
@@ -43,7 +43,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /GX /Ot /I "..\..\include" /I "..\..\common\libsndfile\src" /I "..\..\common\mp4v2" /I "..\..\common\libsndfile\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /QaxK /GA /Qwp_ipo /c
+# ADD CPP /nologo /G6 /MT /GX /O2 /I "..\..\include" /I "..\..\common\libsndfile\src" /I "..\..\common\mp4v2" /I "..\..\common\libsndfile\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /QaxK /Qsox- /Qip /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x809 /d "NDEBUG"
@@ -53,7 +53,7 @@
 # ADD BSC32 /nologo
 LINK32=xilink6.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ws2_32.lib svml_disp.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBCMT.lib"
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib svml_disp.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBCMT.lib"
 # Begin Special Build Tool
 SOURCE="$(InputPath)"
 PostBuild_Desc=Compressing using UPX...
@@ -71,10 +71,9 @@
 # PROP Use_Debug_Libraries 1
 # PROP Output_Dir "Debug"
 # PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\libsndfile\src" /I "..\..\common\mp4v2" /I "..\..\common\libsndfile\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\common\libsndfile\src" /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x809 /d "_DEBUG"
@@ -84,7 +83,7 @@
 # ADD BSC32 /nologo
 LINK32=xilink6.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  winmm.lib ws2_32.lib svml_disp.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
 
 !ENDIF 
 
@@ -151,6 +150,14 @@
 # Begin Group "Resource Files"
 
 # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\resource\AAC01.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=..\resource\AAC01.ico
+# End Source File
 # Begin Source File
 
 SOURCE=..\Script.rc
--- a/aacDECdrop/aacDECdrop/aacDECdrop.dsw
+++ b/aacDECdrop/aacDECdrop/aacDECdrop.dsw
@@ -15,10 +15,10 @@
     Project_Dep_Name libfaad
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name libsndfile
+    Project_Dep_Name libmp4v2_st
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name libmp4v2_st
+    Project_Dep_Name libsndfile
     End Project Dependency
 }}}
 
--- 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.4 2002/08/13 14:38:55 menno Exp $
+** $Id: audio.c,v 1.5 2002/08/13 19:16:06 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -44,6 +44,7 @@
     switch (outputFormat)
     {
     case FAAD_FMT_16BIT:
+    case FAAD_FMT_16BIT_DITHER:
         aufile->bits_per_sample = 16;
         break;
     case FAAD_FMT_24BIT:
@@ -86,6 +87,7 @@
     switch (aufile->outputFormat)
     {
     case FAAD_FMT_16BIT:
+    case FAAD_FMT_16BIT_DITHER:
         return write_audio_16bit(aufile, sample_buffer, samples);
     case FAAD_FMT_24BIT:
         return write_audio_24bit(aufile, sample_buffer, samples);
--- a/aacDECdrop/audio.h
+++ b/aacDECdrop/audio.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: audio.h,v 1.3 2002/08/13 14:38:55 menno Exp $
+** $Id: audio.h,v 1.4 2002/08/13 19:16:06 menno Exp $
 **/
 
 #ifndef AUDIO_H_INCLUDED
--- a/aacDECdrop/decode.c
+++ b/aacDECdrop/decode.c
@@ -16,8 +16,8 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: decode.c,v 1.6 2002/08/13 14:38:55 menno Exp $
-** $Id: decode.c,v 1.6 2002/08/13 14:38:55 menno Exp $
+** $Id: decode.c,v 1.7 2002/08/13 19:16:06 menno Exp $
+** $Id: decode.c,v 1.7 2002/08/13 19:16:06 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -35,6 +35,7 @@
 
 #include "audio.h"
 #include "decode.h"
+#include "misc.h"
 #include "wave_out.h"
 
 #ifndef min
@@ -136,7 +137,6 @@
 	faacDecConfigurationPtr config;
 
 	int first_time = 1;
-	int i;
 
 
 	/* declare variables for buffering */
@@ -277,15 +277,13 @@
 		{
 			unsigned char *buff = NULL;
 			int buff_size = 0;
-			unsigned long dummy1_32;
-            unsigned char dummy2_8, dummy3_8, dummy4_8, dummy5_8, dummy6_8,
-                dummy7_8, dummy8_8;
+			unsigned long dummy32; unsigned char dummy8;
 			MP4GetTrackESConfiguration(infile, trackId, &buff, &buff_size);
 
 			if (buff)
 			{
-				rc = AudioSpecificConfig(buff, &dummy1_32, &dummy2_8, &dummy3_8, &dummy4_8,
-                    &dummy5_8, &dummy6_8, &dummy7_8, &dummy8_8);
+				rc = AudioSpecificConfig(buff, &dummy32, &dummy8, &dummy8, &dummy8,
+                    &dummy8, &dummy8, &dummy8, &dummy8);
 				free(buff);
 
 				if (rc < 0)
@@ -318,7 +316,6 @@
 	audio_file *aufile;
 
 	faacDecHandle hDecoder;
-	faacDecConfigurationPtr config;
 	faacDecFrameInfo frameInfo;
 
 	unsigned char *buffer;
--- a/aacDECdrop/decode.h
+++ b/aacDECdrop/decode.h
@@ -13,10 +13,12 @@
 #include <stdio.h>
 
 typedef void (*progress_func)(long totalsamples, long samples);
+typedef void (*error_func)(char *errormessage);
 
 typedef struct
 {
 	progress_func progress_update;
+	error_func error;
 	int decode_mode;
 	int output_format;
 	int file_type;
--- a/aacDECdrop/decthread.c
+++ b/aacDECdrop/decthread.c
@@ -137,6 +137,11 @@
 	object_type = object_type;
 }
 
+void _error(char *errormessage)
+{
+	// do nothing
+}
+
 void _update(long total, long done)
 {
 	file_complete = (double)done / (double)total;
--- a/aacDECdrop/main.c
+++ b/aacDECdrop/main.c
@@ -468,6 +468,13 @@
 						break;
 					break;
 				}
+				case IDM_ABOUT:
+				{
+					int value = DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUT), hwnd, QCProc);
+					if (value == -7)
+						break;
+					break;
+				}
 
 			} // LOWORD(wParam)
 			return 0;
@@ -647,6 +654,10 @@
 					EndDialog(hwndDlg, -2);
 					return TRUE;
 				}
+				case IDC_BUTTON6:
+					EndDialog(hwndDlg, -7);
+					return TRUE;
+
 				case IDC_PLAYBACK:
 					CheckDlgButton(hwndDlg,IDC_DECODE,FALSE);
 					CheckDlgButton(hwndDlg,IDC_WAV,TRUE);
--- a/aacDECdrop/resource.h
+++ b/aacDECdrop/resource.h
@@ -3,6 +3,7 @@
 // Used by Script.rc
 //
 #define IDD_VOLUME                      101
+#define IDD_ABOUT                       102
 #define IDB_TF01                        112
 #define IDB_TF02                        113
 #define IDB_TF03                        114
@@ -28,8 +29,10 @@
 #define IDC_LC                          1024
 #define IDC_LTP                         1025
 #define IDC_LD                          1026
+#define IDC_BUTTON6                     1033
 #define IDM_VOLUME                      40005
 #define IDM_STOP_DEC                    40006
+#define IDM_ABOUT                       40007
 #define IDM_LOGERR                      40008
 #define IDM_ONTOP                       40015
 #define IDM_QUIT                        40019
--- a/frontend/audio.c
+++ b/frontend/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.5 2002/08/13 14:39:03 menno Exp $
+** $Id: audio.c,v 1.6 2002/08/13 19:16:07 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -44,6 +44,7 @@
     switch (outputFormat)
     {
     case FAAD_FMT_16BIT:
+    case FAAD_FMT_16BIT_DITHER:
         aufile->bits_per_sample = 16;
         break;
     case FAAD_FMT_24BIT:
@@ -86,6 +87,7 @@
     switch (aufile->outputFormat)
     {
     case FAAD_FMT_16BIT:
+    case FAAD_FMT_16BIT_DITHER:
         return write_audio_16bit(aufile, sample_buffer, samples);
     case FAAD_FMT_24BIT:
         return write_audio_24bit(aufile, sample_buffer, samples);
--- 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.20 2002/08/13 14:39:03 menno Exp $
+** $Id: main.c,v 1.21 2002/08/13 19:16:07 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -132,6 +132,7 @@
     fprintf(stderr, "        1:  16 bit PCM data (default).\n");
     fprintf(stderr, "        2:  24 bit PCM data.\n");
     fprintf(stderr, "        3:  32 bit PCM data.\n");
+    fprintf(stderr, "        5:  16 bit PCM data (dithered).\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");
@@ -562,7 +563,7 @@
                     outputFormat = FAAD_FMT_16BIT; /* just use default */
                 } else {
                     outputFormat = atoi(dr);
-                    if ((outputFormat < 1) || (outputFormat > 4))
+                    if ((outputFormat < 1) || (outputFormat > 5))
                         showHelp = 1;
                 }
             }
--- 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.10 2002/08/10 19:01:17 menno Exp $
+** $Id: faad.h,v 1.11 2002/08/13 19:16:07 menno Exp $
 **/
 
 #ifndef __AACDEC_H__
@@ -51,6 +51,7 @@
 #define FAAD_FMT_24BIT 2
 #define FAAD_FMT_32BIT 3
 #define FAAD_FMT_FLOAT 4
+#define FAAD_FMT_16BIT_DITHER 5
 
 /* 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/common.h
+++ b/libfaad/common.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: common.h,v 1.14 2002/07/14 19:11:11 menno Exp $
+** $Id: common.h,v 1.15 2002/08/13 19:16:07 menno Exp $
 **/
 
 #ifndef __COMMON_H__
@@ -88,9 +88,11 @@
 #if defined(_WIN32)
 
 
+typedef unsigned __int64 uint64_t;
 typedef unsigned __int32 uint32_t;
 typedef unsigned __int16 uint16_t;
 typedef unsigned __int8 uint8_t;
+typedef __int64 int64_t;
 typedef __int32 int32_t;
 typedef __int16 int16_t;
 typedef __int8  int8_t;
@@ -103,9 +105,11 @@
 #if defined(LINUX)
 #include <stdint.h>
 #else
+typedef unsigned long long uint64_t;
 typedef unsigned long uint32_t;
 typedef unsigned short uint16_t;
 typedef unsigned char uint8_t;
+typedef long long int32_t;
 typedef long int32_t;
 typedef short int16_t;
 typedef char int8_t;
--- 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.7 2002/06/13 11:03:27 menno Exp $
+** $Id: decoder.h,v 1.8 2002/08/13 19:16:07 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -48,6 +48,7 @@
 #define FAAD_FMT_24BIT 2
 #define FAAD_FMT_32BIT 3
 #define FAAD_FMT_FLOAT 4
+#define FAAD_FMT_16BIT_DITHER 5
 
 typedef struct faacDecConfiguration
 {
--- /dev/null
+++ b/libfaad/dither.c
@@ -1,0 +1,99 @@
+/* This program is licensed under the GNU Library General Public License, version 2,
+ * a copy of which is included with this program (with filename LICENSE.LGPL).
+ *
+ * (c) 2002 John Edwards
+ * 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 $
+ */
+#include "dither.h"
+
+static const  unsigned char    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,
+	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,
+	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,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
+};
+
+static unsigned int  __r1 = 1;
+static unsigned int  __r2 = 1;
+
+
+/*
+ *  This is a simple random number generator with good quality for audio purposes.
+ *  It consists of two polycounters with opposite rotation direction and different
+ *  periods. The periods are coprime, so the total period is the product of both.
+ *
+ *     -------------------------------------------------------------------------------------------------
+ * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
+ * |   -------------------------------------------------------------------------------------------------
+ * |                                                                          |  |  |  |     |        |
+ * |                                                                          +--+--+--+-XOR-+--------+
+ * |                                                                                      |
+ * +--------------------------------------------------------------------------------------+
+ *
+ *     -------------------------------------------------------------------------------------------------
+ *     |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
+ *     -------------------------------------------------------------------------------------------------   |
+ *       |  |           |  |                                                                               |
+ *       +--+----XOR----+--+                                                                               |
+ *                |                                                                                        |
+ *                +----------------------------------------------------------------------------------------+
+ *
+ *
+ *  The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
+ *  which gives a period of 18.410.713.077.675.721.215. The result is the
+ *  XORed values of both generators.
+ */
+
+
+unsigned int
+random_int ( void )
+{
+	unsigned int  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
+	t1   = Parity [t1]; t2  &= 0x63;            // jumps and slow rotate through the carry flag operations.
+	t1 <<= 31;          t2   = Parity [t2];
+
+	return (__r1 = (t3 >> 1) | t1 ) ^ (__r2 = (t4 + t4) | t2 );
+}
+
+
+
+double
+Random_Equi ( double mult )                     // gives a equal distributed random number
+{                                               // between -2^31*mult and +2^31*mult
+	return mult * (int) random_int ();
+}
+
+double
+Random_Triangular ( double mult )               // gives a triangular distributed random number
+{                                               // between -2^32*mult and +2^32*mult
+	return mult * ( (double) (int) random_int () + (double) (int) random_int () );
+}
+
+
+double
+Init_Dither(int bits)
+{
+	static unsigned char        default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67,  0,  0 };
+	int                         index;
+
+	index = bits - 11;
+	if (index < 0) index = 0;
+	if (index > 9) index = 9;
+
+	Dither.Add    = 0.5     * ((1L << (32 - bits)) - 1);
+
+	Dither.Dither = (0.01*default_dither[index]) / (((__int64)1) << bits);
+}
+
+
+
--- /dev/null
+++ b/libfaad/dither.h
@@ -1,0 +1,37 @@
+/* This program is licensed under the GNU Library General Public License, version 2,
+ * a copy of which is included with this program (with filename LICENSE.LGPL).
+ *
+ * (c) 2002 John Edwards
+ *
+ * rand_t header.
+ *
+ * last modified: $Id: dither.h,v 1.1 2002/08/13 19:16:07 menno Exp $
+ */
+
+#ifndef __RAND_T_H
+#define __RAND_T_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+typedef struct {
+    double                 Add;
+    float                  Dither;
+    int                    LastRandomNumber [2];
+} dither_t;
+
+extern dither_t            Dither;
+extern double              doubletmp;
+static const unsigned char Parity [256];
+unsigned int               random_int ( void );
+extern double              Random_Equi ( double mult );
+extern double              Random_Triangular ( double mult );
+extern double              Init_Dither ( int bits );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif __RAND_T_H
+
--- a/libfaad/libfaad.vcproj
+++ b/libfaad/libfaad.vcproj
@@ -124,6 +124,9 @@
 				RelativePath=".\decoder.c">
 			</File>
 			<File
+				RelativePath="dither.c">
+			</File>
+			<File
 				RelativePath=".\drc.c">
 			</File>
 			<File
@@ -250,6 +253,9 @@
 			</File>
 			<File
 				RelativePath=".\decoder.h">
+			</File>
+			<File
+				RelativePath="dither.h">
 			</File>
 			<File
 				RelativePath=".\drc.h">
--- 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.9 2002/03/16 15:49:58 menno Exp $
+** $Id: output.c,v 1.10 2002/08/13 19:16:07 menno Exp $
 **/
 
 #include "common.h"
@@ -23,6 +23,7 @@
 
 #include "output.h"
 #include "decoder.h"
+#include "dither.h"
 
 
 #define ftol(A,B) {tmp = *(int32_t*) & A - 0x4B7F8000; \
@@ -32,9 +33,14 @@
 
 #define ROUND32(x) ROUND(x)
 
+#define ROUND64(x) (doubletmp = (x) + Dither.Add + (int64_t)0x001FFFFD80000000L, *(int64_t*)(&doubletmp) - (int64_t)0x433FFFFD80000000L)
+
 #define FLOAT_SCALE (1.0f/(1<<15))
 
+dither_t Dither;
+double doubletmp;
 
+
 void* output_to_PCM(real_t **input, void *sample_buffer, uint8_t channels,
                     uint16_t frame_len, uint8_t format)
 {
@@ -62,6 +68,21 @@
             }
         }
         break;
+    case FAAD_FMT_16BIT_DITHER:
+        for (ch = 0; ch < channels; ch++)
+        {
+            for(i = 0; i < frame_len; i++)
+            {
+                double Sum = input[ch][i] * 65535.f;
+                int64_t val = dither_output(1, 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++)
         {
@@ -104,4 +125,21 @@
     }
 
     return sample_buffer;
-}
\ No newline at end of file
+}
+
+/* Dither output */
+static int64_t dither_output(uint8_t dithering, double Sum, uint8_t k)
+{
+    double Sum2;
+
+    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);
+    }
+}
--- 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.4 2002/05/01 19:25:19 menno Exp $
+** $Id: output.h,v 1.5 2002/08/13 19:16:07 menno Exp $
 **/
 
 #ifndef __OUTPUT_H__
@@ -32,7 +32,7 @@
                     uint16_t frame_len,
                     uint8_t format);
 
-typedef float float32_t;
+static int64_t dither_output(uint8_t dithering, double Sum, uint8_t k);
 
 #ifdef __cplusplus
 }