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

📄 enc_dtx.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
   if(st->mem_log_en_index < 0)
   {
      st->mem_log_en_index = 0;
   }

   E_DTX_isf_q(isf, pt_prms);
   (*pt_prms) += 5;

   **pt_prms = st->mem_log_en_index;
   (*pt_prms) += 1;

   CN_dith = E_DTX_dithering_control(st);

   **pt_prms = CN_dith;
   (*pt_prms) += 1;

   /* adjust level to speech coder mode */

   log_en = (Float32)((Float32)st->mem_log_en_index / 2.625 - 2.0);
   level = (Float32)(pow( 2.0, log_en ));

   /* generate white noise vector */

   for (i = 0; i < L_FRAME; i++)
   {
      exc2[i] = (Float32)E_UTIL_random(&(st->mem_cng_seed));
   }

   ener = 0.01F;

   for (i = 0; i < L_FRAME; i++)
   {
      ener += exc2[i] * exc2[i];
   }

   gain = (Float32)sqrt(level * L_FRAME / ener);

   for (i = 0; i < L_FRAME; i++)
   {
      exc2[i] *= gain;
   }

   return;
}

/*
 * E_DTX_reset
 *
 * Parameters:
 *    st             O: state struct
 *
 * Function:
 *    Initializes state memory
 *
 * Returns:
 *    non-zero with error, zero for ok
 */
Word32 E_DTX_reset(E_DTX_State *st)
{
   Word32 i;

   if (st == (E_DTX_State *) NULL)
   {
      return -1;
   }

   st->mem_hist_ptr = 0;
   st->mem_log_en_index = 0;

   /* Init isf_hist[] */
   for(i = 0; i < DTX_HIST_SIZE; i++)
   {
      memcpy(&st->mem_isf[i * M], E_ROM_isf, M * sizeof(Float32));
   }

   st->mem_cng_seed = RANDOM_INITSEED;

   /* Reset energy history */
   memset(st->mem_log_en, 0, DTX_HIST_SIZE * sizeof(Float32));

   st->mem_dtx_hangover_count = DTX_HANG_CONST;
   st->mem_dec_ana_elapsed_count = DTX_ELAPSED_FRAMES_THRESH;

   memset(st->mem_distance, 0, 28 * sizeof(Float32));
   memset(st->mem_distance_sum, 0, (DTX_HIST_SIZE - 1) * sizeof(Float32));

   return 0;
}

/*
 * E_DTX_init
 *
 * Parameters:
 *    st           I/O: state struct
 *
 * Function:
 *    Allocates state memory and initializes state memory
 *
 * Returns:
 *    non-zero with error, zero for ok
 */
Word32 E_DTX_init (E_DTX_State **st)
{
   E_DTX_State* s;

   if (st == (E_DTX_State **) NULL)
   {
      return -1;
   }

   *st = NULL;

   /* allocate memory */
   if ((s= (E_DTX_State *) malloc(sizeof(E_DTX_State))) == NULL)
   {
      return -1;
   }

   E_DTX_reset(s);
   *st = s;

   return 0;
}

/*
 * E_DTX_exit
 *
 * Parameters:
 *    state        I/0: State struct
 *
 * Function:
 *    The memory used for state memory is freed
 *
 * Returns:
 *    void
 */
void E_DTX_exit (E_DTX_State **st)
{
   if (st == NULL || *st == NULL)
   {
      return;
   }

   /* deallocate memory */
   free(*st);
   *st = NULL;

   return;
}


/*
 * E_DTX_tx_handler
 *
 * Parameters:
 *    st           I/O: State struct
 *    vad_flag       I: vad decision
 *    usedMode     I/O: mode changed or not
 *
 * Function:
 *    Adds extra speech hangover to analyze speech on the decoding side.
 *
 * Returns:
 *    void
 */
void E_DTX_tx_handler(E_DTX_State *st, Word32 vad_flag, Word16 *usedMode)
{

   /* this state machine is in synch with the GSMEFR txDtx machine */
   st->mem_dec_ana_elapsed_count++;

   if (vad_flag != 0)
   {
      st->mem_dtx_hangover_count = DTX_HANG_CONST;
   }
   else
   {  /* non-speech */
      if (st->mem_dtx_hangover_count == 0)
      {  /* out of decoder analysis hangover  */
         st->mem_dec_ana_elapsed_count = 0;
         *usedMode = MRDTX;
      }
      else
      { /* in possible analysis hangover */
         st->mem_dtx_hangover_count--;

         /* decAnaElapsedCount + dtxHangoverCount < E_DTX_ELAPSED_FRAMES_THRESH */
         if ((st->mem_dec_ana_elapsed_count + st->mem_dtx_hangover_count)
            < DTX_ELAPSED_FRAMES_THRESH)
         {
            *usedMode = MRDTX;
            /* if Word16 time since decoder update, do not add extra HO */
         }
         /*
         else
         override VAD and stay in
         speech mode *usedMode
         and add extra hangover
         */
      }
   }

   return;
}

/*
 * E_DTX_filter5
 *
 * Parameters:
 *    in0         I/O: input values / output low-pass part
 *    in1         I/O: input values / output high-pass part
 *    data        I/O: updated filter memory
 *
 * Function:
 *    Fifth-order half-band lowpass/highpass filter pair with decimation.
 *
 * Returns:
 *    void
 */
static void E_DTX_filter5(Float32 *in0, Float32 *in1,  Float32 data[])
{
   Float32 temp0, temp1, temp2;

   temp0 = *in0 - COEFF5_1 * data[0];
   temp1 = data[0] + COEFF5_1 * temp0;
   data[0] = ((temp0 > 1e-10) | (temp0 < -1e-10)) ? temp0 : 0;

   temp0 = *in1 - COEFF5_2 * data[1];
   temp2 = data[1] + COEFF5_2 * temp0;
   data[1] = ((temp0 > 1e-10) | (temp0 < -1e-10)) ? temp0 : 0;

   *in0 = (temp1 + temp2) * 0.5F;
   *in1 = (temp1 - temp2) * 0.5F;
}

/*
 * E_DTX_filter3
 *
 * Parameters:
 *    in0         I/O: input values / output low-pass part
 *    in1         I/O: input values / output high-pass part
 *    data        I/O: updated filter memory
 *
 * Function:
 *    Third-order half-band lowpass/highpass filter pair with decimation.
 *
 * Returns:
 *    void
 */
static void E_DTX_filter3(Float32 *in0, Float32 *in1, Float32 *data)
{
   Float32 temp1, temp2;

   temp1 = *in1 - COEFF3 * *data;
   temp2 = *data + COEFF3 * temp1;
   *data = ((temp1 > 1e-10) | (temp1 < -1e-10)) ? temp1 : 0;

   *in1 = (*in0 - temp2) * 0.5F;
   *in0 = (*in0 + temp2) * 0.5F;
}

/*
 * E_DTX_level_calculation
 *
 * Parameters:
 *    data          I: signal buffer
 *    sub_level   I/0: level calculated at the end of the previous frame /
 *                     level of signal calculated from the last
 *                     (count2 - count1) samples
 *    count1        I: number of samples to be counted
 *    count2        I: number of samples to be counted
 *    ind_m         I: step size for the index of the data buffer
 *    ind_a         I: starting index of the data buffer
 *    scale         I: scaling for the level calculation
 *
 * Function:
 *    Calculate signal level in a sub-band. Level is calculated
 *    by summing absolute values of the input data.
 *
 *    Because speech coder has a lookahead, signal level calculated
 *    over the lookahead (data[count1 - count2]) is stored (*sub_level)
 *    and added to the level of the next frame. Additionally, group
 *    delay and decimation of the filter bank is taken into the count
 *    for the values of the counters (count1, count2).
 *
 * Returns:
 *    signal level
 */
static Float32 E_DTX_level_calculation(Float32 data[], Float32 *sub_level,
                                       Word16 count1, Word16 count2,
                                       Word16 ind_m, Word16 ind_a,
                                       Float32 scale)
{
  Float64 l_temp1, l_temp2;
  Float32 level;
  Word32 i;

  l_temp1 = 0.0;

  for (i = count1; i < count2; i++)
  {
     l_temp1 += fabs(data[ind_m * i + ind_a]);
  }

  l_temp1 *= 2.0;
  l_temp2 = l_temp1 + *sub_level / scale;
  *sub_level = (Float32)(l_temp1 * scale);

  for (i = 0; i < count1; i++)
  {
     l_temp2 += 2.0f * fabs(data[ind_m * i + ind_a]);
  }

  level = (Float32)(l_temp2 * scale);

  return level;
}

/*
 * E_DTX_filter_bank
 *
 * Parameters:
 *    st          I/0: State struct
 *    in            I: input frame
 *    level         I: signal levels at each band
 *
 * Function:
 *    Divide input signal into bands and calculate level of
 *    the signal in each band
 *
 * Returns:
 *    void
 */
static void E_DTX_filter_bank(E_DTX_Vad_State *st, Float32 in[],
                              Float32 level[])
{
   Float32 tmp_buf[FRAME_LEN];
   Word32 i, j;

   /* shift input 1 bit down for safe scaling */
   for (i = 0; i < FRAME_LEN; i++)
   {
      tmp_buf[i] = in[i] * 0.5F;
   }

   /* run the filter bank */
   for (i = 0; i < (FRAME_LEN >> 1); i++)
   {
      j = i << 1;
      E_DTX_filter5(&tmp_buf[j], &tmp_buf[j + 1], st->mem_a_data5[0]);
   }
   for (i = 0; i < (FRAME_LEN >> 2); i++)
   {
      j = i << 2;
      E_DTX_filter5(&tmp_buf[j], &tmp_buf[j + 2], st->mem_a_data5[1]);
      E_DTX_filter5(&tmp_buf[j + 1], &tmp_buf[j + 3], st->mem_a_data5[2]);
   }
   for (i = 0; i < (FRAME_LEN >> 3); i++)
   {
      j = i << 3;
      E_DTX_filter5(&tmp_buf[j], &tmp_buf[j + 4], st->mem_a_data5[3]);
      E_DTX_filter5(&tmp_buf[j + 2], &tmp_buf[j + 6], st->mem_a_data5[4]);
      E_DTX_filter3(&tmp_buf[j + 3], &tmp_buf[j + 7], &st->mem_a_data3[0]);
   }
   for (i = 0; i < (FRAME_LEN >> 4); i++)
   {
      j = i << 4;
      E_DTX_filter3(&tmp_buf[j], &tmp_buf[j + 8], &st->mem_a_data3[1]);
      E_DTX_filter3(&tmp_buf[j + 4], &tmp_buf[j + 12], &st->mem_a_data3[2]);
      E_DTX_filter3(&tmp_buf[j + 6], &tmp_buf[j + 14], &st->mem_a_data3[3]);
   }

   for (i = 0; i < (FRAME_LEN >> 5); i++)
   {
      j = i << 5;
      E_DTX_filter3(&tmp_buf[j + 0], &tmp_buf[j + 16], &st->mem_a_data3[4]);
      E_DTX_filter3(&tmp_buf[j + 8], &tmp_buf[j + 24], &st->mem_a_data3[5]);
   }

   /* calculate levels in each frequency band */

   /* 4800 - 6400 Hz*/
   level[11] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[11],
      (FRAME_LEN >> 2) - 48, FRAME_LEN >> 2, 4, 1, 0.25F);
   /* 4000 - 4800 Hz*/
   level[10] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[10],
      (FRAME_LEN >> 3) - 24, FRAME_LEN >> 3, 8, 7, 0.5F);
   /* 3200 - 4000 Hz*/
   level[9] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[9],
      (FRAME_LEN >> 3) - 24, FRAME_LEN >> 3, 8, 3, 0.5F);
   /* 2400 - 3200 Hz*/
   level[8] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[8],
      (FRAME_LEN >> 3) - 24, FRAME_LEN >> 3, 8, 2, 0.5F);
   /* 2000 - 2400 Hz*/
   level[7] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[7],
      (FRAME_LEN >> 4) - 12, FRAME_LEN >> 4, 16, 14, 1.0F);
   /* 1600 - 2000 Hz*/
   level[6] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[6],
      (FRAME_LEN >> 4) - 12, FRAME_LEN >> 4, 16, 6, 1.0F);
   /* 1200 - 1600 Hz*/
   level[5] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[5],
      (FRAME_LEN >> 4) - 12, FRAME_LEN >> 4, 16, 4, 1.0F);
   /* 800 - 1200 Hz*/
   level[4] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[4],
      (FRAME_LEN >> 4) - 12, FRAME_LEN >> 4, 16, 12, 1.0F);
   /* 600 - 800 Hz*/
   level[3] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[3],
      (FRAME_LEN >> 5) - 6, FRAME_LEN >> 5, 32, 8, 2.0F);
   /* 400 - 600 Hz*/
   level[2] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[2],
      (FRAME_LEN >> 5) - 6, FRAME_LEN >> 5, 32, 24, 2.0F);
   /* 200 - 400 Hz*/
   level[1] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[1],
      (FRAME_LEN >> 5) - 6, FRAME_LEN >> 5, 32, 16, 2.0F);
   /* 0 - 200 Hz*/
   level[0] = E_DTX_level_calculation(tmp_buf, &st->mem_sub_level[0],
      (FRAME_LEN >> 5) - 6, FRAME_LEN >> 5, 32, 0, 2.0F);
}

/*
 * E_DTX_update_cntrl
 *
 * Parameters:
 *    st          I/0: State struct
 *    level         I: sub-band levels of the input frame
 *
 * Function:
 *    Control update of the background noise estimate.
 *
 * Returns:
 *    void
 */
static void E_DTX_update_cntrl(E_DTX_Vad_State *st, Float32 level[])
{

   Float32 stat_rat;
   Float32 num, denom;
   Float32 alpha;
   Word32 i;

   /* if fullband pitch or tone have been detected for a while, initialize stat_count */

   if ((st->mem_pitch_tone & 0x7c00) == 0x7c00)
   {
      st->mem_stat_count = STAT_COUNT;

   }
   else
   {
      /* if 8 last vad-decisions have been "0", reinitialize stat_count */

      if ((st->mem_vadreg & 0x7f80) == 0)
      {
         st->mem_stat_count = STAT_COUNT;
      }
      else
      {
         stat_rat = 0;
         for (i = 0; i < COMPLEN; i++)
         {

            if (level[i] > st->mem_ave_level[i])
            {
               num = level[i];
               denom = st->mem_ave_level[i];
            }
            else
            {
               num = st->mem_ave_level[i];
               denom = level[i];
            }
            /* Limit nimimum value of num and denom to STAT_THR_LEVEL */

            if (num  < STAT_THR_LEVEL)
            {
               num = STAT_THR_LEVEL;
            }

            if (denom < STAT_THR_LEVEL)
            {
               denom = STAT_THR_LEVEL;
            }

            stat_rat += num/denom * 64;

         }

         /* compare stat_rat with a threshold and update stat_count */

         if (stat_rat  > STAT_THR)
         {
            st->mem_stat_count = STAT_COUNT;
         }
         else
         {

            if ((st->mem_vadreg & 0x4000) != 0)
            {

               if (st->mem_stat_count != 0)
               {
                  st->mem_stat_count--;
               }
            }
         }
      }
   }

   /* Update average amplitude estimate for stationarity estimation */
   alpha = ALPHA4;

   if (st->mem_stat_count == STAT_COUNT)
   {
      alpha = 1.0;
   }
   else if ((st->mem_vadreg & 0x4000) == 0)
   {

      alpha = ALPHA5;
   }

   for (i = 0; i < COMPLEN; i++)
   {
      st->mem_ave_level[i] += alpha * (level[i] - st->mem_ave_level[i]);
   }

}

/*

⌨️ 快捷键说明

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