shithub: aacdec

Download patch

ref: c095b2fdc5c1dc599dcfe9e2b93d23c2224617c7
parent: 3eb36590b9a63b1b719b0f3167c602d1f1bae049
author: menno <menno>
date: Sat Apr 3 14:08:38 EST 2004

Fixed aacDecDrop, now also uses mp4ff, including m4a and m4p support
Added some comments to PS

--- 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 /MD /GX /O2 /I "..\..\include" /I "..\..\common\mp4v2" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /QaxK /Qsox- /Qip /c
+# ADD CPP /nologo /G6 /MD /GX /O2 /I "..\..\include" /I "..\..\common\mp4ff" /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"
@@ -69,7 +69,7 @@
 # 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 /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\mp4v2" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\mp4ff" /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"
--- a/aacDECdrop/aacDECdrop/aacDECdrop.dsw
+++ b/aacDECdrop/aacDECdrop/aacDECdrop.dsw
@@ -15,7 +15,7 @@
     Project_Dep_Name libfaad
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name libmp4v2_st
+    Project_Dep_Name mp4ff
     End Project Dependency
 }}}
 
@@ -33,7 +33,7 @@
 
 ###############################################################################
 
-Project: "libmp4v2_st"=..\..\common\mp4v2\libmp4v2_st60.dsp - Package Owner=<4>
+Project: "mp4ff"=..\..\common\mp4ff\mp4ff.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
--- a/aacDECdrop/decode.c
+++ b/aacDECdrop/decode.c
@@ -16,13 +16,14 @@
 ** 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.15 2004/02/06 10:23:27 menno Exp $
-** $Id: decode.c,v 1.15 2004/02/06 10:23:27 menno Exp $
+** $Id: decode.c,v 1.16 2004/04/03 19:08:37 menno Exp $
+** $Id: decode.c,v 1.16 2004/04/03 19:08:37 menno Exp $
 **/
 
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
+#define off_t __int64
 #else
 #include <time.h>
 #endif
@@ -30,8 +31,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <faad.h>
-#include <mp4.h>
+#include <neaacdec.h>
+#include <mp4ff.h>
 
 #include "audio.h"
 #include "decode.h"
@@ -78,7 +79,7 @@
         bytesconsumed = 0; \
     }
 
-/* update buffer indices after faacDecDecode */
+/* update buffer indices after NeAACDecDecode */
 #define UPDATE_BUFF_IDX(frame) \
     bytesconsumed += frame.bytesconsumed; \
     buffer_index += frame.bytesconsumed; \
@@ -144,7 +145,7 @@
 #define SPEAKER_TOP_BACK_RIGHT         0x20000
 #define SPEAKER_RESERVED               0x80000000
 
-long aacChannelConfig2wavexChannelMask(faacDecFrameInfo *hInfo)
+long aacChannelConfig2wavexChannelMask(NeAACDecFrameInfo *hInfo)
 {
     if (hInfo->channels == 6 && hInfo->num_lfe_channels)
     {
@@ -167,9 +168,9 @@
 
     audio_file *aufile;
 
-    faacDecHandle hDecoder;
-    faacDecFrameInfo frameInfo;
-    faacDecConfigurationPtr config;
+    NeAACDecHandle hDecoder;
+    NeAACDecFrameInfo frameInfo;
+    NeAACDecConfigurationPtr config;
 
     int first_time = 1;
 
@@ -192,25 +193,25 @@
         UPDATE_BUFF_SKIP(tagsize)
     }
 
-    hDecoder = faacDecOpen();
+    hDecoder = NeAACDecOpen();
 
     /* Set the default object type and samplerate */
     /* This is useful for RAW AAC files */
-    config = faacDecGetCurrentConfiguration(hDecoder);
+    config = NeAACDecGetCurrentConfiguration(hDecoder);
     if (def_srate)
         config->defSampleRate = def_srate;
     config->defObjectType = opt->object_type;
     config->outputFormat = opt->output_format;
 
-    faacDecSetConfiguration(hDecoder, config);
+    NeAACDecSetConfiguration(hDecoder, config);
 
-    if ((bytesconsumed = faacDecInit(hDecoder, buffer, bytes_in_buffer,
+    if ((bytesconsumed = NeAACDecInit(hDecoder, buffer, bytes_in_buffer,
         &samplerate, &channels)) < 0)
     {
         /* If some error initializing occured, skip the file */
         error_handler("Error initializing decoder library.\n");
         END_BUFF
-        faacDecClose(hDecoder);
+        NeAACDecClose(hDecoder);
         fclose(infile);
         return 1;
     }
@@ -221,7 +222,7 @@
         /* update buffer */
         UPDATE_BUFF_READ
 
-        sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer);
+        sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer);
 
         /* update buffer indices */
         UPDATE_BUFF_IDX(frameInfo)
@@ -229,7 +230,7 @@
         if (frameInfo.error > 0)
         {
             error_handler("Error: %s\n",
-            faacDecGetErrorMessage(frameInfo.error));
+            NeAACDecGetErrorMessage(frameInfo.error));
         }
 
         opt->progress_update((long)fileread, buffer_index);
@@ -244,7 +245,7 @@
                 {
                     error_handler("\nCan't access %s\n", "WAVE OUT");
                     END_BUFF
-                    faacDecClose(hDecoder);
+                    NeAACDecClose(hDecoder);
                     fclose(infile);
                     return (0);
                 }
@@ -257,7 +258,7 @@
                 if (aufile == NULL)
                 {
                     END_BUFF
-                    faacDecClose(hDecoder);
+                    NeAACDecClose(hDecoder);
                     fclose(infile);
                     return 0;
                 }
@@ -281,7 +282,7 @@
 
     } while (sample_buffer != NULL);
 
-    faacDecClose(hDecoder);
+    NeAACDecClose(hDecoder);
 
     fclose(infile);
 
@@ -298,34 +299,28 @@
     return frameInfo.error;
 }
 
-int GetAACTrack(MP4FileHandle infile)
+int GetAACTrack(mp4ff_t *infile)
 {
     /* find AAC track */
     int i, rc;
-    int numTracks = MP4GetNumberOfTracks(infile, NULL, /* subType */ 0);
+    int numTracks = mp4ff_total_tracks(infile);
 
     for (i = 0; i < numTracks; i++)
     {
-        MP4TrackId trackId = MP4FindTrackId(infile, i, NULL, /* subType */ 0);
-        const char* trackType = MP4GetTrackType(infile, trackId);
+        unsigned char *buff = NULL;
+        int buff_size = 0;
+        mp4AudioSpecificConfig mp4ASC;
 
-        if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE))
+        mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
+
+        if (buff)
         {
-            unsigned char *buff = NULL;
-            int buff_size = 0;
-            mp4AudioSpecificConfig mp4ASC;
+            rc = NeAACDecAudioSpecificConfig(buff, buff_size, &mp4ASC);
+            free(buff);
 
-            MP4GetTrackESConfiguration(infile, trackId, &buff, &buff_size);
-
-            if (buff)
-            {
-                rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
-                free(buff);
-
-                if (rc < 0)
-                    return -1;
-                return trackId;
-            }
+            if (rc < 0)
+                continue;
+            return i;
         }
     }
 
@@ -339,6 +334,16 @@
     12000, 11025, 8000
 };
 
+uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
+{
+    return fread(buffer, 1, length, (FILE*)user_data);
+}
+
+uint32_t seek_callback(void *user_data, uint64_t position)
+{
+    return fseek((FILE*)user_data, position, SEEK_SET);
+}
+
 int decodeMP4file(char *sndfile, aac_dec_opt *opt)
 {
     int track;
@@ -346,13 +351,14 @@
     unsigned char channels;
     void *sample_buffer;
 
-    MP4FileHandle infile;
-    MP4SampleId sampleId, numSamples;
+    mp4ff_t *infile;
+    FILE *mp4File;
+    int sampleId, numSamples;
 
     audio_file *aufile;
 
-    faacDecHandle hDecoder;
-    faacDecFrameInfo frameInfo;
+    NeAACDecHandle hDecoder;
+    NeAACDecFrameInfo frameInfo;
 
     unsigned char *buffer;
     int buffer_size;
@@ -359,9 +365,15 @@
 
     int first_time = 1;
 
-    hDecoder = faacDecOpen();
+    /* initialise the callback structure */
+    mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t));
 
-    infile = MP4Read(opt->filename, 0);
+    mp4File = fopen(opt->filename, "rb");
+    mp4cb->read = read_callback;
+    mp4cb->seek = seek_callback;
+    mp4cb->user_data = mp4File;
+
+    infile = mp4ff_open_read(mp4cb);
     if (!infile)
     {
         /* unable to open file */
@@ -372,28 +384,34 @@
     if ((track = GetAACTrack(infile)) < 0)
     {
         error_handler("Unable to find correct AAC sound track in the MP4 file.\n");
-        MP4Close(infile);
+        mp4ff_close(infile);
+        free(mp4cb);
+        fclose(mp4File);
         return 1;
     }
 
     buffer = NULL;
     buffer_size = 0;
-    MP4GetTrackESConfiguration(infile, track, &buffer, &buffer_size);
+    mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size);
 
-    if(faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0)
+    hDecoder = NeAACDecOpen();
+
+    if(NeAACDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0)
     {
         /* If some error initializing occured, skip the file */
         error_handler("Error initializing decoder library.\n");
-        faacDecClose(hDecoder);
-        MP4Close(infile);
+        NeAACDecClose(hDecoder);
+        mp4ff_close(infile);
+        free(mp4cb);
+        fclose(mp4File);
         return 1;
     }
     if (buffer)
         free(buffer);
 
-    numSamples = MP4GetTrackNumberOfSamples(infile, track);
+    numSamples = mp4ff_num_samples(infile, track);
 
-    for (sampleId = 1; sampleId <= numSamples; sampleId++)
+    for (sampleId = 0; sampleId < numSamples; sampleId++)
     {
         int rc;
 
@@ -401,16 +419,18 @@
         buffer = NULL;
         buffer_size = 0;
 
-        rc = MP4ReadSample(infile, track, sampleId, &buffer, &buffer_size, NULL, NULL, NULL, NULL);
+        rc = mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size);
         if (rc == 0)
         {
             error_handler("Reading from MP4 file failed.\n");
-            faacDecClose(hDecoder);
-            MP4Close(infile);
+            NeAACDecClose(hDecoder);
+            mp4ff_close(infile);
+            free(mp4cb);
+            fclose(mp4File);
             return 1;
         }
 
-        sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
+        sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
 
         if (buffer)
             free(buffer);
@@ -426,8 +446,10 @@
                                 frameInfo.channels) < 0)
                 {
                     error_handler("\nCan't access %s\n", "WAVE OUT");
-                    faacDecClose(hDecoder);
-                    MP4Close(infile);
+                    NeAACDecClose(hDecoder);
+                    mp4ff_close(infile);
+                    free(mp4cb);
+                    fclose(mp4File);
                     return (0);
                 }
             }
@@ -438,8 +460,10 @@
 
                 if (aufile == NULL)
                 {
-                    faacDecClose(hDecoder);
-                    MP4Close(infile);
+                    NeAACDecClose(hDecoder);
+                    mp4ff_close(infile);
+                    free(mp4cb);
+                    fclose(mp4File);
                     return 0;
                 }
             }
@@ -457,7 +481,7 @@
         if (frameInfo.error > 0)
         {
             error_handler("Error: %s\n",
-            faacDecGetErrorMessage(frameInfo.error));
+            NeAACDecGetErrorMessage(frameInfo.error));
             break;
         }
         if(stop_decoding)
@@ -465,10 +489,12 @@
     }
 
 
-    faacDecClose(hDecoder);
+    NeAACDecClose(hDecoder);
 
 
-    MP4Close(infile);
+    mp4ff_close(infile);
+    free(mp4cb);
+    fclose(mp4File);
 
     if(opt->decode_mode == 0)
         WIN_Audio_close();
@@ -505,24 +531,27 @@
     int mp4file = 0;
     char *fnp;
     char audioFileName[MAX_PATH];
-    MP4FileHandle infile;
+    unsigned char header[8];
+    FILE *hMP4File;
 
 
     /* point to the specified file name */
     strcpy(audioFileName, opt->filename);
-
     fnp = (char *)strrchr(audioFileName,'.');
-
     if (fnp)
         fnp[0] = '\0';
-
     strcat(audioFileName, file_ext[opt->file_type]);
 
-    mp4file = 1;
-    infile = MP4Read(audioFileName, 0);
-    if (!infile)
-        mp4file = 0;
-    if (infile) MP4Close(infile);
+    mp4file = 0;
+    hMP4File = fopen(opt->filename, "rb");
+    if (!hMP4File)
+    {
+        return 1;
+    }
+    fread(header, 1, 8, hMP4File);
+    fclose(hMP4File);
+    if (header[4] == 'f' && header[5] == 't' && header[6] == 'y' && header[7] == 'p')
+        mp4file = 1;
 
     if (mp4file)
     {
--- a/aacDECdrop/main.c
+++ b/aacDECdrop/main.c
@@ -263,7 +263,8 @@
 
 		if (ext = strrchr(szFile, '.'))
 		{
-			if (stricmp(ext, ".aac") == 0 || stricmp(ext, ".mp4") == 0)
+			if (stricmp(ext, ".aac") == 0 || stricmp(ext, ".mp4") == 0 ||
+                stricmp(ext, ".m4a") == 0 || stricmp(ext, ".m4p") == 0)
 			{
 				flag = 1;
 				decthread_addfile(szFile);
--- a/include/faad.h
+++ b/include/faad.h
@@ -22,8 +22,11 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: faad.h,v 1.46 2004/03/10 19:45:40 menno Exp $
+** $Id: faad.h,v 1.47 2004/04/03 19:08:37 menno Exp $
 **/
+
+/* warn people for update */
+#pragma message("please update faad2 include filename and function names!")
 
 /* Backwards compatible link */
 #include "neaacdec.h"
--- a/libfaad/ps_dec.c
+++ b/libfaad/ps_dec.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: ps_dec.c,v 1.4 2004/04/03 10:49:14 menno Exp $
+** $Id: ps_dec.c,v 1.5 2004/04/03 19:08:38 menno Exp $
 **/
 
 #include "common.h"
@@ -123,13 +123,13 @@
      32-27, 33-27, 34-27, 35-27, 36-27, 37-27, 38-27, 40-27, 42-27, 44-27, 46-27, 48-27, 51-27, 54-27, 57-27, 60-27, 64-27, 68-27, 91-27
 };
 
-static const uint16_t map_bins2group20[10+12] =
+static const uint16_t map_group2bk20[10+12] =
 {
     (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0),
     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
 };
 
-static const uint16_t map_bins2group34[32+18] =
+static const uint16_t map_group2bk34[32+18] =
 {
     0,  1,  2,  3,  4,  5,  6,  6,  7, (NEGATE_IPD_MASK | 2), (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0),
     10, 10, 4,  5,  6,  7,  8,  9,
@@ -933,7 +933,7 @@
     uint8_t temp_delay_ser[NO_ALLPASS_LINKS];
     real_t P_SmoothPeakDecayDiffNrg, nrg;
     real_t P[32][34];
-    real_t G_TransientRatio[32][34];
+    real_t G_TransientRatio[32][34] = {{0}};
     complex_t inputLeft;
 
 
@@ -945,6 +945,8 @@
         Phi_Fract_SubQmf = Phi_Fract_SubQmf20;
     }
 
+    /* clear the energy values */
+#if 0
     for (n = 0; n < 32; n++)
     {
         for (bk = 0; bk < 34; bk++)
@@ -952,16 +954,22 @@
             P[n][bk] = 0;
         }
     }
+#endif
 
+    /* calculate the energy in each parameter band b(k) */
     for (gr = 0; gr < ps->num_groups; gr++)
     {
-        bk = (~NEGATE_IPD_MASK) & ps->map_bins2group[gr];
+        /* select the parameter index b(k) to which this group belongs */
+        bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr];
+
+        /* select the upper subband border for this group */
         maxsb = (gr < ps->num_hybrid_groups) ? ps->group_border[gr]+1 : ps->group_border[gr+1];
 
         for (sb = ps->group_border[gr]; sb < maxsb; sb++)
         {
-            for (n = ps->border_position[0] ; n < ps->border_position[ps->num_env] ; n++)
+            for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++)
             {
+                /* input from hybrid subbands or QMF subbands */
                 if (gr < ps->num_hybrid_groups)
                 {
                     RE(inputLeft) = QMF_RE(X_hybrid_left[n][sb]);
@@ -970,11 +978,14 @@
                     RE(inputLeft) = QMF_RE(X_left[n][sb]);
                     IM(inputLeft) = QMF_IM(X_left[n][sb]);
                 }
+
+                /* accumulate energy */
                 P[n][bk] += MUL_R(RE(inputLeft),RE(inputLeft)) + MUL_R(IM(inputLeft),IM(inputLeft));
             }
         }
     }
 
+    /* calculate transient reduction ratio for each parameter band b(k) */
     for (bk = 0; bk < ps->nr_par_bands; bk++)
     {
         for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++)
@@ -985,13 +996,17 @@
             if (ps->P_PeakDecayNrg[bk] < P[n][bk])
                 ps->P_PeakDecayNrg[bk] = P[n][bk];
 
+            /* apply smoothing filter to peak decay energy */
             P_SmoothPeakDecayDiffNrg = ps->P_SmoothPeakDecayDiffNrg_prev[bk];
             P_SmoothPeakDecayDiffNrg += MUL_F((ps->P_PeakDecayNrg[bk] - P[n][bk] - ps->P_SmoothPeakDecayDiffNrg_prev[bk]), ps->alpha_smooth);
             ps->P_SmoothPeakDecayDiffNrg_prev[bk] = P_SmoothPeakDecayDiffNrg;
 
+            /* apply smoothing filter to energy */
             nrg = ps->P_prev[bk];
             nrg += MUL_F((P[n][bk] - ps->P_prev[bk]), ps->alpha_smooth);
             ps->P_prev[bk] = nrg;
+
+            /* calculate transient ratio */
             if (MUL_C(P_SmoothPeakDecayDiffNrg, gamma) <= nrg)
             {
                 G_TransientRatio[n][bk] = REAL_CONST(1.0);
@@ -1001,6 +1016,7 @@
         }
     }
 
+    /* apply stereo decorrelation filter to the signal */
     for (gr = 0; gr < ps->num_groups; gr++)
     {
         if (gr < ps->num_hybrid_groups)
@@ -1040,9 +1056,11 @@
 
                 if (gr < ps->num_hybrid_groups)
                 {
+                    /* hybrid filterbank input */
                     RE(inputLeft) = QMF_RE(X_hybrid_left[n][sb]);
                     IM(inputLeft) = QMF_IM(X_hybrid_left[n][sb]);
                 } else {
+                    /* QMF filterbank input */
                     RE(inputLeft) = QMF_RE(X_left[n][sb]);
                     IM(inputLeft) = QMF_IM(X_left[n][sb]);
                 }
@@ -1051,7 +1069,7 @@
                 {
                     /* delay */
 
-                    /* never SubQMF here */
+                    /* never hybrid subbands here, always QMF subbands */
                     RE(tmp) = RE(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]);
                     IM(tmp) = IM(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]);
                     RE(R0) = RE(tmp);
@@ -1066,6 +1084,7 @@
                     /* fetch parameters */
                     if (gr < ps->num_hybrid_groups)
                     {
+                        /* select data from the hybrid subbands */
                         RE(tmp0) = RE(ps->delay_SubQmf[temp_delay][sb]);
                         IM(tmp0) = IM(ps->delay_SubQmf[temp_delay][sb]);
 
@@ -1075,6 +1094,7 @@
                         RE(Phi_Fract) = RE(Phi_Fract_SubQmf[sb]);
                         IM(Phi_Fract) = IM(Phi_Fract_SubQmf[sb]);
                     } else {
+                        /* select data from the QMF subbands */
                         RE(tmp0) = RE(ps->delay_Qmf[temp_delay][sb]);
                         IM(tmp0) = IM(ps->delay_Qmf[temp_delay][sb]);
 
@@ -1085,7 +1105,7 @@
                         IM(Phi_Fract) = IM(Phi_Fract_Qmf[sb]);
                     }
 
-                    /* delay by fraction */
+                    /* z^(-2) * Phi_Fract[k] */
                     ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Phi_Fract), IM(Phi_Fract));
 
                     RE(R0) = RE(tmp);
@@ -1097,6 +1117,7 @@
                         /* fetch parameters */
                         if (gr < ps->num_hybrid_groups)
                         {
+                            /* select data from the hybrid subbands */
                             RE(tmp0) = RE(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]);
                             IM(tmp0) = IM(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]);
 
@@ -1109,6 +1130,7 @@
                                 IM(Q_Fract_allpass) = IM(Q_Fract_allpass_SubQmf20[sb][m]);
                             }
                         } else {
+                            /* select data from the QMF subbands */
                             RE(tmp0) = RE(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]);
                             IM(tmp0) = IM(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]);
 
@@ -1116,13 +1138,19 @@
                             IM(Q_Fract_allpass) = IM(Q_Fract_allpass_Qmf[sb][m]);
                         }
 
+                        /* delay by a fraction */
+                        /* z^(-d(m)) * Q_Fract_allpass[k,m] */
                         ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Q_Fract_allpass), IM(Q_Fract_allpass));
 
+                        /* -a(m) * g_DecaySlope[k] */
                         RE(tmp) += -MUL_F(g_DecaySlope, MUL_F(filter_a[m], RE(R0)));
                         IM(tmp) += -MUL_F(g_DecaySlope, MUL_F(filter_a[m], IM(R0)));
 
+                        /* -a(m) * g_DecaySlope[k] * Q_Fract_allpass[k,m] * z^(-d(m)) */
                         RE(tmp2) = RE(R0) + MUL_F(g_DecaySlope, MUL_F(filter_a[m], RE(tmp)));
                         IM(tmp2) = IM(R0) + MUL_F(g_DecaySlope, MUL_F(filter_a[m], IM(tmp)));
+
+                        /* store sample */
                         if (gr < ps->num_hybrid_groups)
                         {
                             RE(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]) = RE(tmp2);
@@ -1137,22 +1165,31 @@
                     }
                 }
 
-                bk = (~NEGATE_IPD_MASK) & ps->map_bins2group[gr];
+                /* select b(k) for reading the transient ratio */
+                bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr];
 
                 /* duck if a past transient is found */
+                RE(R0) = MUL_R(G_TransientRatio[n][bk], RE(R0));
+                IM(R0) = MUL_R(G_TransientRatio[n][bk], IM(R0));
+
                 if (gr < ps->num_hybrid_groups)
                 {
-                    QMF_RE(X_hybrid_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], RE(R0));
-                    QMF_IM(X_hybrid_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], IM(R0));
+                    /* hybrid */
+                    QMF_RE(X_hybrid_right[n][sb]) = RE(R0);
+                    QMF_IM(X_hybrid_right[n][sb]) = IM(R0);
                 } else {
-                    QMF_RE(X_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], RE(R0));
-                    QMF_IM(X_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], IM(R0));
+                    /* QMF */
+                    QMF_RE(X_right[n][sb]) = RE(R0);
+                    QMF_IM(X_right[n][sb]) = IM(R0);
                 }
 
                 /* Update delay buffer index */
                 if (++temp_delay >= 2)
+                {
                     temp_delay = 0;
+                }
 
+                /* update delay indices */
                 if (sb > ps->nr_allpass_bands && gr >= ps->num_hybrid_groups)
                 {
                     if (++ps->delay_buf_index_delay[sb] >= ps->delay_D[sb])
@@ -1164,12 +1201,15 @@
                 for (m = 0; m < NO_ALLPASS_LINKS; m++)
                 {
                     if (++temp_delay_ser[m] >= ps->num_sample_delay_ser[m])
+                    {
                         temp_delay_ser[m] = 0;
+                    }
                 }
             }
         }
     }
 
+    /* update delay indices */
     ps->saved_delay = temp_delay;
     for (m = 0; m < NO_ALLPASS_LINKS; m++)
         ps->delay_buf_index_ser[m] = temp_delay_ser[m];
@@ -1184,7 +1224,6 @@
     uint8_t sb, maxsb;
     uint8_t env;
     uint8_t nr_ipdopd_par;
-    real_t scaleL, scaleR;
     complex_t h11, h12, h21, h22;
     complex_t H11, H12, H21, H22;
     complex_t deltaH11, deltaH12, deltaH21, deltaH22;
@@ -1214,7 +1253,7 @@
 
     for (gr = 0; gr < ps->num_groups; gr++)
     {
-        bk = (~NEGATE_IPD_MASK) & ps->map_bins2group[gr];
+        bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr];
 
         /* use one channel per group in the subqmf domain */
         maxsb = (gr < ps->num_hybrid_groups) ? ps->group_border[gr] + 1 : ps->group_border[gr + 1];
@@ -1223,7 +1262,8 @@
         {
             if (ps->icc_mode < 3)
             {
-                /* type 'A' mixing */
+                /* type 'A' mixing as described in 8.6.4.6.2.1 */
+                real_t c_1, c_2;
                 real_t cosa, sina;
                 real_t cosb, sinb;
                 real_t ab1, ab2;
@@ -1230,15 +1270,17 @@
                 real_t ab3, ab4;
 
                 /*
-                scaleR = sqrt(2.0 / (1.0 + pow(10.0, quant_iid[no_iid_steps + iid_index] / 10.0)));
-                scaleL = sqrt(2.0 / (1.0 + pow(10.0, quant_iid[no_iid_steps - iid_index] / 10.0)));
+                c_1 = sqrt(2.0 / (1.0 + pow(10.0, quant_iid[no_iid_steps + iid_index] / 10.0)));
+                c_2 = sqrt(2.0 / (1.0 + pow(10.0, quant_iid[no_iid_steps - iid_index] / 10.0)));
                 alpha = 0.5 * acos(quant_rho[icc_index]);
-                beta = alpha * ( scaleR - scaleL ) / sqrt(2.0);
+                beta = alpha * ( c_1 - c_2 ) / sqrt(2.0);
                 */
 
-                scaleR = sf_iid[no_iid_steps + ps->iid_index[env][bk]];
-                scaleL = sf_iid[no_iid_steps - ps->iid_index[env][bk]];
+                /* calculate the scalefactors c_1 and c_2 from the intensity differences */
+                c_1 = sf_iid[no_iid_steps + ps->iid_index[env][bk]];
+                c_2 = sf_iid[no_iid_steps - ps->iid_index[env][bk]];
 
+                /* calculate alpha and beta using the ICC parameters */
                 cosa = cos_alphas[ps->icc_index[env][bk]];
                 sina = sin_alphas[ps->icc_index[env][bk]];
 
@@ -1268,16 +1310,16 @@
                 ab3 = MUL_C(sinb, cosa);
                 ab4 = MUL_C(cosb, sina);
 
-                /* hxx: COEF */
-                RE(h11) = MUL_C(scaleL, (ab1 - ab2));
-                RE(h12) = MUL_C(scaleR, (ab1 + ab2));
-                RE(h21) = MUL_C(scaleL, (ab3 + ab4));
-                RE(h22) = MUL_C(scaleR, (ab3 - ab4));
+                /* h_xy: COEF */
+                RE(h11) = MUL_C(c_2, (ab1 - ab2));
+                RE(h12) = MUL_C(c_1, (ab1 + ab2));
+                RE(h21) = MUL_C(c_2, (ab3 + ab4));
+                RE(h22) = MUL_C(c_1, (ab3 - ab4));
 
                 //printf("%d %f %f %f %f\n", ps->iid_index[env][bin], scaleR, scaleL, alpha, beta);
 
             } else {
-                /* type 'B' mixing */
+                /* type 'B' mixing as described in 8.6.4.6.2.2 */
                 real_t sina, cosa;
                 real_t cosg, sing;
 
@@ -1337,6 +1379,10 @@
                 RE(h22) = MUL_C(COEF_SQRT2, MUL_C(sina, sing));
             }
 
+            /* calculate phase rotation parameters H_xy */
+            /* note that the imaginary part of these parameters are only calculated when
+               IPD and OPD are enabled
+             */
             if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par))
             {
                 real_t ipd, opd;
@@ -1346,6 +1392,7 @@
                 ipd = (float)( M_PI/4.0f ) * ps->ipd_index[env][bk];
                 opd = (float)( M_PI/4.0f ) * ps->opd_index[env][bk];
 
+                /* ringbuffer index */
                 i = ps->phase_hist;
 
                 /* previous value */
@@ -1366,6 +1413,7 @@
                 RE(tempRight) += RE(ps->opd_prev[bk][i]);
                 IM(tempRight) += IM(ps->opd_prev[bk][i]);
 
+                /* ringbuffer index */
                 if (i == 0)
                 { 
                     i = 2;
@@ -1427,9 +1475,10 @@
                 RE(h22) *= RE(phaseRight);
             }
 
-            /* length of the envelope (in time samples) */
+            /* length of the envelope n_e+1 - n_e (in time samples) */
             L = (real_t)(ps->border_position[env + 1] - ps->border_position[env]);
 
+            /* obtain final H_xy by means of linear interpolation */
             RE(deltaH11) = (RE(h11) - RE(ps->h11_prev[gr])) / L;
             RE(deltaH12) = (RE(h12) - RE(ps->h12_prev[gr])) / L;
             RE(deltaH21) = (RE(h21) - RE(ps->h21_prev[gr])) / L;
@@ -1445,8 +1494,10 @@
             RE(ps->h21_prev[gr]) = RE(h21);
             RE(ps->h22_prev[gr]) = RE(h22);
 
+            /* only calculate imaginary part when needed */
             if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par))
             {
+                /* obtain final H_xy by means of linear interpolation */
                 IM(deltaH11) = (IM(h11) - IM(ps->h11_prev[gr])) / L;
                 IM(deltaH12) = (IM(h12) - IM(ps->h12_prev[gr])) / L;
                 IM(deltaH21) = (IM(h21) - IM(ps->h21_prev[gr])) / L;
@@ -1457,7 +1508,7 @@
                 IM(H21) = IM(ps->h21_prev[gr]);
                 IM(H22) = IM(ps->h22_prev[gr]);
 
-                if ((NEGATE_IPD_MASK & ps->map_bins2group[gr]) != 0)
+                if ((NEGATE_IPD_MASK & ps->map_group2bk[gr]) != 0)
                 {
                     IM(deltaH11) = -IM(deltaH11);
                     IM(deltaH12) = -IM(deltaH12);
@@ -1476,8 +1527,10 @@
                 IM(ps->h22_prev[gr]) = IM(h22);
             }
 
+            /* apply H_xy to the current envelope band of the decorrelated subband */
             for (i = ps->border_position[env]; i < ps->border_position[env + 1]; i++)
             {
+                /* addition finalises the interpolation */
                 RE(H11) += RE(deltaH11);
                 RE(H12) += RE(deltaH12);
                 RE(H21) += RE(deltaH21);
@@ -1495,6 +1548,7 @@
                 {
                     complex_t inLeft, inRight;
 
+                    /* load decorrelated samples */
                     if (gr < ps->num_hybrid_groups)
                     {
                         RE(inLeft) =  RE(X_hybrid_left[i][sb]);
@@ -1508,13 +1562,16 @@
                         IM(inRight) = IM(X_right[i][sb]);
                     }
 
+                    /* apply mixing */
                     RE(tempLeft) =  RE(H11) * RE(inLeft) + RE(H21) * RE(inRight);
                     IM(tempLeft) =  RE(H11) * IM(inLeft) + RE(H21) * IM(inRight);
                     RE(tempRight) = RE(H12) * RE(inLeft) + RE(H22) * RE(inRight);
                     IM(tempRight) = RE(H12) * IM(inLeft) + RE(H22) * IM(inRight);
 
+                    /* only perform imaginary operations when needed */
                     if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par))
                     {
+                        /* apply rotation */
                         RE(tempLeft)  -= IM(H11) * IM(inLeft) + IM(H21) * IM(inRight); 
                         IM(tempLeft)  += IM(H11) * RE(inLeft) + IM(H21) * RE(inRight);
                         RE(tempRight) -= IM(H12) * IM(inLeft) + IM(H22) * IM(inRight);
@@ -1521,6 +1578,7 @@
                         IM(tempRight) += IM(H12) * RE(inLeft) + IM(H22) * RE(inRight);
                     }
 
+                    /* store final samples */
                     if (gr < ps->num_hybrid_groups)
                     {
                         RE(X_hybrid_left[i][sb]) =  RE(tempLeft);
@@ -1643,7 +1701,7 @@
     if (ps->use34hybrid_bands)
     {
         ps->group_border = (uint8_t*)group_border34;
-        ps->map_bins2group = (uint16_t*)map_bins2group34;
+        ps->map_group2bk = (uint16_t*)map_group2bk34;
         ps->num_groups = 32+18;
         ps->num_hybrid_groups = 32;
         ps->nr_par_bands = 34;
@@ -1650,7 +1708,7 @@
         ps->decay_cutoff = 5;
     } else {
         ps->group_border = (uint8_t*)group_border20;
-        ps->map_bins2group = (uint16_t*)map_bins2group20;
+        ps->map_group2bk = (uint16_t*)map_group2bk20;
         ps->num_groups = 10+12;
         ps->num_hybrid_groups = 10;
         ps->nr_par_bands = 20;
--- a/libfaad/ps_dec.h
+++ b/libfaad/ps_dec.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: ps_dec.h,v 1.2 2004/04/03 10:49:14 menno Exp $
+** $Id: ps_dec.h,v 1.3 2004/04/03 19:08:38 menno Exp $
 **/
 
 #ifndef __PS_DEC_H__
@@ -95,7 +95,7 @@
     uint8_t decay_cutoff;
 
     uint8_t *group_border;
-    uint16_t *map_bins2group;
+    uint16_t *map_group2bk;
 
     /* filter delay handling */
     uint8_t saved_delay;