[FFmpeg-soc] [soc]: r5005 - amr/amrnbdec.c
cmcq
subversion at mplayerhq.hu
Sun Aug 9 14:38:02 CEST 2009
Author: cmcq
Date: Sun Aug 9 14:38:02 2009
New Revision: 5005
Log:
Keep fixed vector in a sparse representation until pitch sharpening
Modified:
amr/amrnbdec.c
Modified: amr/amrnbdec.c
==============================================================================
--- amr/amrnbdec.c Sun Aug 9 14:18:27 2009 (r5004)
+++ amr/amrnbdec.c Sun Aug 9 14:38:02 2009 (r5005)
@@ -83,6 +83,13 @@ typedef struct AMRContext {
} AMRContext;
+/** Sparse representation for the algebraic codebook (fixed) vector */
+typedef struct {
+ int n;
+ int x[10];
+ float y[10];
+} AMRFixed;
+
static void reset_state(AMRContext *p)
{
int i;
@@ -479,33 +486,14 @@ static void decode_pitch_vector(AMRConte
/// @{
/**
- * Reconstruct the algebraic codebook vector.
- *
- * @param pulse_position vector of pulse positions
- * @param sign signs of the pulses
- * @param nr_pulses number of pulses
- * @param fixed_vector algebraic codebook vector
- */
-static void reconstruct_fixed_vector(int *pulse_position, int sign,
- int nr_pulses, float *fixed_vector)
-{
- int i;
-
- memset(fixed_vector, 0, AMR_SUBFRAME_SIZE * sizeof(float));
-
- for (i = 0; i < nr_pulses; i++)
- fixed_vector[pulse_position[i]] = ((sign >> i) & 1) ? 1.0 : -1.0;
-}
-
-/**
* Decode the algebraic codebook index to pulse positions and signs and
* construct the algebraic codebook vector for MODE_102.
*
* @param fixed_index positions of the eight pulses
- * @param fixed_vector pointer to the algebraic codebook vector
+ * @param fixed_sparse pointer to the algebraic codebook vector
*/
static void decode_8_pulses_31bits(const int16_t *fixed_index,
- float *fixed_vector)
+ AMRFixed *fixed_sparse)
{
int pulse_position[8];
int i, temp;
@@ -534,14 +522,15 @@ static void decode_8_pulses_31bits(const
pulse_position[3] = (pulse_position[3] << 1) + ( fixed_index[6] & 1);
pulse_position[7] = (pulse_position[7] << 1) + ((fixed_index[6] >> 1) & 1);
- memset(fixed_vector, 0, AMR_SUBFRAME_SIZE * sizeof(float));
-
+ fixed_sparse->n = 8;
for (i = 0; i < TRACKS_MODE_102; i++) {
const int pos1 = (pulse_position[i] << 2) + i;
const int pos2 = (pulse_position[i + 4] << 2) + i;
const float sign = fixed_index[i] ? -1.0 : 1.0;
- fixed_vector[pos1] = sign;
- fixed_vector[pos2] += pos2 < pos1 ? -sign : sign;
+ fixed_sparse->x[i ] = pos1;
+ fixed_sparse->x[i + 4] = pos2;
+ fixed_sparse->y[i ] = sign;
+ fixed_sparse->y[i + 4] = pos2 < pos1 ? -sign : sign;
}
}
@@ -552,21 +541,22 @@ static void decode_8_pulses_31bits(const
* @note: The positions and signs are explicitly coded in MODE_122.
*
* @param fixed_index positions of the ten pulses
- * @param fixed_vector pointer to the algebraic codebook vector
+ * @param fixed_sparse pointer to the algebraic codebook vector
*/
static void decode_10_pulses_35bits(const int16_t *fixed_index,
- float *fixed_vector)
+ AMRFixed *fixed_sparse)
{
int i;
- memset(fixed_vector, 0, AMR_SUBFRAME_SIZE * sizeof(float));
-
+ fixed_sparse->n = 10;
for (i = 0; i < TRACKS; i++) {
const int pos1 = gray_decode[fixed_index[i ] & 7] * TRACKS + i;
const int pos2 = gray_decode[fixed_index[i + 5] & 7] * TRACKS + i;
const float sign = (fixed_index[i] & 8) ? -1.0 : 1.0;
- fixed_vector[pos1] = sign;
- fixed_vector[pos2] += pos2 < pos1 ? -sign : sign;
+ fixed_sparse->x[i ] = pos1;
+ fixed_sparse->x[i + 5] = pos2;
+ fixed_sparse->y[i ] = sign;
+ fixed_sparse->y[i + 5] = pos2 < pos1 ? -sign : sign;
}
}
@@ -580,63 +570,71 @@ static void decode_10_pulses_35bits(cons
* MODE_67, 3 | 1-3, 4, 5-7, 8, 9-11
* MODE_74 or MODE_795, 4 | 1-3, 4-6, 7-9, 10, 11-13
*
- * @param fixed_vector pointer to the algebraic codebook vector
+ * @param fixed_sparse pointer to the algebraic codebook vector
* @param pulses algebraic codebook indexes
* @param mode mode of the current frame
* @param subframe current subframe number
*/
-static void decode_fixed_vector(float *fixed_vector, const uint16_t *pulses,
+static void decode_fixed_sparse(AMRFixed *fixed_sparse, const uint16_t *pulses,
const enum Mode mode, const int subframe)
{
assert(MODE_475 <= mode && mode <= MODE_122);
if (mode == MODE_122) {
- decode_10_pulses_35bits(pulses, fixed_vector);
+ decode_10_pulses_35bits(pulses, fixed_sparse);
} else if (mode == MODE_102) {
- decode_8_pulses_31bits(pulses, fixed_vector);
+ decode_8_pulses_31bits(pulses, fixed_sparse);
} else {
- int pulse_position[4], pulse_subset;
+ int *pulse_position = fixed_sparse->x;
+ int i, pulse_subset;
const int fixed_index = pulses[0];
if (mode <= MODE_515) {
pulse_subset = ((fixed_index >> 3) & 8) + (subframe << 1);
pulse_position[0] = ( fixed_index & 7) * 5 + track_position[pulse_subset];
pulse_position[1] = ((fixed_index >> 3) & 7) * 5 + track_position[pulse_subset + 1];
+ fixed_sparse->n = 2;
} else if (mode == MODE_59) {
pulse_subset = ((fixed_index & 1) << 1) + 1;
pulse_position[0] = ((fixed_index >> 1) & 7) * 5 + pulse_subset;
pulse_subset = (fixed_index >> 4) & 3;
pulse_position[1] = ((fixed_index >> 6) & 7) * 5 + pulse_subset + (pulse_subset == 3 ? 1 : 0);
+ fixed_sparse->n = pulse_position[0] == pulse_position[1] ? 1 : 2;
} else if (mode == MODE_67) {
pulse_position[0] = (fixed_index & 7) * 5;
pulse_subset = (fixed_index >> 2) & 2;
pulse_position[1] = ((fixed_index >> 4) & 7) * 5 + pulse_subset + 1;
pulse_subset = (fixed_index >> 6) & 2;
pulse_position[2] = ((fixed_index >> 8) & 7) * 5 + pulse_subset + 2;
+ fixed_sparse->n = 3;
} else { // mode <= MODE_795
pulse_position[0] = gray_decode[ fixed_index & 7] * 5;
pulse_position[1] = gray_decode[(fixed_index >> 3) & 7] * 5 + 1;
pulse_position[2] = gray_decode[(fixed_index >> 6) & 7] * 5 + 2;
pulse_subset = (fixed_index >> 9) & 1;
pulse_position[3] = gray_decode[(fixed_index >> 10) & 7] * 5 + pulse_subset + 3;
+ fixed_sparse->n = 4;
}
- reconstruct_fixed_vector(pulse_position, pulses[1],
- pulses_nb_per_mode[mode], fixed_vector);
+ for (i = 0; i < fixed_sparse->n; i++)
+ fixed_sparse->y[i] = (pulses[1] >> i) & 1 ? 1.0 : -1.0;
}
}
/**
- * Apply pitch lag to the fixed vector (section 6.1.2)
+ * Apply pitch lag to obtain the sharpened fixed vector (section 6.1.2)
*
* @param p the context
* @param subframe unpacked amr subframe
* @param mode mode of the current frame
- * @param fixed_vector vector to be modified
+ * @param in sparse representation of algebraic codebook vector
+ * @param out sharpened fixed vector
*/
static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode,
- float *fixed_vector)
+ const AMRFixed *in, float *out)
{
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)
@@ -644,10 +642,40 @@ static void pitch_sharpening(AMRContext
if (mode == MODE_122)
p->beta = FFMIN(p->pitch_gain[4], 1.0);
- // conduct pitch sharpening as appropriate (section 6.1.2)
- if (p->pitch_lag_int < AMR_SUBFRAME_SIZE)
- for (i = p->pitch_lag_int; i < AMR_SUBFRAME_SIZE; i++)
- fixed_vector[i] += p->beta * fixed_vector[i - p->pitch_lag_int];
+ memset(out, 0, sizeof(float) * AMR_SUBFRAME_SIZE);
+ if (p->pitch_lag_int >= AMR_SUBFRAME_SIZE) {
+ for (i = 0; i < in->n; i++) {
+ x = in->x[i];
+ y = in->y[i];
+ out[x] += y;
+ }
+ } else if (p->pitch_lag_int >= AMR_SUBFRAME_SIZE >> 1) {
+ for (i = 0; i < in->n; i++) {
+ x = in->x[i];
+ y = in->y[i];
+ out[x] += y;
+
+ x += p->pitch_lag_int;
+ if (x < AMR_SUBFRAME_SIZE)
+ out[x] += y * p->beta;
+ }
+ } else {
+ for (i = 0; i < in->n; i++) {
+ x = in->x[i];
+ y = in->y[i];
+ out[x] += y;
+
+ x += p->pitch_lag_int;
+ if (x < AMR_SUBFRAME_SIZE) {
+ y *= p->beta;
+ out[x] += y;
+
+ x += p->pitch_lag_int;
+ if (x < AMR_SUBFRAME_SIZE)
+ out[x] += y * p->beta;
+ }
+ }
+ }
// Save pitch sharpening factor for the next subframe
// MODE_475 only updates on the 2nd and 4th subframes - this follows from
@@ -1052,6 +1080,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
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
@@ -1076,7 +1105,7 @@ static int amrnb_decode_frame(AVCodecCon
decode_pitch_vector(p, amr_subframe, subframe);
- decode_fixed_vector(fixed_vector, amr_subframe->pulses,
+ decode_fixed_sparse(&fixed_sparse, amr_subframe->pulses,
p->cur_frame_mode, subframe);
// The fixed gain (section 6.1.3) depends on the fixed vector
@@ -1086,7 +1115,8 @@ 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_vector);
+ pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse,
+ fixed_vector);
set_fixed_gain(p, p->cur_frame_mode, fixed_gain_factor,
ff_energyf(fixed_vector, AMR_SUBFRAME_SIZE));
More information about the FFmpeg-soc
mailing list