*/
/**
- * @file libavcodec/aacsbr.c
+ * @file
* AAC Spectral Band Replication decoding functions
* @author Robert Swain ( rob opendot cl )
*/
#include "sbr.h"
#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->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
+ sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1;
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 = 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;
+ unsigned bs_num_env_old = ch_data->bs_num_env;
- ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env[1]];
- ch_data->bs_num_env[0] = ch_data->bs_num_env[1];
+ ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env];
ch_data->bs_amp_res = sbr->bs_amp_res_header;
+ ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old];
switch (ch_data->bs_frame_class = get_bits(gb, 2)) {
case FIXFIX:
- ch_data->bs_num_env[1] = 1 << get_bits(gb, 2);
- if (ch_data->bs_num_env[1] == 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->avctx, AV_LOG_ERROR,
+ "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
+ ch_data->bs_num_env);
+ return -1;
+ }
+
+ ch_data->t_env[0] = 0;
+ ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+
+ abs_bord_trail = (abs_bord_trail + (ch_data->bs_num_env >> 1)) /
+ ch_data->bs_num_env;
+ for (i = 0; i < num_rel_lead; i++)
+ ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail;
+
ch_data->bs_freq_res[1] = get_bits1(gb);
- for (i = 1; i < ch_data->bs_num_env[1]; i++)
+ 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:
- ch_data->bs_var_bord[1] = get_bits(gb, 2);
- ch_data->bs_num_rel[1] = get_bits(gb, 2);
- ch_data->bs_num_env[1] = ch_data->bs_num_rel[1] + 1;
+ 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 < ch_data->bs_num_rel[1]; i++)
- ch_data->bs_rel_bord[1][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->bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env[1]]);
+ bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
- for (i = 0; i < ch_data->bs_num_env[1]; i++)
- ch_data->bs_freq_res[ch_data->bs_num_env[1] - i] = get_bits1(gb);
+ for (i = 0; i < ch_data->bs_num_env; i++)
+ ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb);
break;
case VARFIX:
- ch_data->bs_var_bord[0] = get_bits(gb, 2);
- ch_data->bs_num_rel[0] = get_bits(gb, 2);
- ch_data->bs_num_env[1] = ch_data->bs_num_rel[0] + 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 < ch_data->bs_num_rel[0]; i++)
- ch_data->bs_rel_bord[0][i] = 2 * get_bits(gb, 2) + 2;
+ 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;
- ch_data->bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env[1]]);
+ bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
- get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env[1]);
+ get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
break;
case VARVAR:
- ch_data->bs_var_bord[0] = get_bits(gb, 2);
- ch_data->bs_var_bord[1] = get_bits(gb, 2);
- ch_data->bs_num_rel[0] = get_bits(gb, 2);
- ch_data->bs_num_rel[1] = get_bits(gb, 2);
- ch_data->bs_num_env[1] = ch_data->bs_num_rel[0] + ch_data->bs_num_rel[1] + 1;
+ 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->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 < ch_data->bs_num_rel[0]; i++)
- ch_data->bs_rel_bord[0][i] = 2 * get_bits(gb, 2) + 2;
- for (i = 0; i < ch_data->bs_num_rel[1]; i++)
- ch_data->bs_rel_bord[1][i] = 2 * get_bits(gb, 2) + 2;
+ 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->bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env[1]]);
+ bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
- get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env[1]);
+ get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
break;
}
- if (ch_data->bs_frame_class == FIXFIX && ch_data->bs_num_env[1] > 4) {
- av_log(ac->avccontext, AV_LOG_ERROR,
- "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
- ch_data->bs_num_env[1]);
+ if (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);
return -1;
}
- if (ch_data->bs_frame_class == VARVAR && ch_data->bs_num_env[1] > 5) {
- av_log(ac->avccontext, AV_LOG_ERROR,
- "Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n",
- ch_data->bs_num_env[1]);
- 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) + 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[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 = ch_data->bs_num_env >> 1;
+ } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
+ idx = ch_data->bs_num_env - FFMAX(bs_pointer - 1, 1);
+ } else { // VARFIX
+ if (!bs_pointer)
+ idx = 1;
+ else if (bs_pointer == 1)
+ idx = ch_data->bs_num_env - 1;
+ else // bs_pointer > 1
+ idx = bs_pointer - 1;
+ }
+ ch_data->t_q[1] = ch_data->t_env[idx];
+ }
+
+ ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev
+ ch_data->e_a[1] = -1;
+ if ((ch_data->bs_frame_class & 1) && bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0
+ ch_data->e_a[1] = ch_data->bs_num_env + 1 - bs_pointer;
+ } else if ((ch_data->bs_frame_class == 2) && (bs_pointer > 1)) // VARFIX and bs_pointer > 1
+ ch_data->e_a[1] = bs_pointer - 1;
return 0;
}
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[1]];
- dst->bs_num_env[0] = dst->bs_num_env[1];
+ 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);
//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->bs_num_env+1, src->bs_num_env+1, sizeof(dst->bs_num_env)- sizeof(*dst->bs_num_env));
- memcpy(dst->bs_var_bord, src->bs_var_bord, sizeof(dst->bs_var_bord));
- memcpy(dst->bs_rel_bord, src->bs_rel_bord, sizeof(dst->bs_rel_bord));
- memcpy(dst->bs_num_rel, src->bs_num_rel, sizeof(dst->bs_rel_bord));
- dst->bs_amp_res = src->bs_amp_res;
- dst->bs_num_noise = src->bs_num_noise;
- dst->bs_pointer = src->bs_pointer;
- dst->bs_frame_class = src->bs_frame_class;
+ 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];
}
/// Read how the envelope and noise floor data is delta coded
static void read_sbr_dtdf(SpectralBandReplication *sbr, GetBitContext *gb,
SBRData *ch_data)
{
- get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env[1]);
+ get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env);
get_bits1_vector(gb, ch_data->bs_df_noise, ch_data->bs_num_noise);
}
}
}
- for (i = 0; i < ch_data->bs_num_env[1]; i++) {
+ for (i = 0; i < ch_data->bs_num_env; i++) {
if (ch_data->bs_df_env[i]) {
- // bs_freq_res[0] == bs_freq_res[bs_num_env[1]] from prev frame
+ // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
}
//assign 0th elements of env_facs from last elements
- memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env[1]],
+ memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env],
sizeof(ch_data->env_facs[0]));
}
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;
}
}
-static void read_sbr_single_channel_element(AACContext *ac,
+static int read_sbr_single_channel_element(AACContext *ac,
SpectralBandReplication *sbr,
GetBitContext *gb)
{
if (get_bits1(gb)) // bs_data_extra
skip_bits(gb, 4); // bs_reserved
- read_sbr_grid(ac, sbr, gb, &sbr->data[0]);
+ if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
+ return -1;
read_sbr_dtdf(sbr, gb, &sbr->data[0]);
read_sbr_invf(sbr, gb, &sbr->data[0]);
read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb)))
get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);
+
+ return 0;
}
-static void read_sbr_channel_pair_element(AACContext *ac,
+static int read_sbr_channel_pair_element(AACContext *ac,
SpectralBandReplication *sbr,
GetBitContext *gb)
{
skip_bits(gb, 8); // bs_reserved
if ((sbr->bs_coupling = get_bits1(gb))) {
- read_sbr_grid(ac, sbr, gb, &sbr->data[0]);
+ if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
+ return -1;
copy_sbr_grid(&sbr->data[1], &sbr->data[0]);
read_sbr_dtdf(sbr, gb, &sbr->data[0]);
read_sbr_dtdf(sbr, gb, &sbr->data[1]);
read_sbr_envelope(sbr, gb, &sbr->data[1], 1);
read_sbr_noise(sbr, gb, &sbr->data[1], 1);
} else {
- read_sbr_grid(ac, sbr, gb, &sbr->data[0]);
- read_sbr_grid(ac, sbr, gb, &sbr->data[1]);
+ if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) ||
+ read_sbr_grid(ac, sbr, gb, &sbr->data[1]))
+ return -1;
read_sbr_dtdf(sbr, gb, &sbr->data[0]);
read_sbr_dtdf(sbr, gb, &sbr->data[1]);
read_sbr_invf(sbr, gb, &sbr->data[0]);
get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);
if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb)))
get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]);
+
+ return 0;
}
static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr,
unsigned int cnt = get_bits_count(gb);
if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {
- read_sbr_single_channel_element(ac, sbr, gb);
+ if (read_sbr_single_channel_element(ac, sbr, gb)) {
+ sbr->start = 0;
+ return get_bits_count(gb) - cnt;
+ }
} else if (id_aac == TYPE_CPE) {
- read_sbr_channel_pair_element(ac, sbr, gb);
+ if (read_sbr_channel_pair_element(ac, sbr, gb)) {
+ sbr->start = 0;
+ 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;
}
-/// Time/frequency Grid (14496-3 sp04 p200)
-static int sbr_time_freq_grid(AACContext *ac, SpectralBandReplication *sbr,
- SBRData *ch_data, int ch)
-{
- int abs_bord_lead = ch_data->bs_frame_class >= 2 ? ch_data->bs_var_bord[0] : 0;
- // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots
- int abs_bord_trail = (ch_data->bs_frame_class & 1 ? ch_data->bs_var_bord[1] : 0) + 16;
- int n_rel_lead;
- int i;
-
- if (ch_data->bs_frame_class == FIXFIX) {
- n_rel_lead = ch_data->bs_num_env[1] - 1;
- } else if (ch_data->bs_frame_class == FIXVAR) {
- n_rel_lead = 0;
- } else if (ch_data->bs_frame_class < 4) { // VARFIX or VARVAR
- n_rel_lead = ch_data->bs_num_rel[0];
- } else {
- av_log(ac->avccontext, AV_LOG_ERROR,
- "Invalid bs_frame_class for SBR: %d\n", ch_data->bs_frame_class);
- return -1;
- }
-
- ch_data->t_env_num_env_old = ch_data->t_env[ch_data->bs_num_env[0]];
- ch_data->t_env[0] = abs_bord_lead;
- ch_data->t_env[ch_data->bs_num_env[1]] = abs_bord_trail;
-
- if (ch_data->bs_frame_class == FIXFIX) {
- int temp = (abs_bord_trail + (ch_data->bs_num_env[1] >> 1)) /
- ch_data->bs_num_env[1];
- for (i = 0; i < n_rel_lead; i++)
- ch_data->t_env[i + 1] = ch_data->t_env[i] + temp;
- } else if (ch_data->bs_frame_class > 1) { // VARFIX or VARVAR
- for (i = 0; i < n_rel_lead; i++)
- ch_data->t_env[i + 1] = ch_data->t_env[i] + ch_data->bs_rel_bord[0][i];
- } else { // FIXVAR
- for (i = 0; i < n_rel_lead; i++)
- ch_data->t_env[i + 1] = abs_bord_lead;
- }
-
- if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
- for (i = ch_data->bs_num_env[1] - 1; i > n_rel_lead; i--)
- ch_data->t_env[i] = ch_data->t_env[i + 1] -
- ch_data->bs_rel_bord[1][ch_data->bs_num_env[1] - 1 - i];
- } else { // FIXFIX or VARFIX
- for (i = n_rel_lead; i < ch_data->bs_num_env[1]; i++)
- ch_data->t_env[i + 1] = abs_bord_trail;
- }
-
- ch_data->t_q[0] = ch_data->t_env[0];
- if (ch_data->bs_num_noise > 1) { // typo in spec bases this on bs_num_env...
- unsigned int idx;
- if (ch_data->bs_frame_class == FIXFIX) {
- idx = ch_data->bs_num_env[1] >> 1;
- } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
- idx = ch_data->bs_num_env[1] - FFMAX(ch_data->bs_pointer - 1, 1);
- } else { // VARFIX
- if (!ch_data->bs_pointer)
- idx = 1;
- else if (ch_data->bs_pointer == 1)
- idx = ch_data->bs_num_env[1] - 1;
- else // bs_pointer > 1
- idx = ch_data->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[1]];
- } else
- ch_data->t_q[1] = ch_data->t_env[ch_data->bs_num_env[1]];
-
- return 0;
-}
-
/// Dequantization and stereo decoding (14496-3 sp04 p203)
static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
{
if (id_aac == TYPE_CPE && sbr->bs_coupling) {
float alpha = sbr->data[0].bs_amp_res ? 1.0f : 0.5f;
float pan_offset = sbr->data[0].bs_amp_res ? 12.0f : 24.0f;
- for (e = 1; e <= sbr->data[0].bs_num_env[1]; e++) {
+ for (e = 1; e <= sbr->data[0].bs_num_env; e++) {
for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) {
float temp1 = exp2f(sbr->data[0].env_facs[e][k] * alpha + 7.0f);
float temp2 = exp2f((pan_offset - sbr->data[1].env_facs[e][k]) * alpha);
} else { // SCE or one non-coupled CPE
for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) {
float alpha = sbr->data[ch].bs_amp_res ? 1.0f : 0.5f;
- for (e = 1; e <= sbr->data[ch].bs_num_env[1]; e++)
+ for (e = 1; e <= sbr->data[ch].bs_num_env; e++)
for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++)
sbr->data[ch].env_facs[e][k] =
exp2f(alpha * sbr->data[ch].env_facs[e][k] + 6.0f);
* @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];
}
{
int e, i, m;
- e_a[0] = -(e_a[1] != ch_data->bs_num_env[0]); // l_APrev
- e_a[1] = -1;
- if ((ch_data->bs_frame_class & 1) && ch_data->bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0
- e_a[1] = ch_data->bs_num_env[1] + 1 - ch_data->bs_pointer;
- } else if ((ch_data->bs_frame_class == 2) && (ch_data->bs_pointer > 1)) // VARFIX and bs_pointer > 1
- e_a[1] = ch_data->bs_pointer - 1;
-
memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1]));
- for (e = 0; e < ch_data->bs_num_env[1]; e++) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]];
uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
int k;
}
}
- memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env[1]], sizeof(ch_data->s_indexmapped[0]));
+ memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0]));
}
/// Estimation of current envelope (14496-3 sp04 p218)
int e, i, m;
if (sbr->bs_interpol_freq) {
- for (e = 0; e < ch_data->bs_num_env[1]; e++) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]);
int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
} else {
int k, p;
- for (e = 0; e < ch_data->bs_num_env[1]; e++) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]);
int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
// max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off)
static const float limgain[4] = { 0.70795, 1.0, 1.41254, 10000000000 };
- for (e = 0; e < ch_data->bs_num_env[1]; e++) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
int delta = !((e == e_a[1]) || (e == e_a[0]));
for (k = 0; k < sbr->n_lim; k++) {
float gain_boost, gain_max;
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;
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 (e = 0; e < ch_data->bs_num_env[1]; e++) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0]));
memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0]));
}
}
- for (e = 0; e < ch_data->bs_num_env[1]; e++) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
int phi_sign = (1 - 2*(kx & 1));
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) {
- for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) {
- sbr_time_freq_grid(ac, sbr, &sbr->data[ch], ch);
- }
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[1]);
-
- // 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);
}