Mercurial > libavcodec.hg
comparison aacsbr.c @ 11847:67206bbbab10 libavcodec
Rewrite the SBR decoder QMF analysis filter on top of the IMDCT instead of the RDFT.
This is based on a procedure to implement the filterbank on the DCT-IV described in
Hsu, H.W. et al. "A Complex Quadrature Mirror Filterbanks for MPEG-4 HE-AAC"
http://sites.google.com/site/wenchiehlee1020/Papers/ComplexFB_AES_121paper144.pdf
author | alexc |
---|---|
date | Mon, 07 Jun 2010 21:52:08 +0000 |
parents | 9103a9b3573a |
children | 6b52f0c3263d |
comparison
equal
deleted
inserted
replaced
11846:44a08df9971c | 11847:67206bbbab10 |
---|---|
69 }; | 69 }; |
70 | 70 |
71 static VLC vlc_sbr[10]; | 71 static VLC vlc_sbr[10]; |
72 static const int8_t vlc_sbr_lav[10] = | 72 static const int8_t vlc_sbr_lav[10] = |
73 { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 }; | 73 { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 }; |
74 static DECLARE_ALIGNED(16, float, analysis_cos_pre)[64]; | |
75 static DECLARE_ALIGNED(16, float, analysis_sin_pre)[64]; | |
76 static DECLARE_ALIGNED(16, float, analysis_cossin_post)[32][2]; | |
77 static const DECLARE_ALIGNED(16, float, zero64)[64]; | 74 static const DECLARE_ALIGNED(16, float, zero64)[64]; |
78 | 75 |
79 #define SBR_INIT_VLC_STATIC(num, size) \ | 76 #define SBR_INIT_VLC_STATIC(num, size) \ |
80 INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \ | 77 INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \ |
81 sbr_tmp[num].sbr_bits , 1, 1, \ | 78 sbr_tmp[num].sbr_bits , 1, 1, \ |
114 SBR_INIT_VLC_STATIC(6, 544); | 111 SBR_INIT_VLC_STATIC(6, 544); |
115 SBR_INIT_VLC_STATIC(7, 544); | 112 SBR_INIT_VLC_STATIC(7, 544); |
116 SBR_INIT_VLC_STATIC(8, 592); | 113 SBR_INIT_VLC_STATIC(8, 592); |
117 SBR_INIT_VLC_STATIC(9, 512); | 114 SBR_INIT_VLC_STATIC(9, 512); |
118 | 115 |
119 for (n = 0; n < 64; n++) { | |
120 float pre = M_PI * n / 64; | |
121 analysis_cos_pre[n] = cosf(pre); | |
122 analysis_sin_pre[n] = sinf(pre); | |
123 } | |
124 for (k = 0; k < 32; k++) { | |
125 float post = M_PI * (k + 0.5) / 128; | |
126 analysis_cossin_post[k][0] = 4.0 * cosf(post); | |
127 analysis_cossin_post[k][1] = -4.0 * sinf(post); | |
128 } | |
129 for (n = 1; n < 320; n++) | 116 for (n = 1; n < 320; n++) |
130 sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n]; | 117 sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n]; |
131 sbr_qmf_window_us[384] = -sbr_qmf_window_us[384]; | 118 sbr_qmf_window_us[384] = -sbr_qmf_window_us[384]; |
132 sbr_qmf_window_us[512] = -sbr_qmf_window_us[512]; | 119 sbr_qmf_window_us[512] = -sbr_qmf_window_us[512]; |
133 | 120 |
140 sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 | 127 sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 |
141 sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; | 128 sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; |
142 sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); | 129 sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); |
143 sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); | 130 sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); |
144 ff_mdct_init(&sbr->mdct, 7, 1, 1.0/64); | 131 ff_mdct_init(&sbr->mdct, 7, 1, 1.0/64); |
145 ff_rdft_init(&sbr->rdft, 6, IDFT_R2C); | 132 ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0); |
146 } | 133 } |
147 | 134 |
148 av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr) | 135 av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr) |
149 { | 136 { |
150 ff_mdct_end(&sbr->mdct); | 137 ff_mdct_end(&sbr->mdct); |
151 ff_rdft_end(&sbr->rdft); | 138 ff_mdct_end(&sbr->mdct_ana); |
152 } | 139 } |
153 | 140 |
154 static int qsort_comparison_function_int16(const void *a, const void *b) | 141 static int qsort_comparison_function_int16(const void *a, const void *b) |
155 { | 142 { |
156 return *(const int16_t *)a - *(const int16_t *)b; | 143 return *(const int16_t *)a - *(const int16_t *)b; |
1137 * Analysis QMF Bank (14496-3 sp04 p206) | 1124 * Analysis QMF Bank (14496-3 sp04 p206) |
1138 * | 1125 * |
1139 * @param x pointer to the beginning of the first sample window | 1126 * @param x pointer to the beginning of the first sample window |
1140 * @param W array of complex-valued samples split into subbands | 1127 * @param W array of complex-valued samples split into subbands |
1141 */ | 1128 */ |
1142 static void sbr_qmf_analysis(DSPContext *dsp, RDFTContext *rdft, const float *in, float *x, | 1129 static void sbr_qmf_analysis(DSPContext *dsp, RDFTContext *mdct, const float *in, float *x, |
1143 float z[320], float W[2][32][32][2], | 1130 float z[320], float W[2][32][32][2], |
1144 float scale) | 1131 float scale) |
1145 { | 1132 { |
1146 int i, k; | 1133 int i, k; |
1147 memcpy(W[0], W[1], sizeof(W[0])); | 1134 memcpy(W[0], W[1], sizeof(W[0])); |
1154 // are not supported | 1141 // are not supported |
1155 float re, im; | 1142 float re, im; |
1156 dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320); | 1143 dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320); |
1157 for (k = 0; k < 64; k++) { | 1144 for (k = 0; k < 64; k++) { |
1158 float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256]; | 1145 float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256]; |
1159 z[k] = f * analysis_cos_pre[k]; | 1146 z[k] = f; |
1160 z[k+64] = f; | 1147 } |
1161 } | 1148 //Shuffle to IMDCT |
1162 ff_rdft_calc(rdft, z); | 1149 z[64] = z[0]; |
1163 re = z[0] * 0.5f; | |
1164 im = 0.5f * dsp->scalarproduct_float(z+64, analysis_sin_pre, 64); | |
1165 W[1][i][0][0] = re * analysis_cossin_post[0][0] - im * analysis_cossin_post[0][1]; | |
1166 W[1][i][0][1] = re * analysis_cossin_post[0][1] + im * analysis_cossin_post[0][0]; | |
1167 for (k = 1; k < 32; k++) { | 1150 for (k = 1; k < 32; k++) { |
1168 re = z[2*k ] - re; | 1151 z[64+2*k-1] = z[ k]; |
1169 im = z[2*k+1] - im; | 1152 z[64+2*k ] = -z[64-k]; |
1170 W[1][i][k][0] = re * analysis_cossin_post[k][0] - im * analysis_cossin_post[k][1]; | 1153 } |
1171 W[1][i][k][1] = re * analysis_cossin_post[k][1] + im * analysis_cossin_post[k][0]; | 1154 z[64+63] = z[32]; |
1155 | |
1156 ff_imdct_half(mdct, z, z+64); | |
1157 for (k = 0; k < 32; k++) { | |
1158 W[1][i][k][0] = -z[63-k]; | |
1159 W[1][i][k][1] = z[k]; | |
1172 } | 1160 } |
1173 x += 32; | 1161 x += 32; |
1174 } | 1162 } |
1175 } | 1163 } |
1176 | 1164 |
1728 if (sbr->start) { | 1716 if (sbr->start) { |
1729 sbr_dequant(sbr, id_aac); | 1717 sbr_dequant(sbr, id_aac); |
1730 } | 1718 } |
1731 for (ch = 0; ch < nch; ch++) { | 1719 for (ch = 0; ch < nch; ch++) { |
1732 /* decode channel */ | 1720 /* decode channel */ |
1733 sbr_qmf_analysis(&ac->dsp, &sbr->rdft, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, | 1721 sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, |
1734 (float*)sbr->qmf_filter_scratch, | 1722 (float*)sbr->qmf_filter_scratch, |
1735 sbr->data[ch].W, 1/(-1024 * ac->sf_scale)); | 1723 sbr->data[ch].W, 1/(-1024 * ac->sf_scale)); |
1736 sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W); | 1724 sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W); |
1737 if (sbr->start) { | 1725 if (sbr->start) { |
1738 sbr_hf_inverse_filter(sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); | 1726 sbr_hf_inverse_filter(sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); |