⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sp_enc.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Returns:
 *    void
 */
static void Reorder_lsf( Float32 *lsf, Float32 min_dist )
{
   Float32 lsf_min;
   Word32 i;


   lsf_min = min_dist;

   for ( i = 0; i < M; i++ ) {
      if ( lsf[i] < lsf_min ) {
         lsf[i] = lsf_min;
      }
      lsf_min = lsf[i] + min_dist;
   }
}


/*
 * Lsf_lsp
 *
 *
 * Parameters:
 *    lsf               I: vector of LSFs
 *    lsp	            O: vector of LSPs
 *
 * Function:
 *    Transformation lsf to lsp, order M
 *
 * Returns:
 *    void
 */
static void Lsf_lsp( Float32 lsf[], Float32 lsp[] )
{
   Word32 i;


   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( Float32 )cos( SCALE_FREQ_LSP * lsf[i] );
   }
   return;
}


/*
 * Vq_subvec3
 *
 *
 * Parameters:
 *    lsf_r1            I: 1st LSF residual vector
 *    dico              I: quantization codebook
 *    wf1               I: 1st LSF weighting factors
 *    dico_size         I: size of quantization codebook
 *    use_half          I: use every second entry in codebook
 *
 * Function:
 *    Quantization of a 3 dimensional subvector
 *
 * Returns:
 *    index             quantization index
 */
static Word16 Vq_subvec3( Float32 *lsf_r1, const Float32 *dico, Float32 *wf1,
      Word16 dico_size, Word32 use_half )
{
   Float64 dist, dist_min;
   Float32 temp;
   const Float32 *p_dico;
   Word32 i, index = 0;


   dist_min = FLT_MAX;
   p_dico = dico;

   if ( use_half == 0 ) {
      for ( i = 0; i < dico_size; i++ ) {
         temp = lsf_r1[0] - *p_dico++;
         temp *= wf1[0];
         dist = temp * temp;
         temp = lsf_r1[1] - *p_dico++;
         temp *= wf1[1];
         dist += temp * temp;
         temp = lsf_r1[2] - *p_dico++;
         temp *= wf1[2];
         dist += temp * temp;

         if ( dist < dist_min ) {
            dist_min = dist;
            index = i;
         }
      }
      p_dico = &dico[( 3 * index )];
   }
   else {
      for ( i = 0; i < dico_size; i++ ) {
         temp = lsf_r1[0] - *p_dico++;
         temp *= wf1[0];
         dist = temp * temp;
         temp = lsf_r1[1] - *p_dico++;
         temp *= wf1[1];
         dist += temp * temp;
         temp = lsf_r1[2] - *p_dico++;
         temp *= wf1[2];
         dist += temp * temp;

         if ( dist < dist_min ) {
            dist_min = dist;
            index = i;
         }
         p_dico = p_dico + 3;
      }
      p_dico = &dico[6 * index];
   }

   /* Reading the selected vector */
   lsf_r1[0] = *p_dico++;
   lsf_r1[1] = *p_dico++;
   lsf_r1[2] = *p_dico++;
   return( Word16 )index;
}


/*
 * Vq_subvec4
 *
 *
 * Parameters:
 *    lsf_r1            I: 1st LSF residual vector
 *    dico              I: quantization codebook
 *    wf1               I: 1st LSF weighting factors
 *    dico_size         I: size of quantization codebook
 *
 * Function:
 *    Quantization of a 4 dimensional subvector
 *
 * Returns:
 *    index             quantization index
 */
static Word16 Vq_subvec4( Float32 *lsf_r1, const Float32 *dico, Float32 *wf1,
      Word16 dico_size )
{
   Float64 dist, dist_min;
   Float32 temp;
   const Float32 *p_dico;
   Word32 i, index = 0;


   dist_min = FLT_MAX;
   p_dico = dico;

   for ( i = 0; i < dico_size; i++ ) {
      temp = lsf_r1[0] - *p_dico++;
      temp *= wf1[0];
      dist = temp * temp;
      temp = lsf_r1[1] - *p_dico++;
      temp *= wf1[1];
      dist += temp * temp;
      temp = lsf_r1[2] - *p_dico++;
      temp *= wf1[2];
      dist += temp * temp;
      temp = lsf_r1[3] - *p_dico++;
      temp *= wf1[3];
      dist += temp * temp;

      if ( dist < dist_min ) {
         dist_min = dist;
         index = i;
      }
   }

   /* Reading the selected vector */
   p_dico = &dico[index << 2];
   lsf_r1[0] = *p_dico++;
   lsf_r1[1] = *p_dico++;
   lsf_r1[2] = *p_dico++;
   lsf_r1[3] = *p_dico++;
   return( Word16 )index;
}


/*
 * Q_plsf_3
 *
 *
 * Parameters:
 *    mode              I: AMR mode
 *    past_rq           B: past quantized residual
 *    lsp1              I: 1st LSP vector
 *    lsp1_q            O: quantized 1st LSP vector
 *    indice            I: quantization indices of 5 matrices and
 *                         one sign for 3rd
 *    pred_init_i       O: init index for MA prediction in DTX mode
 *
 * Function:
 *    Quantization of LSF parameters with 1st order MA prediction and
 *    split by 3 vector quantization (split-VQ)
 *
 * Returns:
 *    void
 */
static void Q_plsf_3( enum Mode mode, Float32 *past_rq, Float32 *lsp1, Float32 *
      lsp1_q, Word16 *indice, Word32 *pred_init_i )
{
   Float32 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
   Float32 lsf1_q[M];
   Float32 pred_init_err;
   Float32 min_pred_init_err;
   Float32 temp_r1[M];
   Float32 temp_p[M];
   Word32 j, i;


   /* convert LSFs to normalize frequency domain */
   Lsp_lsf( lsp1, lsf1 );

   /* compute LSF weighting factors */
   Lsf_wt( lsf1, wf1 );

   /* Compute predicted LSF and prediction error */
   if ( mode != MRDTX ) {
      for ( i = 0; i < M; i++ ) {
         lsf_p[i] = mean_lsf_3[i] + past_rq[i] * pred_fac[i];
         lsf_r1[i] = lsf1[i] - lsf_p[i];
      }
   }
   else {
      /*
       * DTX mode, search the init vector that yields
       * lowest prediction resuidual energy
       */
      *pred_init_i = 0;
      min_pred_init_err = FLT_MAX;

      for ( j = 0; j < PAST_RQ_INIT_SIZE; j++ ) {
         pred_init_err = 0;

         for ( i = 0; i < M; i++ ) {
            temp_p[i] = mean_lsf_3[i] + past_rq_init[j * M + i];
            temp_r1[i] = lsf1[i] - temp_p[i];
            pred_init_err += temp_r1[i] * temp_r1[i];
         }   /* next i */

         if ( pred_init_err < min_pred_init_err ) {
            min_pred_init_err = pred_init_err;
            memcpy( lsf_r1, temp_r1, M <<2 );
            memcpy( lsf_p, temp_p, M <<2 );
            memcpy( past_rq, &past_rq_init[j * M], M <<2 );
            *pred_init_i = j;
         }
      }
   }

   /* Split-VQ of prediction error */
   /* MR475, MR515 */
   if ( ( mode == MR475 ) || ( mode == MR515 ) ) {
      indice[0] = Vq_subvec3( &lsf_r1[0], dico1_lsf_3, &wf1[0], DICO1_SIZE_3, 0
            );
      indice[1] = Vq_subvec3( &lsf_r1[3], dico2_lsf_3, &wf1[3], DICO2_SIZE_3 /2,
            1 );
      indice[2] = Vq_subvec4( &lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE );
   }

   /* MR795 */
   else if ( mode == MR795 ) {
      indice[0] = Vq_subvec3( &lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0
            );
      indice[1] = Vq_subvec3( &lsf_r1[3], dico2_lsf_3, &wf1[3], DICO2_SIZE_3, 0
            );
      indice[2] = Vq_subvec4( &lsf_r1[6], dico3_lsf_3, &wf1[6], DICO3_SIZE_3 );
   }

   /* MR59, MR67, MR74, MR102 , MRDTX */
   else {
      indice[0] = Vq_subvec3( &lsf_r1[0], dico1_lsf_3, &wf1[0], DICO1_SIZE_3, 0
            );
      indice[1] = Vq_subvec3( &lsf_r1[3], dico2_lsf_3, &wf1[3], DICO2_SIZE_3, 0
            );
      indice[2] = Vq_subvec4( &lsf_r1[6], dico3_lsf_3, &wf1[6], DICO3_SIZE_3 );
   }

   /* Compute quantized LSFs and update the past quantized residual */
   for ( i = 0; i < M; i++ ) {
      lsf1_q[i] = lsf_r1[i] + lsf_p[i];
      past_rq[i] = lsf_r1[i];
   }

   /* verification that LSFs has mimimum distance of LSF_GAP 50 Hz */
   Reorder_lsf( lsf1_q, 50.0F );

   /*  convert LSFs to the cosine domain */
   Lsf_lsp( lsf1_q, lsp1_q );
}


/*
 * Q_plsf_5
 *
 *
 * Parameters:
 *    past_rq           B: past quantized residual
 *    lsp1              I: 1st LSP vector
 *    lsp2              I: 2nd LSP vector
 *    lsp1_q            O: quantized 1st LSP vector
 *    lsp2_q            O: quantized 2nd LSP vector
 *    indice	         I: quantization indices of 5 matrices and
 *                         one sign for 3rd
 *
 * Function:
 *    Quantization of 2 sets of LSF parameters using 1st order MA
 *    prediction and split by 5 matrix quantization (split-MQ).
 *
 * Returns:
 *    void
 */
static void Q_plsf_5( Float32 *past_rq, Float32 *lsp1, Float32 *lsp2, Float32 *
      lsp1_q, Float32 *lsp2_q, Word16 *indice )
{
   Float32 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M];
   Float32 lsf1_q[M], lsf2_q[M];
   Word32 i;


   /* convert LSFs to normalize frequency domain */
   Lsp_lsf( lsp1, lsf1 );
   Lsp_lsf( lsp2, lsf2 );

   /* Compute LSF weighting factors */
   Lsf_wt( lsf1, wf1 );
   Lsf_wt( lsf2, wf2 );

   /* Compute predicted LSF and prediction error */
   for ( i = 0; i < M; i++ ) {
      /* MR122 LSP prediction factor = 0.65 */
      lsf_p[i] = mean_lsf_5[i] + past_rq[i] * 0.65F;
      lsf_r1[i] = lsf1[i] - lsf_p[i];
      lsf_r2[i] = lsf2[i] - lsf_p[i];
   }

   /* Split-MQ of prediction error */
   indice[0] = Vq_subvec( &lsf_r1[0], &lsf_r2[0], dico1_lsf_5, &wf1[0], &wf2[0],
         DICO1_SIZE_5 );
   indice[1] = Vq_subvec( &lsf_r1[2], &lsf_r2[2], dico2_lsf_5, &wf1[2], &wf2[2],
         DICO2_SIZE_5 );
   indice[2] = Vq_subvec_s( &lsf_r1[4], &lsf_r2[4], dico3_lsf_5, &wf1[4], &wf2[4
         ], DICO3_SIZE_5 );
   indice[3] = Vq_subvec( &lsf_r1[6], &lsf_r2[6], dico4_lsf_5, &wf1[6], &wf2[6],
         DICO4_SIZE_5 );
   indice[4] = Vq_subvec( &lsf_r1[8], &lsf_r2[8], dico5_lsf_5, &wf1[8], &wf2[8],
         DICO5_SIZE_5 );

   /* Compute quantized LSFs and update the past quantized residual */
   for ( i = 0; i < M; i++ ) {
      lsf1_q[i] = lsf_r1[i] + lsf_p[i];
      lsf2_q[i] = lsf_r2[i] + lsf_p[i];
      past_rq[i] = lsf_r2[i];
   }

   /* verification that LSFs has minimum distance of LSF_GAP 50hz */
   Reorder_lsf( lsf1_q, 50.0F );
   Reorder_lsf( lsf2_q, 50.0F );

   /*  convert LSFs to the cosine domain */
   Lsf_lsp( lsf1_q, lsp1_q );
   Lsf_lsp( lsf2_q, lsp2_q );
}


/*
 * Int_lpc_1and3
 *
 *
 * Parameters:
 *    lsp_old        I: LSP vector at the 4th subfr. of past frame      [M]
 *    lsp_mid        I: LSP vector at the 2nd subframe of present frame [M]
 *    lsp_new        I: LSP vector at the 4th subframe of present frame [M]
 *    az             O: interpolated LP parameters in subframes 1 and 3
 *                                                                [AZ_SIZE]
 *
 * Function:
 *    Interpolates the LSPs and converts to LPC parameters
 *    to get a different LP filter in each subframe.
 *
 *    The 20 ms speech frame is divided into 4 subframes.
 *    The LSPs are quantized and transmitted at the 2nd and
 *    4th subframes (twice per frame) and interpolated at the
 *    1st and 3rd subframe.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1and3( Float32 lsp_old[], Float32 lsp_mid[], Float32 lsp_new
      [], Float32 az[] )
{
   Word32 i;
   Float32 lsp[M];


   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( lsp_mid[i] + lsp_old[i] ) * 0.5F;
   }

   /* Subframe 1 */
   Lsp_Az( lsp, az );
   az += MP1;

   /* Subframe 2 */
   Lsp_Az( lsp_mid, az );
   az += MP1;

   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( lsp_mid[i] + lsp_new[i] ) * 0.5F;
   }

   /* Subframe 3 */
   Lsp_Az( lsp, az );
   az += MP1;

   /* Subframe 4 */
   Lsp_Az( lsp_new, az );
   return;
}


/*
 * Int_lpc_1to3_2
 *
 *
 * Parameters:
 *    lsp_old           I: LSP vector at the 4th subfr. of past frame      [M]
 *    lsp_new           I: LSP vector at the 4th subframe of present frame [M]
 *    az                O: interpolated LP parameters in subframes 1, 2 and 3
 *                                                                   [AZ_SIZE]
 *
 * Function:
 *    Interpolation of the LPC parameters.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1to3_2( Float32 lsp_old[], Float32 lsp_new[], Float32 az[] )
{
   Float32 lsp[M];
   Word32 i;


   for ( i = 0; i < M; i += 2 ) {
      lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
      lsp[i + 1] = lsp_new[i + 1] *0.25F + lsp_old[i + 1] *0.75F;
   }

   /* Subframe 1 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i += 2 ) {
      lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
      lsp[i + 1] = ( lsp_old[i + 1] +lsp_new[i+1] )*0.5F;
   }

   /* Subframe 2 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i += 2 ) {
      lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
      lsp[i + 1] = lsp_old[i + 1] *0.25F + lsp_new[i + 1] *0.75F;
   }

   /* Subframe 3 */
   Lsp_Az( lsp, az );
   return;
}


/*
 * Int_lpc_1to3
 *
 *
 * Parameters:
 *    lsp_old           I: LSP vector at the 4th subfr. of past frame      [M]
 *    lsp_new           I: LSP vector at the 4th subframe of present frame [M]
 *    az                O: interpolated LP parameters in all subframes
 *                                                                   [AZ_SIZE]
 *
 * Function:
 *    Interpolates the LSPs and converts to LPC parameters to get a different
 *    LP filter in each subframe.
 *
 *    The 20 ms speech frame is divided into 4 subframes.
 *    The LSPs are quantized and transmitted at the 4th
 *    subframes (once per frame) and interpolated at the
 *    1st, 2nd and 3rd subframe.
 *
 * Returns:
 *    void
 */
static void Int_lpc_1to3( Float32 lsp_old[], Float32 lsp_new[], Float32 az[] )
{
   Float32 lsp[M];
   Word32 i;


   for ( i = 0; i < M; i++ ) {
      lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
   }

   /* Subframe 1 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i++ ) {
      lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
   }

   /* Subframe 2 */
   Lsp_Az( lsp, az );
   az += MP1;

   for ( i = 0; i < M; i++ ) {
      lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
   }

   /* Subframe 3 */
   Lsp_Az( lsp, az );
   az += MP1;

   /* Subframe 4 */
   Lsp_Az( lsp_new, az );
   return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -