*/
/**
- * @file libavcodec/aacsbr.c
+ * @file
* AAC Spectral Band Replication decoding functions
* @author Robert Swain ( rob opendot cl )
*/
#include "aacsbr.h"
#include "aacsbrdata.h"
#include "fft.h"
+#include "aacps.h"
#include <stdint.h>
#include <float.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 DECLARE_ALIGNED(16, float, analysis_cos_pre)[64];
-static DECLARE_ALIGNED(16, float, analysis_sin_pre)[64];
-static DECLARE_ALIGNED(16, float, analysis_cossin_post)[32][2];
static const DECLARE_ALIGNED(16, float, zero64)[64];
#define SBR_INIT_VLC_STATIC(num, size) \
av_cold void ff_aac_sbr_init(void)
{
- int n, k;
+ int n;
static const struct {
const void *sbr_codes, *sbr_bits;
const unsigned int table_size, elem_size;
SBR_INIT_VLC_STATIC(8, 592);
SBR_INIT_VLC_STATIC(9, 512);
- for (n = 0; n < 64; n++) {
- float pre = M_PI * n / 64;
- analysis_cos_pre[n] = cosf(pre);
- analysis_sin_pre[n] = sinf(pre);
- }
- for (k = 0; k < 32; k++) {
- float post = M_PI * (k + 0.5) / 128;
- analysis_cossin_post[k][0] = 4.0 * cosf(post);
- analysis_cossin_post[k][1] = -4.0 * sinf(post);
- }
for (n = 1; n < 320; n++)
sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n];
sbr_qmf_window_us[384] = -sbr_qmf_window_us[384];
for (n = 0; n < 320; n++)
sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n];
+
+ ff_ps_init();
}
av_cold void ff_aac_sbr_ctx_init(SpectralBandReplication *sbr)
sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
ff_mdct_init(&sbr->mdct, 7, 1, 1.0/64);
- ff_rdft_init(&sbr->rdft, 6, IDFT_R2C);
+ ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0);
+ ff_ps_ctx_init(&sbr->ps);
}
av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr)
{
ff_mdct_end(&sbr->mdct);
- ff_rdft_end(&sbr->rdft);
+ ff_mdct_end(&sbr->mdct_ana);
}
static int qsort_comparison_function_int16(const void *a, const void *b)
1.18509277094158210129f, //2^(0.49/2)
1.11987160404675912501f }; //2^(0.49/3)
const float lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1];
- int16_t patch_borders[5];
+ int16_t patch_borders[7];
uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim;
patch_borders[0] = sbr->kx[1];
bands[num_bands-1] = stop - previous;
}
-static int check_n_master(AVCodecContext *avccontext, int n_master, int bs_xover_band)
+static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band)
{
// Requirements (14496-3 sp04 p205)
if (n_master <= 0) {
- av_log(avccontext, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master);
+ av_log(avctx, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master);
return -1;
}
if (bs_xover_band >= n_master) {
- av_log(avccontext, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"Invalid bitstream, crossover band index beyond array bounds: %d\n",
bs_xover_band);
return -1;
sbr_offset_ptr = sbr_offset[5];
break;
default:
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Unsupported sample rate for SBR: %d\n", sbr->sample_rate);
return -1;
}
} else if (spectrum->bs_stop_freq == 15) {
sbr->k[2] = 3*sbr->k[0];
} else {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq);
return -1;
}
max_qmf_subbands = 32;
if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]);
return -1;
}
if (!spectrum->bs_freq_scale) {
- unsigned int dk;
- int k2diff;
+ int dk, k2diff;
dk = spectrum->bs_alter_scale + 1;
sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1;
- if (check_n_master(ac->avccontext, sbr->n_master, sbr->spectrum_params.bs_xover_band))
+ if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
return -1;
for (k = 1; k <= sbr->n_master; k++)
k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk;
if (k2diff < 0) {
sbr->f_master[1]--;
- sbr->f_master[2]-= (k2diff < 1);
+ sbr->f_master[2]-= (k2diff < -1);
} else if (k2diff) {
sbr->f_master[sbr->n_master]++;
}
num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2;
if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205)
- av_log(ac->avccontext, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);
+ av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);
return -1;
}
vk0[0] = sbr->k[0];
for (k = 1; k <= num_bands_0; k++) {
if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205)
- av_log(ac->avccontext, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]);
+ av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]);
return -1;
}
vk0[k] += vk0[k-1];
vk1[0] = sbr->k[1];
for (k = 1; k <= num_bands_1; k++) {
if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205)
- av_log(ac->avccontext, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]);
+ av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]);
return -1;
}
vk1[k] += vk1[k-1];
}
sbr->n_master = num_bands_0 + num_bands_1;
- if (check_n_master(ac->avccontext, sbr->n_master, sbr->spectrum_params.bs_xover_band))
+ if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
return -1;
memcpy(&sbr->f_master[0], vk0,
(num_bands_0 + 1) * sizeof(sbr->f_master[0]));
} else {
sbr->n_master = num_bands_0;
- if (check_n_master(ac->avccontext, sbr->n_master, sbr->spectrum_params.bs_xover_band))
+ if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
return -1;
memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0]));
}
odd = (sb + sbr->k[0]) & 1;
}
+ // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5.
+ // After this check the final number of patches can still be six which is
+ // illegal however the Coding Technologies decoder check stream has a final
+ // count of 6 patches
+ if (sbr->num_patches > 5) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches);
+ return -1;
+ }
+
sbr->patch_num_subbands[sbr->num_patches] = FFMAX(sb - usb, 0);
sbr->patch_start_subband[sbr->num_patches] = sbr->k[0] - odd - sbr->patch_num_subbands[sbr->num_patches];
if (sbr->patch_num_subbands[sbr->num_patches-1] < 3 && sbr->num_patches > 1)
sbr->num_patches--;
- // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5
- // However the Coding Technologies decoder check uses 6 patches
- if (sbr->num_patches > 6) {
- av_log(ac->avccontext, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches);
- return -1;
- }
-
return 0;
}
// Requirements (14496-3 sp04 p205)
if (sbr->kx[1] + sbr->m[1] > 64) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Stop frequency border too high: %d\n", sbr->kx[1] + sbr->m[1]);
return -1;
}
if (sbr->kx[1] > 32) {
- av_log(ac->avccontext, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]);
+ av_log(ac->avctx, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]);
return -1;
}
sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands *
log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3
if (sbr->n_q > 5) {
- av_log(ac->avccontext, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q);
+ av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q);
return -1;
}
GetBitContext *gb, SBRData *ch_data)
{
int i;
- unsigned bs_pointer;
+ unsigned 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;
switch (ch_data->bs_frame_class = get_bits(gb, 2)) {
case FIXFIX:
- ch_data->bs_num_env = 1 << get_bits(gb, 2);
- num_rel_lead = ch_data->bs_num_env - 1;
+ ch_data->bs_num_env = 1 << get_bits(gb, 2);
+ num_rel_lead = ch_data->bs_num_env - 1;
if (ch_data->bs_num_env == 1)
ch_data->bs_amp_res = 0;
if (ch_data->bs_num_env > 4) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
ch_data->bs_num_env);
return -1;
for (i = 0; i < num_rel_lead; i++)
ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail;
- bs_pointer = 0;
-
ch_data->bs_freq_res[1] = get_bits1(gb);
for (i = 1; i < ch_data->bs_num_env; i++)
ch_data->bs_freq_res[i + 1] = ch_data->bs_freq_res[1];
break;
case FIXVAR:
- abs_bord_trail += get_bits(gb, 2);
- num_rel_trail = get_bits(gb, 2);
- num_rel_lead = 0;
- ch_data->bs_num_env = num_rel_trail + 1;
- ch_data->t_env[0] = 0;
+ abs_bord_trail += get_bits(gb, 2);
+ num_rel_trail = get_bits(gb, 2);
+ ch_data->bs_num_env = num_rel_trail + 1;
+ ch_data->t_env[0] = 0;
ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
for (i = 0; i < num_rel_trail; i++)
- ch_data->t_env[ch_data->bs_num_env - 1 - i] = ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
+ ch_data->t_env[ch_data->bs_num_env - 1 - i] =
+ ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb);
break;
case VARFIX:
- ch_data->t_env[0] = get_bits(gb, 2);
- num_rel_lead = get_bits(gb, 2);
- ch_data->bs_num_env = num_rel_lead + 1;
+ ch_data->t_env[0] = get_bits(gb, 2);
+ num_rel_lead = get_bits(gb, 2);
+ ch_data->bs_num_env = num_rel_lead + 1;
ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
for (i = 0; i < num_rel_lead; i++)
get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
break;
case VARVAR:
- ch_data->t_env[0] = get_bits(gb, 2);
- abs_bord_trail += get_bits(gb, 2);
- num_rel_lead = get_bits(gb, 2);
- num_rel_trail = get_bits(gb, 2);
- ch_data->bs_num_env = num_rel_lead + num_rel_trail + 1;
- ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+ ch_data->t_env[0] = get_bits(gb, 2);
+ abs_bord_trail += get_bits(gb, 2);
+ num_rel_lead = get_bits(gb, 2);
+ num_rel_trail = get_bits(gb, 2);
+ ch_data->bs_num_env = num_rel_lead + num_rel_trail + 1;
if (ch_data->bs_num_env > 5) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n",
ch_data->bs_num_env);
return -1;
}
+ ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+
for (i = 0; i < num_rel_lead; i++)
ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2;
for (i = 0; i < num_rel_trail; i++)
- ch_data->t_env[ch_data->bs_num_env - 1 - i] = ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
+ ch_data->t_env[ch_data->bs_num_env - 1 - i] =
+ ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
}
if (bs_pointer > ch_data->bs_num_env + 1) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ 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);
return -1;
}
+ for (i = 1; i <= ch_data->bs_num_env; i++) {
+ if (ch_data->t_env[i-1] > ch_data->t_env[i]) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Non monotone time borders\n");
+ return -1;
+ }
+ }
+
ch_data->bs_num_noise = (ch_data->bs_num_env > 1) + 1;
- ch_data->t_q[0] = ch_data->t_env[0];
+ 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;
if (ch_data->bs_frame_class == FIXFIX) {
idx = bs_pointer - 1;
}
ch_data->t_q[1] = ch_data->t_env[idx];
- ch_data->t_q[2] = ch_data->t_env[ch_data->bs_num_env];
- } else
- ch_data->t_q[1] = ch_data->t_env[ch_data->bs_num_env];
+ }
ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev
ch_data->e_a[1] = -1;
static void copy_sbr_grid(SBRData *dst, const SBRData *src) {
//These variables are saved from the previous frame rather than copied
- dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env];
+ dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env];
dst->t_env_num_env_old = dst->t_env[dst->bs_num_env];
- dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env);
+ dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env);
//These variables are read from the bitstream and therefore copied
memcpy(dst->bs_freq_res+1, src->bs_freq_res+1, sizeof(dst->bs_freq_res)-sizeof(*dst->bs_freq_res));
memcpy(dst->t_env, src->t_env, sizeof(dst->t_env));
memcpy(dst->t_q, src->t_q, sizeof(dst->t_q));
- dst->bs_num_env = src->bs_num_env;
- dst->bs_amp_res = src->bs_amp_res;
- dst->bs_num_noise = src->bs_num_noise;
- dst->bs_frame_class = src->bs_frame_class;
- dst->e_a[1] = src->e_a[1];
+ dst->bs_num_env = src->bs_num_env;
+ dst->bs_amp_res = src->bs_amp_res;
+ dst->bs_num_noise = src->bs_num_noise;
+ dst->bs_frame_class = src->bs_frame_class;
+ dst->e_a[1] = src->e_a[1];
}
/// Read how the envelope and noise floor data is delta coded
static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
GetBitContext *gb,
- int bs_extension_id, int *num_bits_left)
+ int bs_extension_id, int *num_bits_left)
{
-//TODO - implement ps_data for parametric stereo parsing
switch (bs_extension_id) {
case EXTENSION_ID_PS:
-#if 0
- *num_bits_left -= ff_ps_data(gb, ps);
+ if (!ac->m4ac.ps) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n");
+ 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->avccontext, "Parametric Stereo is", 0);
- skip_bits_long(gb, *num_bits_left); // bs_fill_bits
- *num_bits_left = 0;
+ av_log_missing_feature(ac->avctx, "Parametric Stereo is", 0);
+ skip_bits_long(gb, *num_bits_left); // bs_fill_bits
+ *num_bits_left = 0;
#endif
+ }
break;
default:
- av_log_missing_feature(ac->avccontext, "Reserved SBR extensions are", 1);
+ av_log_missing_feature(ac->avctx, "Reserved SBR extensions are", 1);
skip_bits_long(gb, *num_bits_left); // bs_fill_bits
*num_bits_left = 0;
break;
return get_bits_count(gb) - cnt;
}
} else {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bitstream - cannot apply SBR to element type %d\n", id_aac);
sbr->start = 0;
return get_bits_count(gb) - cnt;
num_bits_left -= 2;
read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id
}
+ if (num_bits_left < 0) {
+ av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over read.\n");
+ }
+ if (num_bits_left > 0)
+ skip_bits(gb, num_bits_left);
}
return get_bits_count(gb) - cnt;
if (err >= 0)
err = sbr_make_f_derived(ac, sbr);
if (err < 0) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"SBR reset failed. Switching SBR to pure upsampling mode.\n");
sbr->start = 0;
}
bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3);
if (bytes_read > cnt) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read);
}
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, RDFTContext *rdft, const float *in, float *x,
+static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct, const float *in, float *x,
float z[320], float W[2][32][32][2],
- float bias, float scale)
+ float scale)
{
int i, k;
memcpy(W[0], W[1], sizeof(W[0]));
memcpy(x , x+1024, (320-32)*sizeof(x[0]));
- if (scale != 1.0f || bias != 0.0f)
- for (i = 0; i < 1024; i++)
- x[288 + i] = (in[i] - bias) * scale;
+ if (scale != 1.0f)
+ dsp->vector_fmul_scalar(x+288, in, scale, 1024);
else
memcpy(x+288, in, 1024*sizeof(*x));
for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
// are not supported
- float re, im;
dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
for (k = 0; k < 64; k++) {
float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
- z[k] = f * analysis_cos_pre[k];
- z[k+64] = f;
+ z[k] = f;
}
- ff_rdft_calc(rdft, z);
- re = z[0] * 0.5f;
- im = 0.5f * dsp->scalarproduct_float(z+64, analysis_sin_pre, 64);
- W[1][i][0][0] = re * analysis_cossin_post[0][0] - im * analysis_cossin_post[0][1];
- W[1][i][0][1] = re * analysis_cossin_post[0][1] + im * analysis_cossin_post[0][0];
+ //Shuffle to IMDCT
+ z[64] = z[0];
for (k = 1; k < 32; k++) {
- re = z[2*k ] - re;
- im = z[2*k+1] - im;
- W[1][i][k][0] = re * analysis_cossin_post[k][0] - im * analysis_cossin_post[k][1];
- W[1][i][k][1] = re * analysis_cossin_post[k][1] + im * analysis_cossin_post[k][0];
+ z[64+2*k-1] = z[ k];
+ z[64+2*k ] = -z[64-k];
+ }
+ z[64+63] = z[32];
+
+ ff_imdct_half(mdct, z, z+64);
+ for (k = 0; k < 32; k++) {
+ W[1][i][k][0] = -z[63-k];
+ W[1][i][k][1] = z[k];
}
x += 32;
}
* (14496-3 sp04 p206)
*/
static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
- float *out, float X[2][32][64],
+ float *out, float X[2][38][64],
float mdct_buf[2][64],
float *v0, int *v_off, const unsigned int div,
float bias, float scale)
*v_off -= 128 >> div;
}
v = v0 + *v_off;
- for (n = 1; n < 64 >> div; n+=2) {
- X[1][i][n] = -X[1][i][n];
- }
- if (div) {
- memset(X[0][i]+32, 0, 32*sizeof(float));
- memset(X[1][i]+32, 0, 32*sizeof(float));
- }
- ff_imdct_half(mdct, mdct_buf[0], X[0][i]);
- ff_imdct_half(mdct, mdct_buf[1], X[1][i]);
if (div) {
for (n = 0; n < 32; n++) {
- v[ n] = -mdct_buf[0][63 - 2*n] + mdct_buf[1][2*n ];
- v[ 63 - n] = mdct_buf[0][62 - 2*n] + mdct_buf[1][2*n + 1];
+ X[0][i][ n] = -X[0][i][n];
+ X[0][i][32+n] = X[1][i][31-n];
+ }
+ ff_imdct_half(mdct, mdct_buf[0], X[0][i]);
+ for (n = 0; n < 32; n++) {
+ v[ n] = mdct_buf[0][63 - 2*n];
+ v[63 - n] = -mdct_buf[0][62 - 2*n];
}
} else {
+ for (n = 1; n < 64; n+=2) {
+ X[1][i][n] = -X[1][i][n];
+ }
+ ff_imdct_half(mdct, mdct_buf[0], X[0][i]);
+ ff_imdct_half(mdct, mdct_buf[1], X[1][i]);
for (n = 0; n < 64; n++) {
v[ n] = -mdct_buf[0][63 - n] + mdct_buf[1][ n ];
v[127 - n] = mdct_buf[0][63 - n] + mdct_buf[1][ n ];
g--;
if (g < 0) {
- av_log(ac->avccontext, AV_LOG_ERROR,
+ av_log(ac->avctx, AV_LOG_ERROR,
"ERROR : no subband found for frequency %d\n", k);
return -1;
}
}
/// Generate the subband filtered lowband
-static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][32][64],
+static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
const float X_low[32][40][2], const float Y[2][38][64][2],
int ch)
{
}
for (k = 0; k < sbr->kx[1]; k++) {
- for (i = i_Temp; i < i_f; i++) {
+ for (i = i_Temp; i < 38; i++) {
X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0];
X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1];
}
sum[1] += sbr->e_curr[e][m];
}
gain_max = limgain[sbr->bs_limiter_gains] * sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1]));
- gain_max = FFMIN(100000, gain_max);
+ gain_max = FFMIN(100000.f, gain_max);
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
float q_m_max = sbr->q_m[e][m] * gain_max / sbr->gain[e][m];
sbr->q_m[e][m] = FFMIN(sbr->q_m[e][m], q_m_max);
+ (delta && !sbr->s_m[e][m]) * sbr->q_m[e][m] * sbr->q_m[e][m];
}
gain_boost = sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1]));
- gain_boost = FFMIN(1.584893192, gain_boost);
+ gain_boost = FFMIN(1.584893192f, gain_boost);
for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
sbr->gain[e][m] *= gain_boost;
sbr->q_m[e][m] *= gain_boost;
ch_data->f_indexsine = indexsine;
}
-void ff_sbr_dequant(AACContext *ac, SpectralBandReplication *sbr, int id_aac)
+void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
+ float* L, float* R)
{
+ int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate;
+ int ch;
+ int nch = (id_aac == TYPE_CPE) ? 2 : 1;
+
if (sbr->start) {
sbr_dequant(sbr, id_aac);
}
-}
+ for (ch = 0; ch < nch; ch++) {
+ /* decode channel */
+ sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+ (float*)sbr->qmf_filter_scratch,
+ sbr->data[ch].W, 1/(-1024 * ac->sf_scale));
+ sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W);
+ if (sbr->start) {
+ sbr_hf_inverse_filter(sbr->alpha0, sbr->alpha1, 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->data[ch].bw_array, sbr->data[ch].t_env,
+ sbr->data[ch].bs_num_env);
+
+ // hf_adj
+ sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
+ 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->X_high, sbr, &sbr->data[ch],
+ sbr->data[ch].e_a);
+ }
-void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int ch,
- const float* in, float* out)
-{
- int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate;
+ /* synthesis */
+ sbr_x_gen(sbr, sbr->X[ch], sbr->X_low, sbr->data[ch].Y, ch);
+ }
- /* decode channel */
- sbr_qmf_analysis(&ac->dsp, &sbr->rdft, in, sbr->data[ch].analysis_filterbank_samples,
- (float*)sbr->qmf_filter_scratch,
- sbr->data[ch].W, ac->add_bias, 1/(-1024 * ac->sf_scale));
- sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W);
- if (sbr->start) {
- sbr_hf_inverse_filter(sbr->alpha0, sbr->alpha1, 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->data[ch].bw_array, sbr->data[ch].t_env,
- sbr->data[ch].bs_num_env);
-
- // hf_adj
- sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
- 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->X_high, sbr, &sbr->data[ch],
- sbr->data[ch].e_a);
+ if (ac->m4ac.ps == 1) {
+ if (sbr->ps.start) {
+ ff_ps_apply(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]);
+ } else {
+ memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0]));
+ }
+ nch = 2;
}
- /* synthesis */
- sbr_x_gen(sbr, sbr->X, sbr->X_low, sbr->data[ch].Y, ch);
- sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, out, sbr->X, sbr->qmf_filter_scratch,
- sbr->data[ch].synthesis_filterbank_samples,
- &sbr->data[ch].synthesis_filterbank_samples_offset,
+ sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, L, sbr->X[0], sbr->qmf_filter_scratch,
+ sbr->data[0].synthesis_filterbank_samples,
+ &sbr->data[0].synthesis_filterbank_samples_offset,
downsampled,
ac->add_bias, -1024 * ac->sf_scale);
+ if (nch == 2)
+ sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, R, sbr->X[1], sbr->qmf_filter_scratch,
+ sbr->data[1].synthesis_filterbank_samples,
+ &sbr->data[1].synthesis_filterbank_samples_offset,
+ downsampled,
+ ac->add_bias, -1024 * ac->sf_scale);
}