[FFmpeg-soc] [soc]AMR-WB decoder branch, master, updated.
Marcelo Póvoa
marspeoplester at gmail.com
Thu Jul 22 07:37:53 CEST 2010
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 ade74ca125016eab5a8c5766e192bd8885686b01 (commit)
via ee327e3dbb0cfa189db2b12dce8ea9154ade2943 (commit)
via 5216a6b9e872b5c23c56f91011a83ac87c19b329 (commit)
via 50f3a13500de12d7d9fb3b382965c133a9eea200 (commit)
from c2a8e2ad2d9c51c9d1f7b9101175db05f2fecabb (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 ade74ca125016eab5a8c5766e192bd8885686b01
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date: Thu Jul 22 02:35:50 2010 -0300
Sketch the LP filter (6k60 mode) for the high freq band,
up to the autocorrelation calculation
diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index d16253a..7f221e4 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -25,6 +25,7 @@
#include <stdint.h>
#define LP_ORDER 16 ///< linear predictive coding filter order
+#define LP_ORDER_16k 20 ///< lpc filter order at 16kHz
#define MIN_ISF_SPACING (128 / 32768.0) ///< minimum isf gap
#define PRED_FACTOR (1.0 / 3.0)
#define MIN_ENERGY -14.0 ///< initial innnovation energy (dB)
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 58bbff6..a0bf66d 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -1038,6 +1038,50 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
hb_exc[i] *= hb_gain;
}
+static float auto_correlation(float *diff_isf, float mean, int lag)
+{
+ int i;
+ float sum = 0.0;
+
+ for (i = 7; i < LP_ORDER - 2; i++) {
+ float prod = (diff_isf[i] - mean) * (diff_isf[i - lag] - mean);
+ sum += prod * prod;
+ }
+ return sum;
+}
+
+static void extrapolate_isf(float *out, float *isf)
+{
+ float diff_isf[LP_ORDER - 2], diff_mean;
+ float corr_lag[3];
+ int i, i_max_corr;
+
+ memcpy(out, isf, LP_ORDER - 1);
+ out[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];
+
+ /* Calculate the difference vector */
+ for (i = 0; i < LP_ORDER - 2; i++)
+ diff_isf[i] = isf[i + 1] - isf[i];
+
+ diff_mean = 0.0;
+ for (i = 2; i < LP_ORDER - 2; i++)
+ diff_mean += diff_isf[i] / (LP_ORDER - 4);
+
+ /* Find which is the maximum autocorrelation */
+ i_max_corr = 0;
+ for (i = 0; i < 3; i++) {
+ corr_lag[i] = auto_correlation(diff_isf, diff_mean, i + 2);
+ if (corr_lag[i] > corr_lag[i_max_corr])
+ i_max_corr = i;
+ }
+ i_max_corr++;
+
+ for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
+ out[i] = isf[i - 1] + isf[i - 1 - i_max_corr]
+ - isf[i - 2 - i_max_corr];
+ return;
+}
+
/**
* Update context state before the next subframe
*/
commit ee327e3dbb0cfa189db2b12dce8ea9154ade2943
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date: Thu Jul 22 02:33:20 2010 -0300
Test: Fix ISF/ISP initialization, add new past ISF, fix typo in
isf_set_min_dist, add ISP special case when in the first frame
diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index a4404be..d16253a 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -25,8 +25,8 @@
#include <stdint.h>
#define LP_ORDER 16 ///< linear predictive coding filter order
-#define MIN_ISF_SPACING 50.0 // XXX: Taken from fixed-point 26.173, not sure
-#define PRED_FACTOR (1.0/3.0)
+#define MIN_ISF_SPACING (128 / 32768.0) ///< minimum isf gap
+#define PRED_FACTOR (1.0 / 3.0)
#define MIN_ENERGY -14.0 ///< initial innnovation energy (dB)
#define ENERGY_MEAN 30.0 ///< mean innovation energy (dB) in all modes
@@ -1611,10 +1611,10 @@ static const int16_t isf_mean[LP_ORDER] = {
8750, 9753, 10705, 11728, 12833, 13971, 15043, 4037
};
-/* Initialization tables for the ISP vector */
-static const int16_t isp_init[LP_ORDER] = {
- 32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
- -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
+/* Initialization tables for the processed ISF vector */
+static const int16_t isf_init[LP_ORDER] = {
+ 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
+ 9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
};
/* Coefficients for FIR interpolation of excitation vector
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 0281ae1..58bbff6 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -45,8 +45,9 @@ typedef struct {
uint8_t fr_mode_ind; ///< mode indication field
uint8_t fr_mode_req; ///< mode request field
uint8_t fr_crc; ///< crc for class A bits
- float isf_quant[LP_ORDER]; ///< quantized ISF vector from current frame
+ float isf_cur[LP_ORDER]; ///< working ISF vector from current frame
float isf_q_past[LP_ORDER]; ///< quantized ISF vector of the previous frame
+ float isf_past_final[LP_ORDER]; ///< final processed ISF vector of the prev frame
double isp[4][LP_ORDER]; ///< ISP vectors from current frame
double isp_sub4_past[LP_ORDER]; ///< ISP vector for the 4th subframe of the previous frame
@@ -77,6 +78,7 @@ typedef struct {
float hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high-pass filters
AVLFG prng; ///< random number generator for white noise excitation
+ uint8_t first_frame; ///< flag active in the first frame decoded
} AMRWBContext;
static av_cold int amrwb_decode_init(AVCodecContext *avctx)
@@ -88,12 +90,12 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
av_lfg_init(&ctx->prng, 1);
- ctx->excitation = &ctx->excitation_buf[PITCH_MAX + LP_ORDER + 1];
+ ctx->excitation = &ctx->excitation_buf[PITCH_MAX + LP_ORDER + 1];
+ ctx->first_frame = 1;
+ ctx->tilt_coef = ctx->prev_tr_gain = 0.0;
for (i = 0; i < LP_ORDER; i++)
- ctx->isp_sub4_past[i] = isp_init[i] / (float) (1 << 15);
-
- ctx->tilt_coef = ctx->prev_tr_gain = 0.0;
+ ctx->isf_past_final[i] = isf_init[i] / (float) (1 << 15);
for (i = 0; i < 4; i++)
ctx->prediction_error[i] = MIN_ENERGY;
@@ -278,7 +280,7 @@ static void isf_set_min_dist(float *isf, float min_spacing, int size) {
int i;
float prev = 0.0;
- for (i = 0; i < size; i++) {
+ for (i = 0; i < size - 1; i++) {
isf[i] = FFMAX(isf[i], prev + min_spacing);
prev = isf[i];
}
@@ -813,7 +815,9 @@ static float stability_factor(const float *isf, const float *isf_past)
for (i = 0; i < LP_ORDER - 1; i++)
acc += (isf[i] - isf_past[i]) * (isf[i] - isf_past[i]);
- return 1.25 - acc * 0.8 / 256;
+ // XXX: I could not understand well this part from ref code
+ // it made more sense changing the "/ 256" to "* 256"
+ return FFMAX(0.0, 1.25 - acc * 0.8 * 256);
}
/**
@@ -1073,21 +1077,27 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
/* Decode the quantized ISF vector */
if (ctx->fr_cur_mode == MODE_6k60) {
- decode_isf_indices_36b(cf->isp_id, ctx->isf_quant, ctx->fr_quality);
+ decode_isf_indices_36b(cf->isp_id, ctx->isf_cur, ctx->fr_quality);
}
else {
- decode_isf_indices_46b(cf->isp_id, ctx->isf_quant, ctx->fr_quality);
+ decode_isf_indices_46b(cf->isp_id, ctx->isf_cur, ctx->fr_quality);
}
- stab_fac = stability_factor(ctx->isf_quant, ctx->isf_q_past);
+ isf_add_mean_and_past(ctx->isf_cur, ctx->isf_q_past);
+ isf_set_min_dist(ctx->isf_cur, MIN_ISF_SPACING, LP_ORDER);
- isf_add_mean_and_past(ctx->isf_quant, ctx->isf_q_past);
- isf_set_min_dist(ctx->isf_quant, MIN_ISF_SPACING, LP_ORDER);
+ stab_fac = stability_factor(ctx->isf_cur, ctx->isf_past_final);
- isf2isp(ctx->isf_quant, ctx->isp[3]);
+ isf2isp(ctx->isf_cur, ctx->isp[3]);
/* Generate a ISP vector for each subframe */
+ if (ctx->first_frame) {
+ ctx->first_frame = 0;
+ memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(double));
+ }
interpolate_isp(ctx->isp, ctx->isp_sub4_past);
+ /* XXX: Tested against the ref code until here */
+
for (sub = 0; sub < 4; sub++)
isp2lp(ctx->isp[sub], ctx->lp_coef[sub], LP_ORDER/2);
@@ -1170,6 +1180,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
// update state for next frame
memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
+ memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
/* report how many samples we got */
*data_size = 4 * AMRWB_SFR_SIZE_OUT * sizeof(float);
commit 5216a6b9e872b5c23c56f91011a83ac87c19b329
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date: Wed Jul 21 21:32:30 2010 -0300
Fix the ISF past vector initialization, now to zero
diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 29624fa..a4404be 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -1611,12 +1611,7 @@ static const int16_t isf_mean[LP_ORDER] = {
8750, 9753, 10705, 11728, 12833, 13971, 15043, 4037
};
-/* Initialization tables for ISF and ISP vectors */
-static const int16_t isf_init[LP_ORDER] = {
- 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
- 9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
-};
-
+/* Initialization tables for the ISP vector */
static const int16_t isp_init[LP_ORDER] = {
32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
-6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 992bcdc..0281ae1 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -90,10 +90,8 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
ctx->excitation = &ctx->excitation_buf[PITCH_MAX + LP_ORDER + 1];
- for (i = 0; i < LP_ORDER; i++) {
- ctx->isf_q_past[i] = isf_init[i] / (float) (1 << 15);
+ for (i = 0; i < LP_ORDER; i++)
ctx->isp_sub4_past[i] = isp_init[i] / (float) (1 << 15);
- }
ctx->tilt_coef = ctx->prev_tr_gain = 0.0;
@@ -262,8 +260,8 @@ static void isf_add_mean_and_past(float *isf_q, float *isf_past) {
for (i = 0; i < LP_ORDER; i++) {
tmp = isf_q[i];
- isf_q[i] = tmp + isf_mean[i] / (float) (1<<15);
- isf_q[i] = isf_q[i] + PRED_FACTOR * isf_past[i];
+ isf_q[i] += isf_mean[i] / (float) (1<<15);
+ isf_q[i] += PRED_FACTOR * isf_past[i];
isf_past[i] = tmp;
}
}
commit 50f3a13500de12d7d9fb3b382965c133a9eea200
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date: Wed Jul 21 14:21:49 2010 -0300
Use separate states for the high-pass filters
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 063afc0..992bcdc 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -74,7 +74,7 @@ typedef struct {
float samples_in[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< floating point samples
float demph_mem[1]; ///< previous value in the de-emphasis filter
- float hpf_mem[4]; ///< previous values in the high-pass filter
+ float hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high-pass filters
AVLFG prng; ///< random number generator for white noise excitation
} AMRWBContext;
@@ -1150,14 +1150,14 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
de_emphasis(&ctx->samples_in[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);
high_pass_filter(&ctx->samples_in[LP_ORDER], hpf_31_coef,
- ctx->hpf_mem, &ctx->samples_in[LP_ORDER]);
+ ctx->hpf_31_mem, &ctx->samples_in[LP_ORDER]);
// XXX: the 5/4 upsampling for the lower band goes in here
/* High frequency band generation */
high_pass_filter(&ctx->samples_in[LP_ORDER], hpf_400_coef,
- ctx->hpf_mem, &ctx->samples_in[LP_ORDER]);
+ ctx->hpf_400_mem, &ctx->samples_in[LP_ORDER]);
hb_gain = find_hb_gain(ctx, &ctx->samples_in[LP_ORDER],
cur_subframe->hb_gain, cf->vad);
-----------------------------------------------------------------------
Summary of changes:
libavcodec/amrwbdata.h | 16 +++-----
libavcodec/amrwbdec.c | 95 +++++++++++++++++++++++++++++++++++++-----------
2 files changed, 80 insertions(+), 31 deletions(-)
hooks/post-receive
--
AMR-WB decoder
More information about the FFmpeg-soc
mailing list