[FFmpeg-soc] [soc]: r1401 - in amr: amrnbfloatdata.h amrnbfloatdec.c

superdump subversion at mplayerhq.hu
Wed Oct 10 13:02:21 CEST 2007


Author: superdump
Date: Wed Oct 10 13:02:21 2007
New Revision: 1401

Log:
- Pitch lag and pitch vector decoding functions


Modified:
   amr/amrnbfloatdata.h
   amr/amrnbfloatdec.c

Modified: amr/amrnbfloatdata.h
==============================================================================
--- amr/amrnbfloatdata.h	(original)
+++ amr/amrnbfloatdata.h	Wed Oct 10 13:02:21 2007
@@ -29,7 +29,8 @@
 #include <math.h>
 
 // general definitions
-#define AMR_BLOCK_SIZE 160
+#define AMR_BLOCK_SIZE    160
+#define AMR_SUBFRAME_SIZE 40
 
 // definition of modes for decoder
 #define NO_DATA 15
@@ -1774,5 +1775,36 @@ static const float pred_fac[LP_FILTER_OR
 #define PRED_FAC_MODE_122 0.65
 #define FREQ_LSP_FAC 2*M_PI/8000.0
 
+// pitch tables
+
+#define PITCH_LAG_MAX            143
+#define PITCH_LAG_MIN             20
+#define PITCH_LAG_MIN_MODE_122    18
+
+// b60 hamming windowed sinc function coefficients
+static const float b60[61] = {
+0.898529   , 0.865051   , 0.769257   , 0.624054   , 0.448639   , 0.265289   , 0.0959167  , 0.0412598  ,
+0.134338   , 0.178986   , 0.178528   , 0.142609   , 0.0849304  , 0.0205078  , 0.0369568  , 0.0773926  ,
+0.0955200  , 0.0912781  , 0.0689392  , 0.0357056  , 0.000000   , 0.0305481  , 0.0504150  , 0.0570068  ,
+0.0508423  , 0.0350037  , 0.0141602  , 0.00665283 , 0.0230713  , 0.0323486  , 0.0335388  , 0.0275879  ,
+0.0167847  , 0.00411987 , 0.00747681 , 0.0156860  , 0.0193481  , 0.0183716  , 0.0137634  , 0.00704956 ,
+0.000000   , 0.00582886 , 0.00939941 , 0.0103760  , 0.00903320 , 0.00604248 , 0.00238037 , 0.00109863 ,
+0.00366211 , 0.00497437 , 0.00503540 , 0.00402832 , 0.00241089 , 0.000579834, 0.00103760 , 0.00222778 ,
+0.00277710 , 0.00271606 , 0.00213623 , 0.00115967 , 0.000000   ,
+};
+
+static const float qua_gain_pit[16] = {
+0.0             , 0.20001220703125, 0.400146484375  , 0.5             ,
+0.5999755859375 , 0.70001220703125, 0.75            , 0.79998779296875,
+0.8499755859375 , 0.9000244140625 , 0.95001220703125, 1.0             ,
+1.04998779296875, 1.0999755859375 , 1.1500244140625 , 1.20001220703125,
+};
+
+static const float qua_gain_pit_MODE_122[16] = {
+0.0           , 0.199951171875, 0.400146484375, 0.5           ,
+0.599853515625, 0.699951171875, 0.75          , 0.7998046875  ,
+0.849853515625, 0.89990234375 , 0.949951171875, 1.0           ,
+1.0498046875  , 1.099853515625, 1.14990234375 , 1.199951171875,
+};
 
 /**************************** end of tables *****************************/

Modified: amr/amrnbfloatdec.c
==============================================================================
--- amr/amrnbfloatdec.c	(original)
+++ amr/amrnbfloatdec.c	Wed Oct 10 13:02:21 2007
@@ -43,6 +43,7 @@ typedef struct AMRContext {
 
     int16_t                       *amr_prms; ///< pointer to the decoded amr parameters (lsf coefficients, codebook indices, etc)
     int                 bad_frame_indicator; ///< bad frame ? 1 : 0
+    int                      cur_frame_mode; ///< current frame mode
 
     float       prev_lsf_r[LP_FILTER_ORDER];
     float           lsp[4][LP_FILTER_ORDER]; ///< lsp vectors from current frame
@@ -50,6 +51,13 @@ typedef struct AMRContext {
 
     float           lpc[4][LP_FILTER_ORDER]; ///< vectors of lpc coefficients for 4 subframes
 
+    int                       pitch_lag_int; ///< integer part of pitch lag from current subframe
+    int                      pitch_lag_frac; ///< fractional part of pitch lag from current subframe
+    int                  prev_pitch_lag_int; ///< integer part of pitch lag from previous subframe
+
+    float prev_excitation[PITCH_LAG_MAX + LP_FILTER_ORDER + 1]; ///< buffer of the past excitation vector
+    float                      pitch_vector[AMR_SUBFRAME_SIZE]; ///< adaptive code book (pitch) vector
+
 } AMRContext;
 
 
@@ -394,12 +402,148 @@ static void lsp2lpc(float *lsp, float *l
 /*** end of LPC coefficient decoding functions ***/
 
 
+/*** pitch vector decoding functions ***/
+
+/**
+ * Decode the adaptive codebook index to the integer and fractional parts of the
+ * pitch lag for one subframe at 1/3 resolution
+ *
+ * @param p                   pointer to the AMRContext
+ * @param pitch_index         parsed adaptive codebook (pitch) index
+ *
+ * @return void
+ */
+
+static void decode_pitch_lag_3(AMRContext *p, int pitch_index) {
+    // subframe 1 or 3
+    if(p->cur_subframe & 1) {
+        if(pitch_index < 197) {
+            // 10923>>15 is approximately 1/3
+            p->pitch_lag_int = ( ((pitch_index + 2)*10923)>>15 ) + 19;
+            p->pitch_lag_frac = pitch_index - p->pitch_lag_int*3 + 58;
+        }else {
+            p->pitch_lag_int = pitch_index - 112;
+            p->pitch_lag_frac = 0;
+        }
+    // subframe 2 or 4
+    }else {
+        if( (p->cur_frame_mode == MODE_475) || (p->cur_frame_mode == MODE_515) ||
+            (p->cur_frame_mode == MODE_59)  || (p->cur_frame_mode == MODE_67) ) {
+            // decoding with 4 bit resolution
+            int t1_temp = clip(p->prev_pitch_lag_int, p->search_range_max-4, p->search_range_min+5);
+
+            if(pitch_index < 4) {
+                // integer only precision for [t1_temp-5, t1_temp-2]
+                p->pitch_lag_int = pitch_index + (t1_temp - 5);
+                p->pitch_lag_frac = 0;
+            }else if(pitch_index < 12) {
+                // 1/3 fractional precision for [t1_temp-1 2/3, t1_temp+2/3]
+                p->pitch_lag_int = ( ((pitch_index - 5)*10923)>>15 ) + t1_temp - 1;
+                p->pitch_lag_frac = pitch_index - p->pitch_lag_int*3 - 9;
+            }else {
+                // integer only precision for [t1_temp+1, t1_temp+4]
+                pitch_lag_int = pitch_index + t1_temp - 11;
+                pitch_lag_frac = 0;
+            }
+        }else {
+            // decoding with 5 or 6 bit resolution, 1/3 fractional precision
+            // 10923>>15 is approximately 1/3
+            int temp = ( ((pitch_index + 2)*10923)>>15 ) - 1;
+            p->pitch_lag_int = temp + p->search_range_min;
+            p->pitch_lag_frac = pitch_index - temp*3 - 2;
+        }
+    }
+}
+
+/**
+ * Decode the adaptive codebook index to the integer and fractional parts of the
+ * pitch lag for one subframe at 1/6 resolution
+ *
+ * @param p                   pointer to the AMRContext
+ * @param pitch_index         parsed adaptive codebook (pitch) index
+ *
+ * @return void
+ */
+
+static void decode_pitch_lag_6(AMRContext *p, int pitch_index) {
+    // subframe 1 or 3
+    if(p->cur_subframe & 1) {
+        if(pitch_index < 463){
+            p->pitch_lag_int = (pitch_index + 5)/6 + 17;
+            p->pitch_lag_frac = pitch_index - p->pitch_lag_int*6 + 105;
+        }else {
+            p->pitch_lag_int = pitch_index - 368;
+            p->pitch_lag_frac = 0;
+        }
+    // subframe 2 or 4
+    }else {
+        int temp;
+        // find the search range
+        p->search_range_min = FFMAX(p->pitch_lag_int - 5, PITCH_LAG_MIN_MODE_122);
+        p->search_range_max = p->search_range_min + 9;
+        if(p->search_range_max > PITCH_LAG_MAX) {
+            p->search_range_max = PITCH_LAG_MAX;
+            p->search_range_min = p->search_range_max - 9;
+        }
+        // calculate the pitch lag
+        temp = (pitch_index + 5)/6 - 1;
+        p->pitch_lag_int = temp + p->search_range_min;
+        p->pitch_lag_frac = pitch_index - temp*6 - 3;
+    }
+}
+
+/**
+ * Calculate the pitch vector by interpolating the past excitation at the pitch
+ * pitch lag using a b60 hamming windowed sinc function
+ *
+ * @param p                   pointer to the AMRContext
+ * @param lag_int             integer part of pitch lag
+ * @param lag_frac            fractional part of pitch lag
+ *
+ * @return void
+ */
+
+static void interp_pitch_vector(AMRContext *p, int lag_int, int lag_frac) {
+    int n, i;
+    float *b60_idx1, *b60_idx2, *exc_idx;
+
+    lag_frac *= -1;
+    if(p->cur_frame_mode != MODE_122) {
+        lag_frac <<= 1;
+    }
+
+    if(lag_frac < 0) {
+        lag_frac += 6;
+        lag_int--;
+    }
+
+    b60_idx1 = &b60[    lag_frac];
+    b60_idx2 = &b60[6 - lag_frac];
+    exc_idx = &p->prev_excitation[-lag_int];
+
+    for(n=0; n<AMR_SUBFRAME_SIZE; n++) {
+        for(i=0; i<10; i++) {
+            p->pitch_vector[n] += b60_idx1[6*i] * exc_idx[-i];
+        }
+        exc_idx++;
+        for(i=0; i<10; i++) {
+            p->pitch_vector[n] += b60_idx2[6*i] * exc_idx[ i];
+        }
+        exc_idx++;
+    }
+}
+
+/*** end of pitch vector decoding functions ***/
+
+
 static int amrnb_decode_frame(AVCodecContext *avctx,
         void *data, int *data_size, uint8_t *buf, int buf_size) {
 
     AMRContext *p = avctx->priv_data;        // pointer to private data
     int16_t *buf_out = data;                 // pointer to the output data buffer
-    int i;                                   // counter
+    int i, subframe;                         // counters
+    int index = 0;                           // index counter (different modes
+                                             // advance through amr_prms differently)
     enum Mode speech_mode = MODE_475;        // ???
 
     // decode the bitstream to amr parameters
@@ -412,11 +556,15 @@ static int amrnb_decode_frame(AVCodecCon
         lsf2lsp_5(p);
         // interpolate LSP vectors at subframes 1 and 3
         interp_lsp_13(p);
+        // advance index into amr_prms
+        index += 5;
     }else {
         // decode split-matrix quantised lsf vector indices to an lsp vector
         lsf2lsp_3(p);
         // interpolate LSP vectors at subframes 1, 2 and 3
         interp_lsp_123(p);
+        // advance index into amr_prms
+        index += 3;
     }
 
     // convert LSP vectors to LPC coefficient vectors
@@ -426,6 +574,26 @@ static int amrnb_decode_frame(AVCodecCon
 
 /*** end of LPC coefficient decoding ***/
 
+    for(subframe = 0; subframe < 5; subframe++) {
+
+/*** adaptive code book (pitch) vector decoding ***/
+
+        // decode integer and fractional parts of pitch lag from parsed pitch
+        // index
+        if(p->cur_frame_mode == MODE_122) {
+            decode_pitch_lag_6(p, p->amr_prms[index]);
+        }else {
+            decode_pitch_lag_3(p, p->amr_prms[index]);
+        }
+
+        // interpolate the past excitation at the pitch lag to obtain the pitch
+        // vector
+        interp_pitch_vector(p, p->pitch_lag_int, p->pitch_lag_frac);
+
+/*** end of adaptive code book (pitch) vector decoding ***/
+
+    }
+
     /* Report how many samples we got */
     *data_size = buf_size;
 



More information about the FFmpeg-soc mailing list