[FFmpeg-soc] [soc]: r5006 - amr/amrnbdec.c
cmcq
subversion at mplayerhq.hu
Sun Aug 9 14:45:49 CEST 2009
Author: cmcq
Date: Sun Aug 9 14:45:49 2009
New Revision: 5006
Log:
Keep fixed vector sparse until anti-sparseness processing
Modified:
amr/amrnbdec.c
Modified: amr/amrnbdec.c
==============================================================================
--- amr/amrnbdec.c Sun Aug 9 14:38:02 2009 (r5005)
+++ amr/amrnbdec.c Sun Aug 9 14:45:49 2009 (r5006)
@@ -61,6 +61,7 @@ typedef struct AMRContext {
float *excitation; ///< pointer to the current excitation vector in excitation_buf
float pitch_vector[AMR_SUBFRAME_SIZE]; ///< adaptive code book (pitch) vector
+ float fixed_vector[AMR_SUBFRAME_SIZE]; ///< algebraic codebook (fixed) vector (must be kept zero between frames)
float prediction_error[4]; ///< quantified prediction errors {20log10(^gamma_gc)} for previous four subframes
float pitch_gain[5]; ///< quantified pitch gains for the current and previous four subframes
@@ -88,6 +89,8 @@ typedef struct {
int n;
int x[10];
float y[10];
+ int pitch_lag;
+ float pitch_fac;
} AMRFixed;
static void reset_state(AMRContext *p)
@@ -626,62 +629,109 @@ static void decode_fixed_sparse(AMRFixed
* @param p the context
* @param subframe unpacked amr subframe
* @param mode mode of the current frame
- * @param in sparse representation of algebraic codebook vector
- * @param out sharpened fixed vector
+ * @param fixed_sparse sparse respresentation of the fixed vector
*/
static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode,
- const AMRFixed *in, float *out)
+ AMRFixed *fixed_sparse)
{
- int i;
- int x;
- float y;
-
// The spec suggests the current pitch gain is always used, but in other
// modes the pitch and codebook gains are joinly quantized (sec 5.8.2)
// so the codebook gain cannot depend on the quantized pitch gain.
if (mode == MODE_122)
p->beta = FFMIN(p->pitch_gain[4], 1.0);
- memset(out, 0, sizeof(float) * AMR_SUBFRAME_SIZE);
- if (p->pitch_lag_int >= AMR_SUBFRAME_SIZE) {
+ fixed_sparse->pitch_lag = p->pitch_lag_int;
+ fixed_sparse->pitch_fac = p->beta;
+
+ // Save pitch sharpening factor for the next subframe
+ // MODE_475 only updates on the 2nd and 4th subframes - this follows from
+ // the fact that the gains for two subframes are jointly quantized.
+ if (mode != MODE_475 || subframe & 1)
+ p->beta = av_clipf(p->pitch_gain[4], 0.0, SHARP_MAX);
+}
+
+/**
+ * Add fixed vector to an array from a sparse representation
+ *
+ * @param out fixed vector with pitch sharpening
+ * @param in sparse fixed vector
+ * @param scale number to multiply the fixed vector by
+ */
+static void set_fixed_vector(float *out, const AMRFixed *in, float scale) {
+ int i;
+ int x;
+ float y;
+ if (in->pitch_lag >= AMR_SUBFRAME_SIZE) {
for (i = 0; i < in->n; i++) {
x = in->x[i];
- y = in->y[i];
+ y = in->y[i] * scale;
out[x] += y;
}
- } else if (p->pitch_lag_int >= AMR_SUBFRAME_SIZE >> 1) {
+ } else if (in->pitch_lag >= AMR_SUBFRAME_SIZE >> 1) {
for (i = 0; i < in->n; i++) {
x = in->x[i];
- y = in->y[i];
+ y = in->y[i] * scale;
out[x] += y;
- x += p->pitch_lag_int;
+ x += in->pitch_lag;
if (x < AMR_SUBFRAME_SIZE)
- out[x] += y * p->beta;
+ out[x] += y * in->pitch_fac;
}
} else {
for (i = 0; i < in->n; i++) {
x = in->x[i];
- y = in->y[i];
+ y = in->y[i] * scale;
out[x] += y;
- x += p->pitch_lag_int;
+ x += in->pitch_lag;
if (x < AMR_SUBFRAME_SIZE) {
- y *= p->beta;
+ y *= in->pitch_fac;
out[x] += y;
- x += p->pitch_lag_int;
+ x += in->pitch_lag;
if (x < AMR_SUBFRAME_SIZE)
- out[x] += y * p->beta;
+ out[x] += y * in->pitch_fac;
}
}
}
+}
- // Save pitch sharpening factor for the next subframe
- // MODE_475 only updates on the 2nd and 4th subframes - this follows from
- // the fact that the gains for two subframes are jointly quantized.
- if (mode != MODE_475 || subframe & 1)
- p->beta = av_clipf(p->pitch_gain[4], 0.0, SHARP_MAX);
+/**
+ * Clear array values set by set_fixed_vector
+ *
+ * @param out fixed vector to be cleared
+ * @param in sparse fixed vector
+ */
+static void clear_fixed_vector(float *out, const AMRFixed *in) {
+ int i;
+ int x;
+ if (in->pitch_lag >= AMR_SUBFRAME_SIZE) {
+ for (i = 0; i < in->n; i++)
+ out[in->x[i]] = 0.0;
+ } else if (in->pitch_lag >= AMR_SUBFRAME_SIZE >> 1) {
+ for (i = 0; i < in->n; i++) {
+ x = in->x[i];
+ out[x] = 0.0;
+
+ x += in->pitch_lag;
+ if (x < AMR_SUBFRAME_SIZE)
+ out[x] = 0.0;
+ }
+ } else {
+ for (i = 0; i < in->n; i++) {
+ x = in->x[i];
+ out[x] = 0.0;
+
+ x += in->pitch_lag;
+ if (x < AMR_SUBFRAME_SIZE) {
+ out[x] = 0.0;
+
+ x += in->pitch_lag;
+ if (x < AMR_SUBFRAME_SIZE)
+ out[x] = 0.0;
+ }
+ }
+ }
}
/// @}
@@ -808,13 +858,16 @@ static void set_fixed_gain(AMRContext *p
* reference source, but not in the spec.
*
* @param p the context
- * @param fixed_vector algebraic codebook vector
+ * @param fixed_sparse algebraic codebook vector
+ * @param fixed_vector unfiltered fixed vector
* @param fixed_gain smoothed gain
- * @param spare_vector space for modified vector if necessary
+ * @param out space for modified vector if necessary
*/
-static float *anti_sparseness(AMRContext *p, float *fixed_vector,
- float fixed_gain, float *spare_vector)
+static float *anti_sparseness(AMRContext *p, AMRFixed *fixed_sparse,
+ const float *fixed_vector,
+ float fixed_gain, float *out)
{
+ int i, k;
int ir_filter_strength;
if (p->pitch_gain[4] < 0.6) {
@@ -852,23 +905,58 @@ static float *anti_sparseness(AMRContext
if (p->cur_frame_mode != MODE_74 && p->cur_frame_mode < MODE_102
&& ir_filter_strength < 2) {
- const float **filters;
+ const float *filter = (p->cur_frame_mode == MODE_795 ?
+ ir_filters_lookup_MODE_795 :
+ ir_filters_lookup)[ir_filter_strength];
+ float filter1[40], filter2[40];
+ int lag = fixed_sparse->pitch_lag;
+ float fac = fixed_sparse->pitch_fac;
- if (p->cur_frame_mode == MODE_795) {
- filters = ir_filters_lookup_MODE_795;
- } else
- filters = ir_filters_lookup;
+ if (fixed_sparse->pitch_lag < AMR_SUBFRAME_SIZE) {
+ for (k = 0; k < lag; k++)
+ filter1[k] = filter[k]
+ + fac * filter [AMR_SUBFRAME_SIZE + k - lag];
+ for (; k < AMR_SUBFRAME_SIZE; k++)
+ filter1[k] = filter[k]
+ + fac * filter [ k - lag];
- ff_celp_convolve_circf(spare_vector, fixed_vector,
- filters[ir_filter_strength], AMR_SUBFRAME_SIZE);
- fixed_vector = spare_vector;
- }
+ if (fixed_sparse->pitch_lag < AMR_SUBFRAME_SIZE >> 1) {
+ for (k = 0; k < lag; k++)
+ filter2[k] = filter[k]
+ + fac * filter1[AMR_SUBFRAME_SIZE + k - lag];
+ for (; k < AMR_SUBFRAME_SIZE; k++)
+ filter2[k] = filter[k]
+ + fac * filter1[ k - lag];
+ }
+ }
+
+ memset(out, 0, sizeof(float) * AMR_SUBFRAME_SIZE);
+ for (i = 0; i < fixed_sparse->n; i++) {
+ int x = fixed_sparse->x[i];
+ float y = fixed_sparse->y[i];
+ const float *filterp;
+
+ if (x >= AMR_SUBFRAME_SIZE - lag) {
+ filterp = filter;
+ } else if (x >= AMR_SUBFRAME_SIZE - (lag << 1)) {
+ filterp = filter1;
+ } else
+ filterp = filter2;
+
+ for (k = 0; k < x; k++)
+ out[k] += y * filterp[AMR_SUBFRAME_SIZE + k - x];
+
+ for (; k < AMR_SUBFRAME_SIZE; k++)
+ out[k] += y * filterp[ k - x];
+ }
+ } else
+ out = fixed_vector;
// update ir filter strength history
p->prev_ir_filter_strength = ir_filter_strength;
p->prev_sparse_fixed_gain = fixed_gain;
- return fixed_vector;
+ return out;
}
/// @}
@@ -1080,8 +1168,7 @@ static int amrnb_decode_frame(AVCodecCon
float *buf_out = data; // pointer to the output data buffer
int i, subframe;
float fixed_gain_factor;
- AMRFixed fixed_sparse;
- float fixed_vector[AMR_SUBFRAME_SIZE]; // algebraic code book (fixed) vector
+ AMRFixed fixed_sparse; // fixed vector up to anti-sparseness processing
float spare_vector[AMR_SUBFRAME_SIZE]; // extra stack space to hold result from anti-sparseness processing
float synth_fixed_gain; // the fixed gain that synthesis should use
float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use
@@ -1115,17 +1202,18 @@ static int amrnb_decode_frame(AVCodecCon
decode_gains(p, amr_subframe, p->cur_frame_mode, subframe,
&fixed_gain_factor);
- pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse,
- fixed_vector);
+ pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse);
+
+ set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0);
set_fixed_gain(p, p->cur_frame_mode, fixed_gain_factor,
- ff_energyf(fixed_vector, AMR_SUBFRAME_SIZE));
+ ff_energyf(p->fixed_vector, AMR_SUBFRAME_SIZE));
// The excitation feedback is calculated without any processing such
// as fixed gain smoothing. This isn't mentioned in the specification.
- ff_weighted_vector_sumf(p->excitation, p->excitation, fixed_vector,
- p->pitch_gain[4], p->fixed_gain[4],
- AMR_SUBFRAME_SIZE);
+ for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
+ p->excitation[i] *= p->pitch_gain[4];
+ set_fixed_vector(p->excitation, &fixed_sparse, p->fixed_gain[4]);
// In the ref decoder, excitation is stored with no fractional bits.
// This step prevents buzz in silent periods. The ref encoder can
@@ -1141,8 +1229,8 @@ static int amrnb_decode_frame(AVCodecCon
synth_fixed_gain = fixed_gain_smooth(p, p->lsf_q[subframe],
p->lsf_avg, p->cur_frame_mode);
- synth_fixed_vector = anti_sparseness(p, fixed_vector, synth_fixed_gain,
- spare_vector);
+ synth_fixed_vector = anti_sparseness(p, &fixed_sparse, p->fixed_vector,
+ synth_fixed_gain, spare_vector);
if (synthesis(p, p->lpc[subframe], synth_fixed_gain,
synth_fixed_vector, &p->samples_in[LP_FILTER_ORDER], 0))
@@ -1155,6 +1243,7 @@ static int amrnb_decode_frame(AVCodecCon
postfilter(p, p->lpc[subframe], buf_out + subframe * AMR_SUBFRAME_SIZE);
// update buffers and history
+ clear_fixed_vector(p->fixed_vector, &fixed_sparse);
update_state(p);
}
More information about the FFmpeg-soc
mailing list