#include "fft.h"
#include "aacps.h"
#include "sbrdsp.h"
+#include "libavutil/internal.h"
#include "libavutil/libm.h"
#include <stdint.h>
static VLC vlc_sbr[10];
static const int8_t vlc_sbr_lav[10] =
{ 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 };
-static const DECLARE_ALIGNED(16, float, zero64)[64];
#define SBR_INIT_VLC_STATIC(num, size) \
INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \
/** Places SBR in pure upsampling mode. */
static void sbr_turnoff(SpectralBandReplication *sbr) {
sbr->start = 0;
- // Init defults used in pure upsampling mode
+ // Init defaults used in pure upsampling mode
sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
sbr->m[1] = 0;
// Reset values for first SBR header
static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
SpectrumParameters *spectrum)
{
- unsigned int temp, max_qmf_subbands;
+ unsigned int temp, max_qmf_subbands = 0;
unsigned int start_min, stop_min;
int k;
const int8_t *sbr_offset_ptr;
int16_t stop_dk[13];
- if (sbr->sample_rate < 32000) {
- temp = 3000;
- } else if (sbr->sample_rate < 64000) {
- temp = 4000;
- } else
- temp = 5000;
-
- start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
- stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
-
switch (sbr->sample_rate) {
case 16000:
sbr_offset_ptr = sbr_offset[0];
return -1;
}
+ if (sbr->sample_rate < 32000) {
+ temp = 3000;
+ } else if (sbr->sample_rate < 64000) {
+ temp = 4000;
+ } else
+ temp = 5000;
+
+ start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
+ stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
+
sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq];
if (spectrum->bs_stop_freq < 14) {
k = sbr->n_master;
} while (sb != sbr->kx[1] + sbr->m[1]);
- if (sbr->patch_num_subbands[sbr->num_patches-1] < 3 && sbr->num_patches > 1)
+ if (sbr->num_patches > 1 &&
+ sbr->patch_num_subbands[sbr->num_patches - 1] < 3)
sbr->num_patches--;
return 0;
GetBitContext *gb, SBRData *ch_data)
{
int i;
- unsigned bs_pointer = 0;
+ int bs_pointer = 0;
// frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots
int abs_bord_trail = 16;
int num_rel_lead, num_rel_trail;
break;
}
- if (bs_pointer > ch_data->bs_num_env + 1) {
+ if (bs_pointer < 0 || bs_pointer > ch_data->bs_num_env + 1) {
av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bitstream, bs_pointer points to a middle noise border outside the time borders table: %d\n",
bs_pointer);
ch_data->t_q[0] = ch_data->t_env[0];
ch_data->t_q[ch_data->bs_num_noise] = ch_data->t_env[ch_data->bs_num_env];
if (ch_data->bs_num_noise > 1) {
- unsigned int idx;
+ int idx;
if (ch_data->bs_frame_class == FIXFIX) {
idx = ch_data->bs_num_env >> 1;
} else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
skip_bits_long(gb, *num_bits_left); // bs_fill_bits
*num_bits_left = 0;
} else {
-#if 1
*num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left);
-#else
- av_log_missing_feature(ac->avctx, "Parametric Stereo", 0);
- skip_bits_long(gb, *num_bits_left); // bs_fill_bits
- *num_bits_left = 0;
-#endif
+ ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
}
break;
default:
- av_log_missing_feature(ac->avctx, "Reserved SBR extensions", 1);
+ // some files contain 0-padding
+ if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left))
+ avpriv_request_sample(ac->avctx, "Reserved SBR extensions");
skip_bits_long(gb, *num_bits_left); // bs_fill_bits
*num_bits_left = 0;
break;
if (bytes_read > cnt) {
av_log(ac->avctx, AV_LOG_ERROR,
"Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read);
+ sbr_turnoff(sbr);
}
return cnt;
}
* @param x pointer to the beginning of the first sample window
* @param W array of complex-valued samples split into subbands
*/
-static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
+static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
SBRDSPContext *sbrdsp, const float *in, float *x,
- float z[320], float W[2][32][32][2])
+ float z[320], float W[2][32][32][2], int buf_idx)
{
int i;
- memcpy(W[0], W[1], sizeof(W[0]));
memcpy(x , x+1024, (320-32)*sizeof(x[0]));
memcpy(x+288, in, 1024*sizeof(x[0]));
for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
sbrdsp->sum64x5(z);
sbrdsp->qmf_pre_shuffle(z);
mdct->imdct_half(mdct, z, z+64);
- sbrdsp->qmf_post_shuffle(W[1][i], z);
+ sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
x += 32;
}
}
* Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
* (14496-3 sp04 p206)
*/
-static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
- SBRDSPContext *sbrdsp,
+static void sbr_qmf_synthesis(FFTContext *mdct,
+ SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
float *out, float X[2][38][64],
float mdct_buf[2][64],
float *v0, int *v_off, const unsigned int div)
mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
}
- dsp->vector_fmul_add(out, v , sbr_qmf_window , zero64, 64 >> div);
+ dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div);
dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div);
dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div);
dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div);
/// Generate the subband filtered lowband
static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
- float X_low[32][40][2], const float W[2][32][32][2])
+ float X_low[32][40][2], const float W[2][32][32][2],
+ int buf_idx)
{
int i, k;
const int t_HFGen = 8;
memset(X_low, 0, 32*sizeof(*X_low));
for (k = 0; k < sbr->kx[1]; k++) {
for (i = t_HFGen; i < i_f + t_HFGen; i++) {
- X_low[k][i][0] = W[1][i - t_HFGen][k][0];
- X_low[k][i][1] = W[1][i - t_HFGen][k][1];
+ X_low[k][i][0] = W[buf_idx][i - t_HFGen][k][0];
+ X_low[k][i][1] = W[buf_idx][i - t_HFGen][k][1];
}
}
+ buf_idx = 1-buf_idx;
for (k = 0; k < sbr->kx[0]; k++) {
for (i = 0; i < t_HFGen; i++) {
- X_low[k][i][0] = W[0][i + i_f - t_HFGen][k][0];
- X_low[k][i][1] = W[0][i + i_f - t_HFGen][k][1];
+ X_low[k][i][0] = W[buf_idx][i + i_f - t_HFGen][k][0];
+ X_low[k][i][1] = W[buf_idx][i + i_f - t_HFGen][k][1];
}
}
return 0;
memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0]));
}
} else if (h_SL) {
- memcpy(g_temp[2*ch_data->t_env[0]], g_temp[2*ch_data->t_env_num_env_old], 4*sizeof(g_temp[0]));
- memcpy(q_temp[2*ch_data->t_env[0]], q_temp[2*ch_data->t_env_num_env_old], 4*sizeof(q_temp[0]));
+ for (i = 0; i < 4; i++) {
+ memcpy(g_temp[i + 2 * ch_data->t_env[0]],
+ g_temp[i + 2 * ch_data->t_env_num_env_old],
+ sizeof(g_temp[0]));
+ memcpy(q_temp[i + 2 * ch_data->t_env[0]],
+ q_temp[i + 2 * ch_data->t_env_num_env_old],
+ sizeof(q_temp[0]));
+ }
}
for (e = 0; e < ch_data->bs_num_env; e++) {
}
for (ch = 0; ch < nch; ch++) {
/* decode channel */
- sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+ sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
(float*)sbr->qmf_filter_scratch,
- sbr->data[ch].W);
- sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W);
+ sbr->data[ch].W, sbr->data[ch].Ypos);
+ sbr_lf_gen(ac, sbr, sbr->X_low,
+ (const float (*)[32][32][2]) sbr->data[ch].W,
+ sbr->data[ch].Ypos);
sbr->data[ch].Ypos ^= 1;
if (sbr->start) {
- sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
+ sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
+ (const float (*)[40][2]) sbr->X_low, sbr->k[0]);
sbr_chirp(sbr, &sbr->data[ch]);
- sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1,
+ sbr_hf_gen(ac, sbr, sbr->X_high,
+ (const float (*)[40][2]) sbr->X_low,
+ (const float (*)[2]) sbr->alpha0,
+ (const float (*)[2]) sbr->alpha1,
sbr->data[ch].bw_array, sbr->data[ch].t_env,
sbr->data[ch].bs_num_env);
sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
- sbr->X_high, sbr, &sbr->data[ch],
+ (const float (*)[40][2]) sbr->X_high,
+ sbr, &sbr->data[ch],
sbr->data[ch].e_a);
}
}
/* synthesis */
sbr_x_gen(sbr, sbr->X[ch],
- sbr->data[ch].Y[1-sbr->data[ch].Ypos],
- sbr->data[ch].Y[ sbr->data[ch].Ypos],
- sbr->X_low, ch);
+ (const float (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
+ (const float (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos],
+ (const float (*)[40][2]) sbr->X_low, ch);
}
if (ac->oc[1].m4ac.ps == 1) {
nch = 2;
}
- sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, L, sbr->X[0], sbr->qmf_filter_scratch,
+ sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+ L, sbr->X[0], sbr->qmf_filter_scratch,
sbr->data[0].synthesis_filterbank_samples,
&sbr->data[0].synthesis_filterbank_samples_offset,
downsampled);
if (nch == 2)
- sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, R, sbr->X[1], sbr->qmf_filter_scratch,
+ sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+ R, sbr->X[1], sbr->qmf_filter_scratch,
sbr->data[1].synthesis_filterbank_samples,
&sbr->data[1].synthesis_filterbank_samples_offset,
downsampled);