[FFmpeg-soc] [soc]: r4804 - amr/amrnbfloatdec.c

cmcq subversion at mplayerhq.hu
Fri Jul 24 12:02:52 CEST 2009


Author: cmcq
Date: Fri Jul 24 12:02:51 2009
New Revision: 4804

Log:
Move out pitch sharpening to be with the other algebraic vector functions

Modified:
   amr/amrnbfloatdec.c

Modified: amr/amrnbfloatdec.c
==============================================================================
--- amr/amrnbfloatdec.c	Fri Jul 24 09:10:25 2009	(r4803)
+++ amr/amrnbfloatdec.c	Fri Jul 24 12:02:51 2009	(r4804)
@@ -686,6 +686,36 @@ static void decode_fixed_vector(float *f
     }
 }
 
+/**
+ * Apply pitch lag to the fixed vector (section 6.1.2)
+ *
+ * @param p the context
+ * @param amr_subframe unpacked amr subframe
+ * @param mode mode of the current frame
+ * @param fixed_vector algebraic codebook vector
+ */
+static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode)
+{
+    int i;
+
+    // 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 quantised pitch gain.
+    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++)
+            p->fixed_vector[i] += p->beta*p->fixed_vector[i-p->pitch_lag_int];
+
+    // 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 quantised.
+    if (mode != MODE_475 || subframe & 1)
+        p->beta = av_clipf(p->pitch_gain[4], 0.0, SHARP_MAX);
+}
+
 /// @}
 
 
@@ -764,23 +794,22 @@ static float fixed_gain_smooth(AMRContex
 }
 
 /**
- * Decode fixed and pitch gains, and apply pitch sharpening.
+ * Decode pitch gain and fixed gain factor (part of section 6.1.3).
  *
  * @param p the context
  * @param amr_subframe unpacked amr subframe
  * @param mode mode of the current frame
  * @param subframe current subframe number
+ * @param fixed_gain_factor decoded gain correction factor
  */
 static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe,
-                         const enum Mode mode, const int subframe)
+                         const enum Mode mode, const int subframe,
+                         float *fixed_gain_factor)
 {
-    float fixed_gain_factor; // fixed gain correction factor {^gamma_gc} for the current frame
-    int i;
-
     // decode pitch gain and fixed gain correction factor
     if (mode == MODE_122 || mode == MODE_795) {
         p->pitch_gain[4]  = qua_gain_pit [amr_subframe->p_gain];
-        fixed_gain_factor = qua_gain_code[amr_subframe->fixed_gain];
+        *fixed_gain_factor = qua_gain_code[amr_subframe->fixed_gain];
     } else {
         // gain index is only coded in subframes 0,2 for MODE_475
         const float *gains = mode >= MODE_67  ? gains_high[amr_subframe->p_gain] :
@@ -788,27 +817,21 @@ static void decode_gains(AMRContext *p, 
                                                 gains_MODE_475[(p->frame.subframe[subframe&2].p_gain << 1) + (subframe&1)];
 
         p->pitch_gain[4]  = gains[0];
-        fixed_gain_factor = gains[1];
+        *fixed_gain_factor = gains[1];
     }
+}
 
-    // Only 12.2kbit/s mode uses the current pitch gain for pitch sharpening.
-    // 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 quantised pitch gain.
-    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++)
-            p->fixed_vector[i] += p->beta*p->fixed_vector[i-p->pitch_lag_int];
-
-    // 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 quantised.
-    if (mode != MODE_475 || subframe & 1)
-        p->beta = av_clipf(p->pitch_gain[4], 0.0, SHARP_MAX);
-
+/**
+ * Calculate fixed gain (part of section 6.1.3)
+ *
+ * @param p the context
+ * @param mode mode of the current frame
+ * @param fixed_gain_factor gain correction factor
+ * @param fixed_vector algebraic codebook vector
+ */
+static void set_fixed_gain(AMRContext *p, const enum Mode mode,
+                           float fixed_gain_factor)
+{
     // ^g_c = g_c' * ^gamma_gc
     p->fixed_gain[4] = fixed_gain_factor
                      * fixed_gain_prediction(p->fixed_vector, p->prediction_error, mode);
@@ -1134,6 +1157,7 @@ static int amrnb_decode_frame(AVCodecCon
     float *buf_out = data;                   // pointer to the output data buffer
     int i, subframe;                         // counters
     enum Mode speech_mode = MODE_475;        // ???
+    float fixed_gain_factor;
     float exc_feedback[AMR_SUBFRAME_SIZE];
     float synth_fixed_gain;
 
@@ -1169,9 +1193,18 @@ static int amrnb_decode_frame(AVCodecCon
         decode_fixed_vector(p->fixed_vector, amr_subframe->pulses,
                             p->cur_frame_mode, subframe);
 
-/*** pre-processing ***/
+        // The fixed gain (section 6.1.3) depends on the fixed vector
+        // (section 6.1.2), but the fixed vector calculation uses
+        // pitch sharpening based on the on the pitch gain (section 6.1.3).
+        // So the correct order is: pitch gain, pitch sharpening, fixed gain.
+        decode_gains(p, amr_subframe, p->cur_frame_mode, subframe,
+                     &fixed_gain_factor);
 
-        decode_gains(p, amr_subframe, p->cur_frame_mode, subframe);
+        pitch_sharpening(p, subframe, p->cur_frame_mode);
+
+        set_fixed_gain(p, p->cur_frame_mode, fixed_gain_factor);
+
+/*** pre-processing ***/
 
         // The excitation feedback is calculated without any processing such
         // as fixed gain smoothing. This isn't mentioned in the specification.


More information about the FFmpeg-soc mailing list