[soc]AMR-WB decoder branch, master, updated.
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "AMR-WB decoder". The branch, master has been updated via 121492a18969d4665210fe6dede43482776acce8 (commit) via 8cbd44b44a1b8d4332fc8d22ced69a93d85a31fc (commit) from 01100290fe3b220e4fbbe6ec16f7f85652d25092 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 121492a18969d4665210fe6dede43482776acce8 Author: Marcelo Povoa <marspeoplester@gmail.com> Date: Fri Jul 30 02:34:33 2010 -0300 Write post-processing FIR filters for the high-band diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h index 76a1a60..17f7d9e 100644 --- a/libavcodec/amrwbdata.h +++ b/libavcodec/amrwbdata.h @@ -28,6 +28,7 @@ #define LP_ORDER_16k 20 ///< lpc filter order at 16kHz #define UPS_FIR_SIZE 12 ///< upsampling filter size #define UPS_MEM_SIZE 2 * UPS_FIR_SIZE +#define HB_FIR_SIZE 30 ///< amount of past data needed by HB filters #define MIN_ISF_SPACING (128 / 32768.0) ///< minimum isf gap #define PRED_FACTOR (1.0 / 3.0) @@ -1840,6 +1841,36 @@ static const uint16_t qua_hb_gain[16] = { 11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728 }; +/* High-band post-processing FIR filters coefficients in Q15 */ +// XXX: not sure if it is Q15 indeed (guessing) +static const float bpf_6_7_coef[31] = { // band pass, 6kHz and 7kHz cutoffs + -9.765625e-04, 1.434326e-03, 9.765625e-04, + -8.239746e-04, -1.126099e-02, 3.424072e-02, + -4.336548e-02, 0.000000e+00, 1.159058e-01, + -2.709961e-01, 3.768616e-01, -3.352051e-01, + 1.082764e-01, 2.369995e-01, -5.493469e-01, + 6.749878e-01, + -5.493469e-01, 2.369995e-01, 1.082764e-01, + -3.352051e-01, 3.768616e-01, -2.709961e-01, + 1.159058e-01, 0.000000e+00, -4.336548e-02, + 3.424072e-02, -1.126099e-02, -8.239746e-04, + 9.765625e-04, 1.434326e-03, -9.765625e-04 +}; + +static const float lpf_7_coef[31] = { // low pass, 7kHz cutoff + -6.408691e-04, 1.434326e-03, -2.716064e-03, + 4.455566e-03, -6.195068e-03, 6.988525e-03, + -5.401611e-03, 0.000000e+00, 1.022339e-02, + -2.560425e-02, 4.531860e-02, -6.747437e-02, + 8.944702e-02, -1.080933e-01, 1.206360e-01, + 8.753052e-01, + 1.206360e-01, -1.080933e-01, 8.944702e-02, + -6.747437e-02, 4.531860e-02, -2.560425e-02, + 1.022339e-02, 0.000000e+00, -5.401611e-03, + 6.988525e-03, -6.195068e-03, 4.455566e-03, + -2.716064e-03, 1.434326e-03, -6.408691e-04 +}; + /* Core frame sizes in each mode */ static const uint16_t cf_sizes_wb[] = { 132, 177, 253, 285, 317, 365, 397, 461, 477, diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 2786816..de4b399 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -73,11 +73,13 @@ typedef struct { float prev_tr_gain; ///< previous initial gain used by noise enhancer for thresold float samples_az[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< lower band samples from synthesis at 12.8kHz - float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling at 12.8kHz + float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_OUT]; ///< higher band samples from synthesis at 16kHz - float hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high-pass filters + float hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high pass filters float demph_mem[1]; ///< previous value in the de-emphasis filter + float bpf_6_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band band pass filter + float lpf_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band low pass filter AVLFG prng; ///< random number generator for white noise excitation uint8_t first_frame; ///< flag active during decoding of the first frame @@ -1176,6 +1178,39 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples, } /** + * Apply to high-band samples a 15th order filter + * The filter characteristic depends on the given coefficients + * + * @param out [out] buffer for filtered output + * @param fir_coef [in] filter coefficients + * @param mem [in/out] state from last filtering (updated) + * @param cp_gain [in] compensation gain (usually the filter gain) + * @param in [in] input speech data (high-band) + * + * @remark It is safe to pass the same array in in and out parameters. + */ +static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1], + float mem[HB_FIR_SIZE], float cp_gain, const float *in) +{ + int i, j; + float data[AMRWB_SFR_SIZE_OUT + HB_FIR_SIZE]; // past and current samples + + memcpy(data, mem, HB_FIR_SIZE * sizeof(float)); + + for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) + data[i + HB_FIR_SIZE] = in[i] / cp_gain; + + for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) + { + out[i] = 0.0; + for (j = 0; j <= HB_FIR_SIZE; j++) + out[i] += data[i + j] * fir_coef[j]; + } + + memcpy(mem, data + AMRWB_SFR_SIZE_OUT, HB_FIR_SIZE * sizeof(float)); +} + +/** * Update context state before the next subframe */ static void update_sub_state(AMRWBContext *ctx) @@ -1212,6 +1247,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, float voice_fac, stab_fac; // parameters used for gain smoothing float synth_exc[AMRWB_SUBFRAME_SIZE]; // post-processed excitation for synthesis float hb_exc[AMRWB_SFR_SIZE_OUT]; // excitation for the high frequency band + float hb_samples[AMRWB_SFR_SIZE_OUT]; // filtered high-band samples from synthesis float hb_gain; int sub, i; @@ -1324,12 +1360,17 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, hb_exc, ctx->isf_cur, ctx->isf_past_final); /* High-band post-processing filters */ + hb_fir_filter(hb_samples, bpf_6_7_coef, ctx->bpf_6_7_mem, + 4.0, &ctx->samples_hb[LP_ORDER_16k]); + + if (ctx->fr_cur_mode == MODE_23k85) + hb_fir_filter(hb_samples, lpf_7_coef, ctx->lpf_7_mem, + 1.0, hb_samples); /* Add low frequency and high frequency bands */ for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) { // XXX: the lower band should really be upscaled by 2.0? - sub_buf[i] = (sub_buf[i] * 2.0 + - ctx->samples_hb[i + LP_ORDER_16k]) / 32768.0; + sub_buf[i] = (sub_buf[i] * 2.0 + hb_samples[i]) / 32768.0; } /* Update buffers and history */ commit 8cbd44b44a1b8d4332fc8d22ced69a93d85a31fc Author: Marcelo Povoa <marspeoplester@gmail.com> Date: Fri Jul 30 02:32:08 2010 -0300 Fix high-band excitation length diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 7f6152f..2786816 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -931,11 +931,10 @@ static void de_emphasis(float *out, float *in, float m, float mem[1]) /** * Apply to synthesis a 2nd order high-pass filter - * with cutoff frequency at 31 Hz * * @param out [out] buffer for filtered output * @param hpf_coef [in] filter coefficients as used below - * @param mem [in] state from last filtering + * @param mem [in/out] state from last filtering (updated) * @param in [in] input speech data * * @remark It is safe to pass the same array in in and out parameters. @@ -1028,13 +1027,13 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc, float energy = ff_dot_productf(synth_exc, synth_exc, AMRWB_SUBFRAME_SIZE); /* Generate a white-noise excitation */ - for (i = 0; i < AMRWB_SUBFRAME_SIZE; i++) + for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) hb_exc[i] = 32768.0 - (uint16_t) av_lfg_get(&ctx->prng); ff_scale_vector_to_given_sum_of_squares(hb_exc, hb_exc, energy, - AMRWB_SUBFRAME_SIZE); + AMRWB_SFR_SIZE_OUT); - for (i = 0; i < AMRWB_SUBFRAME_SIZE; i++) + for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) hb_exc[i] *= hb_gain; } @@ -1212,7 +1211,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, float synth_fixed_gain; // the fixed gain that synthesis should use float voice_fac, stab_fac; // parameters used for gain smoothing float synth_exc[AMRWB_SUBFRAME_SIZE]; // post-processed excitation for synthesis - float hb_exc[AMRWB_SUBFRAME_SIZE]; // excitation for the high frequency band + float hb_exc[AMRWB_SFR_SIZE_OUT]; // excitation for the high frequency band float hb_gain; int sub, i; ----------------------------------------------------------------------- Summary of changes: libavcodec/amrwbdata.h | 31 ++++++++++++++++++++++++ libavcodec/amrwbdec.c | 60 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 81 insertions(+), 10 deletions(-) hooks/post-receive -- AMR-WB decoder
On Fri, Jul 30, 2010 at 02:35:21AM -0300, Marcelo Póvoa wrote:
--- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -73,11 +73,13 @@ typedef struct { float prev_tr_gain; ///< previous initial gain used by noise enhancer for thresold
float samples_az[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< lower band samples from synthesis at 12.8kHz - float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling at 12.8kHz + float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_OUT]; ///< higher band samples from synthesis at 16kHz
You should vertically align the doxygen comments. This probably applies to a lot of other places as well.
@@ -1176,6 +1178,39 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
/** + * Apply to high-band samples a 15th order filter + * The filter characteristic depends on the given coefficients + * + * @param out [out] buffer for filtered output + * @param fir_coef [in] filter coefficients + * @param mem [in/out] state from last filtering (updated) + * @param cp_gain [in] compensation gain (usually the filter gain) + * @param in [in] input speech data (high-band)
This is incorrect doxygen syntax. The [in]/[out] attributes need to directly follow the @param command, i.e. @param[in]. You have the same mistake in other places, fix it everywhere. Doxygen should warn about this. Please run doxygen and fix all the warnings that doxygen generates.
+ for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) + {
Please use K&R style, i.e. place the { on the same line as the for/while/if/do. Diego
On 30 July 2010 03:36, Diego Biurrun <diego@biurrun.de> wrote:
On Fri, Jul 30, 2010 at 02:35:21AM -0300, Marcelo Póvoa wrote:
--- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -73,11 +73,13 @@ typedef struct { float prev_tr_gain; ///< previous initial gain used by noise enhancer for thresold
float samples_az[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< lower band samples from synthesis at 12.8kHz - float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling at 12.8kHz + float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_OUT]; ///< higher band samples from synthesis at 16kHz
You should vertically align the doxygen comments. This probably applies to a lot of other places as well.
These lines are too long, so I could not align the comments with the adjacent lines. I've now aligned these three by themselves.
@@ -1176,6 +1178,39 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
/** + * Apply to high-band samples a 15th order filter + * The filter characteristic depends on the given coefficients + * + * @param out [out] buffer for filtered output + * @param fir_coef [in] filter coefficients + * @param mem [in/out] state from last filtering (updated) + * @param cp_gain [in] compensation gain (usually the filter gain) + * @param in [in] input speech data (high-band)
This is incorrect doxygen syntax. The [in]/[out] attributes need to directly follow the @param command, i.e. @param[in]. You have the same mistake in other places, fix it everywhere.
Doxygen should warn about this. Please run doxygen and fix all the warnings that doxygen generates.
Doing this modification I am getting new warnings like this: Warning: argument 'out' of command @param is not found in the argument list of decode_isf_indices_36b(uint16_t *ind, float *isf_q, uint8_t fr_q)
+ for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) + {
Please use K&R style, i.e. place the { on the same line as the for/while/if/do.
Fixed. -- Marcelo
2010/7/30 Marcelo Galvão Póvoa <marspeoplester@gmail.com>:
On 30 July 2010 03:36, Diego Biurrun <diego@biurrun.de> wrote:
On Fri, Jul 30, 2010 at 02:35:21AM -0300, Marcelo Póvoa wrote:
--- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -73,11 +73,13 @@ typedef struct { float prev_tr_gain; ///< previous initial gain used by noise enhancer for thresold
float samples_az[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< lower band samples from synthesis at 12.8kHz - float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling at 12.8kHz + float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_OUT]; ///< higher band samples from synthesis at 16kHz
You should vertically align the doxygen comments. This probably applies to a lot of other places as well.
These lines are too long, so I could not align the comments with the adjacent lines. I've now aligned these three by themselves.
@@ -1176,6 +1178,39 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
/** + * Apply to high-band samples a 15th order filter + * The filter characteristic depends on the given coefficients + * + * @param out [out] buffer for filtered output + * @param fir_coef [in] filter coefficients + * @param mem [in/out] state from last filtering (updated) + * @param cp_gain [in] compensation gain (usually the filter gain) + * @param in [in] input speech data (high-band)
This is incorrect doxygen syntax. The [in]/[out] attributes need to directly follow the @param command, i.e. @param[in]. You have the same mistake in other places, fix it everywhere.
Doxygen should warn about this. Please run doxygen and fix all the warnings that doxygen generates.
Doing this modification I am getting new warnings like this:
Warning: argument 'out' of command @param is not found in the argument list of decode_isf_indices_36b(uint16_t *ind, float *isf_q, uint8_t fr_q)
Nevermind, I've misunderstood your message and put the [in] after the variable name. It's working now.
+ for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) + {
Please use K&R style, i.e. place the { on the same line as the for/while/if/do.
Fixed.
-- Marcelo
-- Marcelo
participants (3)
-
Diego Biurrun -
Marcelo Galvão Póvoa -
Marcelo Póvoa