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 Mpeg4AAClicense@nero.com.
**
-** $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 Mpeg4AAClicense@nero.com.
**
-** $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 Mpeg4AAClicense@nero.com.
**
-** $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;