Should this be split more? I left out the half of this patch that wires this into aac.c since that is still ugly.
This also doesn't yet handle downsampled SBR and is only tested with SBR in pure upsampling mode. Still it decodes al_sbr_qmf_* perfectly. With this commit I'd also like to add myself to the copyright.
From 41bb8f8efff6ca7c8dd68f07a0ee0e70d5476fd3 Mon Sep 17 00:00:00 2001 From: Alex Converse <alex.conve...@gmail.com> Date: Tue, 1 Dec 2009 15:52:03 -0500 Subject: [PATCH 1/4] Add the ff_sbr_apply() function. MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------1" This is a multi-part message in MIME format. --------------1 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit --- aacsbr.c | 132 ++++++++++++++++++++++++++++++++++++++++++----------- aacsbr.h | 12 ++++- aacsbr_internal.h | 1 + 3 files changed, 116 insertions(+), 29 deletions(-) --------------1 Content-Type: text/x-patch; name="0001-Add-the-ff_sbr_apply-function.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="0001-Add-the-ff_sbr_apply-function.patch" diff --git a/aacsbr.c b/aacsbr.c index 1cec490..a26aafe 100644 --- a/aacsbr.c +++ b/aacsbr.c @@ -422,7 +422,9 @@ static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr) memcpy(sbr->f_tablehigh, &sbr->f_master[sbr->spectrum_params[1].bs_xover_band], (sbr->n[1] + 1) * sizeof(sbr->f_master[0])); + sbr->mold = sbr->m; sbr->m = sbr->f_tablehigh[sbr->n[1]] - sbr->f_tablehigh[0]; + sbr->k[4] = sbr->k[3]; sbr->k[3] = sbr->f_tablehigh[0]; // Requirements (14496-3 sp04 p205) @@ -860,6 +862,7 @@ static int sbr_time_freq_grid(AACContext *ac, SpectralBandReplication *sbr, n_rel_trail = ch_data->bs_frame_class & 1 ? ch_data->bs_num_rel[1] : 0; + sbr->t_env_num_env_old[ch] = sbr->t_env[ch][ch_data->bs_num_env[0]]; //FIXME move me into a setup next frame area sbr->t_env[ch][0] = abs_bord_lead; sbr->t_env[ch][ch_data->bs_num_env[1]] = abs_bord_trail; @@ -1004,9 +1007,10 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac, int ch) * @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(const float *in, float *x, float W[32][32][2]) +static void sbr_qmf_analysis(const float *in, float *x, float W[2][32][32][2]) { int i, k, l, n; + memcpy(W[1], W[0], sizeof(W[0])); memcpy(x , x+1024, (320-32)*sizeof(x[0])); memcpy(x+288, in , 1024*sizeof(x[0])); x += 319; @@ -1019,13 +1023,13 @@ static void sbr_qmf_analysis(const float *in, float *x, float W[32][32][2]) for (k = 0; k < 32; k++) { float temp1 = u[0] * 2.0f; float temp2 = -(k + 0.5f) * M_PI / 128.0f; - W[k][l][0] = temp1 * cosf(temp2); - W[k][l][1] = temp1 * sinf(temp2); + W[0][k][l][0] = temp1 * cosf(temp2); + W[0][k][l][1] = temp1 * sinf(temp2); for (n = 1; n < 64; n++) { temp1 = u[n] * 2.0f; temp2 = (n - 0.25f) * (k + 0.5f) * M_PI / 32.0f; - W[k][l][0] += temp1 * cosf(temp2); - W[k][l][1] += temp1 * sinf(temp2); + W[0][k][l][0] += temp1 * cosf(temp2); + W[0][k][l][1] += temp1 * sinf(temp2); } } x += 32; @@ -1034,7 +1038,7 @@ static void sbr_qmf_analysis(const float *in, float *x, float W[32][32][2]) // Synthesis QMF Bank (14496-3 sp04 p206) // Downsampled Synthesis QMF Bank (14496-3 sp04 p206) -static void sbr_qmf_synthesis(float *out, const float **X, +static void sbr_qmf_synthesis(float *out, float X[64][40][2], float *v, const unsigned int div) { int k, l, n; @@ -1042,9 +1046,11 @@ static void sbr_qmf_synthesis(float *out, const float **X, for (l = 0; l < 32; l++) { memmove(&v[128 / div], v, (1280 - 128) / div * sizeof(float)); for (n = 0; n < 128 / div; n++) { - v[n] = X[0][l] * cosf((2.0f * n - 255.0f / div) * M_PI / (256.0f / div)); + v[n] = X[0][l][0] * cosf((2.0f * n - 255.0f / div) * M_PI / (256.0f / div)) - + X[0][l][1] * sinf((2.0f * n - 255.0f / div) * M_PI / (256.0f / div)); for (k = 1; k < 64 / div; k++) { - v[n] += X[k][l] * cosf((k + 0.5f) * (2.0f * n - 255.0f / div) * M_PI / (128.0f / div)); + v[n] += X[k][l][0] * cosf((k + 0.5f) * (2.0f * n - 255.0f / div) * M_PI / (128.0f / div)) - + X[k][l][1] * sinf((k + 0.5f) * (2.0f * n - 255.0f / div) * M_PI / (128.0f / div)); } v[n] /= 64.0f / div; } @@ -1066,8 +1072,8 @@ static void sbr_qmf_synthesis(float *out, const float **X, // High Frequency Generation (14496-3 sp04 p214+) // Inverse Filtering (14496-3 sp04 p214) -static void sbr_hf_inverse_filter(float **alpha0, float **alpha1, - const float ***x_low, int k0) +static void sbr_hf_inverse_filter(float (*alpha0)[2], float (*alpha1)[2], + float x_low[32][40][2], int k0) { int i, j, k, n; for (k = 0; k < k0; k++) { @@ -1193,10 +1199,32 @@ static inline int find_freq_subband(uint16_t *table, int nel, int needle) return -1; } +// Generate the subband filtered lowband +static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr, + float x_low[32][40][2], float W[2][32][32][2]) { + int k, l; + const int t_HFGen = 8; + const int l_f = 32; + memset(x_low, 0, sizeof(x_low)); + for (k = 0; k < sbr->k[3]; k++) { + for (l = t_HFGen; l < l_f + t_HFGen; l++) { + x_low[k][l][0] = W[0][k][l - t_HFGen][0]; + x_low[k][l][1] = W[0][k][l - t_HFGen][1]; + } + } + for (k = 0; k < sbr->k[4]; k++) { + for (l = 0; l < t_HFGen; l++) { + x_low[k][l][0] = W[1][k][l + l_f - t_HFGen][0]; + x_low[k][l][1] = W[1][k][l + l_f - t_HFGen][1]; + } + } + return 0; +} + // High Frequency Generator (14496-3 sp04 p215) static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr, - float **x_high[2], float **x_low[2], float *alpha0[2], - float *alpha1[2], float **bw_array, uint8_t *t_env, + float x_high[32][40][2], float x_low[32][40][2], float (*alpha0)[2], + float (*alpha1)[2], float bw_array[2][5], uint8_t *t_env, int bs_num_env) { int i, x, l; @@ -1235,6 +1263,42 @@ static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr, return 0; } +// Generate the subband filtered lowband +static int sbr_x_gen(SpectralBandReplication *sbr, + float x[64][40][2], float x_low[32][40][2], float Y[2][64][40][2], int ch) { + int k, l; + const int t_HFAdj = ENVELOPE_ADJUSTMENT_OFFSET; + const int l_f = 32; + const int l_Temp = FFMAX(sbr->t_env_num_env_old[ch] - l_f, 0); //FIXME hack to make l_Temp initialize to zero + memset(x, 0, sizeof(x)); + for (k = 0; k < sbr->k[4]; k++) { + for (l = 0; l < l_Temp; l++) { + x[k][l][0] = x_low[k][l + t_HFAdj][0]; + x[k][l][1] = x_low[k][l + t_HFAdj][1]; + } + } + for (; k < sbr->k[4] + sbr->mold; k++) { + for (l = 0; l < l_Temp; l++) { + x[k][l][0] = Y[1][k][l + t_HFAdj + l_f][0]; + x[k][l][1] = Y[1][k][l + t_HFAdj + l_f][1]; + } + } + + for (k = 0; k < sbr->k[3]; k++) { + for (l = l_Temp; l < l_f; l++) { + x[k][l][0] = x_low[k][l + t_HFAdj][0]; + x[k][l][1] = x_low[k][l + t_HFAdj][1]; + } + } + for (; k < sbr->k[4] + sbr->m; k++) { + for (l = l_Temp; l < l_f; l++) { + x[k][l][0] = Y[0][k][l + t_HFAdj][0]; + x[k][l][1] = Y[0][k][l + t_HFAdj][1]; + } + } + return 0; +} + // High Frequency Adjustment (14496-3 sp04 p217) // Mapping (14496-3 sp04 p217) @@ -1294,7 +1358,7 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, } // Estimation of current envelope (14496-3 sp04 p218) -static void sbr_env_estimate(float **e_curr, float ***x_high, +static void sbr_env_estimate(float (*e_curr)[48], float x_high[32][40][2], SpectralBandReplication *sbr, SBRData *ch_data, int ch) { @@ -1439,7 +1503,7 @@ static void sbr_gain_calc(AACContext * ac, SpectralBandReplication *sbr, } // Assembling HF Signals (14496-3 sp04 p220) -static void sbr_hf_assemble(float **y[2], float **x_high[2], +static void sbr_hf_assemble(float y[2][64][40][2], float x_high[32][40][2], SpectralBandReplication *sbr, SBRData *ch_data, int ch, int l_a[2]) { @@ -1457,6 +1521,7 @@ static void sbr_hf_assemble(float **y[2], float **x_high[2], { 0, 1, 0, -1}, // imaginary }; float g_temp[42][48], g_filt[42][48], q_temp[42][48], q_filt[42][48], w_temp[42][48][2]; + memcpy(y[1], y[0], sizeof(y[0])); for (l = 0; l < ch_data->bs_num_env[1]; l++) { for (i = sbr->t_env[ch][l] << 1; i < sbr->t_env[ch][l + 1] << 1; i++) { @@ -1525,30 +1590,43 @@ static void sbr_hf_assemble(float **y[2], float **x_high[2], for (i = sbr->t_env[ch][l] << 1; i < sbr->t_env[ch][l + 1] << 1; i++) { sbr->f_indexsine[i][0] = (((sbr->f_indexsine[i][1] + 1) & 3) + i - (sbr->t_env[ch][0] << 1)) & 3; for (m = 0; m < sbr->m; m++) { - y[i + ENVELOPE_ADJUSTMENT_OFFSET][m + sbr->k[3]][0] = + y[0][i + ENVELOPE_ADJUSTMENT_OFFSET][m + sbr->k[3]][0] = w_temp[i][m][0] + sbr->s_m_boost[i][m] * phi[0][sbr->f_indexsine[i][0]]; - y[i + ENVELOPE_ADJUSTMENT_OFFSET][m + sbr->k[3]][1] = + y[0][i + ENVELOPE_ADJUSTMENT_OFFSET][m + sbr->k[3]][1] = w_temp[i][m][1] + sbr->s_m_boost[i][m] * phi[1][sbr->f_indexsine[i][0]] * (1 - 2*((m + sbr->k[3]) & 1)); } } } } -static void apply_sbr(void) +void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, int ch, float* in, float* out) { -#if 0 + int l_a[2]; + + if (sbr->start) { + sbr_time_freq_grid(ac, sbr, &sbr->data[ch], ch); + sbr_env_noise_floors(sbr, &sbr->data[ch], ch); + sbr_dequant(sbr, id_aac, ch); + } + /* decode channel */ - sbr_qmf_analysis(); - sbr_hf_gen(); + sbr_qmf_analysis(in, sbr->data[ch].analysis_filterbank_samples, sbr->W); + sbr_lf_gen(ac, sbr, sbr->x_low, sbr->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_low, sbr->x_high, sbr->alpha0, sbr->alpha1, + sbr->bw_array, sbr->t_env[ch], sbr->data[ch].bs_num_env[1]); // hf_adj - sbr_mapping(); - sbr_env_estimate(); - sbr_hf_additional_levels(); - sbr_gain_calc(); - sbr_hf_assemble(); + sbr_mapping(ac, sbr, &sbr->data[ch], ch, l_a); + sbr_env_estimate(sbr->e_curr, sbr->x_high, sbr, &sbr->data[ch], ch); + sbr_hf_additional_levels(sbr, &sbr->data[ch]); + sbr_gain_calc(ac, sbr, &sbr->data[ch], l_a); + sbr_hf_assemble(sbr->y, sbr->x_high, sbr, &sbr->data[ch], ch, l_a); + } /* synthesis */ - sbr_qmf_synthesis(); -#endif + sbr_x_gen(sbr, sbr->X, sbr->x_low, sbr->y, ch); + sbr_qmf_synthesis(out, sbr->X, sbr->data[ch].synthesis_filterbank_samples, 1); } diff --git a/aacsbr.h b/aacsbr.h index 575000a..19c6d73 100644 --- a/aacsbr.h +++ b/aacsbr.h @@ -124,8 +124,9 @@ typedef struct { SBRData data[2]; // SBR tool variables uint8_t reset; - uint8_t k[4]; // k0, k1, k2 and kx respectively + uint8_t k[5]; // k0, k1, k2, kx, and kx' respectively uint8_t m; + uint8_t mold; uint8_t n_master; uint8_t n[2]; // n_low and n_high respectively uint8_t n_q; @@ -139,10 +140,17 @@ typedef struct { uint8_t patch_num_subbands[5]; uint8_t patch_start_subband[5]; uint8_t t_env[2][8]; + uint8_t t_env_num_env_old[2]; uint8_t t_q[2][3]; float env_facs[2][7][48]; float noise_facs[2][2][5]; - float W[32][32][2]; + float W[2][32][32][2]; + float x_low[32][40][2]; + float x_high[32][40][2]; + float y[2][64][40][2]; + float X[64][40][2]; + float alpha0[64][2]; + float alpha1[64][2]; float bw_array[2][5]; float e_origmapped[7][48]; float q_mapped[7][48]; diff --git a/aacsbr_internal.h b/aacsbr_internal.h index afd8b24..0e6d062 100644 --- a/aacsbr_internal.h +++ b/aacsbr_internal.h @@ -35,5 +35,6 @@ av_cold void ff_aac_sbr_init(void); int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, GetBitContext *gb, int crc, int cnt, int id_aac); +void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, int ch, float* in, float* out); #endif /* AVCODEC_AACSBR_INTERNAL_H */ --------------1--
_______________________________________________ FFmpeg-soc mailing list FFmpeg-soc@mplayerhq.hu https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc