summaryrefslogtreecommitdiffstats
path: root/libfaad2/sbr_dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libfaad2/sbr_dec.c')
-rw-r--r--libfaad2/sbr_dec.c164
1 files changed, 101 insertions, 63 deletions
diff --git a/libfaad2/sbr_dec.c b/libfaad2/sbr_dec.c
index 3bab4a8d01..ed1e28dd5b 100644
--- a/libfaad2/sbr_dec.c
+++ b/libfaad2/sbr_dec.c
@@ -22,39 +22,9 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dec.c,v 1.5 2003/07/29 08:20:13 menno Exp $
+** $Id: sbr_dec.c,v 1.12 2003/09/25 12:04:31 menno Exp $
**/
-/*
- SBR Decoder overview:
-
- To achieve a synchronized output signal, the following steps have to be
- acknowledged in the decoder:
- - The bitstream parser divides the bitstream into two parts; the AAC
- core coder part and the SBR part.
- - The SBR bitstream part is fed to the bitstream de-multiplexer followed
- by de-quantization The raw data is Huffman decoded.
- - The AAC bitstream part is fed to the AAC core decoder, where the
- bitstream data of the current frame is decoded, yielding a time domain
- audio signal block of 1024 samples. The block length could easily be
- adapted to other sizes e.g. 960.
- - The core coder audio block is fed to the analysis QMF bank using a
- delay of 1312 samples.
- - The analysis QMF bank performs the filtering of the delayed core coder
- audio signal. The output from the filtering is stored in the matrix
- Xlow. The output from the analysis QMF bank is delayed tHFGen subband
- samples, before being fed to the synthesis QMF bank. To achieve
- synchronization tHFGen = 32, i.e. the value must equal the number of
- subband samples corresponding to one frame.
- - The HF generator calculates XHigh given the matrix XLow. The process
- is guided by the SBR data contained in the current frame.
- - The envelope adjuster calculates the matrix Y given the matrix XHigh
- and the SBR envelope data, extracted from the SBR bitstream. To
- achieve synchronization, tHFAdj has to be set to tHFAdj = 0, i.e. the
- envelope adjuster operates on data delayed tHFGen subband samples.
- - The synthesis QMF bank operates on the delayed output from the analysis
- QMF bank and the output from the envelope adjuster.
- */
#include "common.h"
#include "structs.h"
@@ -71,7 +41,11 @@
#include "sbr_hfadj.h"
-sbr_info *sbrDecodeInit()
+sbr_info *sbrDecodeInit(uint16_t framelength
+#ifdef DRM
+ , uint8_t IsDRM
+#endif
+ )
{
sbr_info *sbr = malloc(sizeof(sbr_info));
memset(sbr, 0, sizeof(sbr_info));
@@ -90,6 +64,36 @@ sbr_info *sbrDecodeInit()
sbr->prevEnvIsShort[1] = -1;
sbr->header_count = 0;
+#ifdef DRM
+ sbr->Is_DRM_SBR = 0;
+ if (IsDRM)
+ {
+ sbr->Is_DRM_SBR = 1;
+ sbr->tHFGen = T_HFGEN_DRM;
+ sbr->tHFAdj = T_HFADJ_DRM;
+
+ /* "offset" is different in DRM */
+ sbr->bs_samplerate_mode = 0;
+ } else
+#endif
+ {
+ sbr->bs_samplerate_mode = 1;
+ sbr->tHFGen = T_HFGEN;
+ sbr->tHFAdj = T_HFADJ;
+ }
+
+ /* force sbr reset */
+ sbr->bs_start_freq_prev = -1;
+
+ if (framelength == 960)
+ {
+ sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS_960;
+ sbr->numTimeSlots = NO_TIME_SLOTS_960;
+ } else {
+ sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS;
+ sbr->numTimeSlots = NO_TIME_SLOTS;
+ }
+
return sbr;
}
@@ -152,10 +156,9 @@ void sbr_save_prev_data(sbr_info *sbr, uint8_t ch)
sbr->prevEnvIsShort[ch] = -1;
}
-
void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
real_t *right_channel, uint8_t id_aac,
- uint8_t just_seeked)
+ uint8_t just_seeked, uint8_t upsample_only)
{
int16_t i, k, l;
@@ -168,34 +171,47 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
real_t deg[64];
#endif
- bitfile *ld = (bitfile*)malloc(sizeof(bitfile));
-
+ bitfile *ld = NULL;
sbr->id_aac = id_aac;
channels = (id_aac == ID_SCE) ? 1 : 2;
+ if (sbr->data == NULL || sbr->data_size == 0)
+ {
+ ret = 1;
+ } else {
+ ld = (bitfile*)malloc(sizeof(bitfile));
+
/* initialise and read the bitstream */
faad_initbits(ld, sbr->data, sbr->data_size);
ret = sbr_extension_data(ld, sbr, id_aac);
- if (sbr->data) free(sbr->data);
- sbr->data = NULL;
-
ret = ld->error ? ld->error : ret;
faad_endbits(ld);
if (ld) free(ld);
ld = NULL;
+ }
+
+ if (sbr->data) free(sbr->data);
+ sbr->data = NULL;
+
if (ret || (sbr->header_count == 0))
{
/* don't process just upsample */
dont_process = 1;
+
+ /* Re-activate reset for next frame */
+ if (ret && sbr->Reset)
+ sbr->bs_start_freq_prev = -1;
}
if (just_seeked)
+ {
sbr->just_seeked = 1;
- else
+ } else {
sbr->just_seeked = 0;
+ }
for (ch = 0; ch < channels; ch++)
{
@@ -211,11 +227,11 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
sbr->Q_temp_prev[ch][j] = malloc(64*sizeof(real_t));
}
- sbr->Xsbr[ch] = malloc((32+tHFGen)*64 * sizeof(qmf_t));
- sbr->Xcodec[ch] = malloc((32+tHFGen)*32 * sizeof(qmf_t));
+ sbr->Xsbr[ch] = malloc((sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t));
+ sbr->Xcodec[ch] = malloc((sbr->numTimeSlotsRate+sbr->tHFGen)*32 * sizeof(qmf_t));
- memset(sbr->Xsbr[ch], 0, (32+tHFGen)*64 * sizeof(qmf_t));
- memset(sbr->Xcodec[ch], 0, (32+tHFGen)*32 * sizeof(qmf_t));
+ memset(sbr->Xsbr[ch], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t));
+ memset(sbr->Xcodec[ch], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*32 * sizeof(qmf_t));
}
if (ch == 0)
@@ -223,7 +239,8 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
else
ch_buf = right_channel;
- for (i = 0; i < tHFAdj; i++)
+#if 0
+ for (i = 0; i < sbr->tHFAdj; i++)
{
int8_t j;
for (j = sbr->kx_prev; j < sbr->kx; j++)
@@ -234,9 +251,13 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
#endif
}
}
+#endif
/* subband analysis */
- sbr_qmf_analysis_32(sbr->qmfa[ch], ch_buf, sbr->Xcodec[ch], tHFGen);
+ if (dont_process)
+ sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], ch_buf, sbr->Xcodec[ch], sbr->tHFGen, 32);
+ else
+ sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], ch_buf, sbr->Xcodec[ch], sbr->tHFGen, sbr->kx);
if (!dont_process)
{
@@ -253,28 +274,30 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
{
for (k = 0; k < sbr->kx; k++)
{
- QMF_RE(sbr->Xsbr[ch][(tHFAdj + l)*64 + k]) = 0;
+ QMF_RE(sbr->Xsbr[ch][(sbr->tHFAdj + l)*64 + k]) = 0;
}
}
#endif
+#if 1
/* hf adjustment */
hf_adjustment(sbr, sbr->Xsbr[ch]
#ifdef SBR_LOW_POWER
,deg
#endif
,ch);
+#endif
}
if ((sbr->just_seeked != 0) || dont_process)
{
- for (l = 0; l < 32; l++)
+ for (l = 0; l < sbr->numTimeSlotsRate; l++)
{
for (k = 0; k < 32; k++)
{
- QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
+ QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
#ifndef SBR_LOW_POWER
- QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
+ QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
#endif
}
for (k = 32; k < 64; k++)
@@ -286,7 +309,7 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
}
}
} else {
- for (l = 0; l < 32; l++)
+ for (l = 0; l < sbr->numTimeSlotsRate; l++)
{
uint8_t xover_band;
@@ -295,48 +318,63 @@ void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
else
xover_band = sbr->kx;
+#ifdef DRM
+ if (sbr->Is_DRM_SBR)
+ xover_band = sbr->kx;
+#endif
+
for (k = 0; k < xover_band; k++)
{
- QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
+ QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
#ifndef SBR_LOW_POWER
- QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
+ QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
#endif
}
for (k = xover_band; k < 64; k++)
{
- QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xsbr[ch][(l + tHFAdj)*64 + k]);
+ QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xsbr[ch][(l + sbr->tHFAdj)*64 + k]);
#ifndef SBR_LOW_POWER
- QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xsbr[ch][(l + tHFAdj)*64 + k]);
+ QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xsbr[ch][(l + sbr->tHFAdj)*64 + k]);
#endif
}
#ifdef SBR_LOW_POWER
- QMF_RE(X[l * 64 + xover_band - 1]) += QMF_RE(sbr->Xsbr[ch][(l + tHFAdj)*64 + xover_band - 1]);
+ QMF_RE(X[l * 64 + xover_band - 1]) += QMF_RE(sbr->Xsbr[ch][(l + sbr->tHFAdj)*64 + xover_band - 1]);
+#endif
+#ifdef DRM
+ if (sbr->Is_DRM_SBR)
+ {
+ for (k = xover_band; k < xover_band + 4; k++)
+ {
+ QMF_RE(X[l * 64 + k]) += QMF_RE(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+ QMF_IM(X[l * 64 + k]) += QMF_IM(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+ }
+ }
#endif
}
}
/* subband synthesis */
- sbr_qmf_synthesis_64(sbr->qmfs[ch], (const complex_t*)X, ch_buf);
+ sbr_qmf_synthesis_64(sbr, sbr->qmfs[ch], (const complex_t*)X, ch_buf);
for (i = 0; i < 32; i++)
{
int8_t j;
- for (j = 0; j < tHFGen; j++)
+ for (j = 0; j < sbr->tHFGen; j++)
{
- QMF_RE(sbr->Xcodec[ch][j*32 + i]) = QMF_RE(sbr->Xcodec[ch][(j+32)*32 + i]);
+ QMF_RE(sbr->Xcodec[ch][j*32 + i]) = QMF_RE(sbr->Xcodec[ch][(j+sbr->numTimeSlotsRate)*32 + i]);
#ifndef SBR_LOW_POWER
- QMF_IM(sbr->Xcodec[ch][j*32 + i]) = QMF_IM(sbr->Xcodec[ch][(j+32)*32 + i]);
+ QMF_IM(sbr->Xcodec[ch][j*32 + i]) = QMF_IM(sbr->Xcodec[ch][(j+sbr->numTimeSlotsRate)*32 + i]);
#endif
}
}
for (i = 0; i < 64; i++)
{
int8_t j;
- for (j = 0; j < tHFGen; j++)
+ for (j = 0; j < sbr->tHFGen; j++)
{
- QMF_RE(sbr->Xsbr[ch][j*64 + i]) = QMF_RE(sbr->Xsbr[ch][(j+32)*64 + i]);
+ QMF_RE(sbr->Xsbr[ch][j*64 + i]) = QMF_RE(sbr->Xsbr[ch][(j+sbr->numTimeSlotsRate)*64 + i]);
#ifndef SBR_LOW_POWER
- QMF_IM(sbr->Xsbr[ch][j*64 + i]) = QMF_IM(sbr->Xsbr[ch][(j+32)*64 + i]);
+ QMF_IM(sbr->Xsbr[ch][j*64 + i]) = QMF_IM(sbr->Xsbr[ch][(j+sbr->numTimeSlotsRate)*64 + i]);
#endif
}
}