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

📄 dec_dtx.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *===================================================================
 *  3GPP AMR Wideband Floating-point Speech Codec
 *===================================================================
 */
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include "typedef.h"
#include "dec_dtx.h"
#include "dec_lpc.h"
#include "dec_util.h"
#include "..\include\options.h"
#define MAX_31                      (Word32)0x3FFFFFFF
#define L_FRAME                     256   /* Frame size                          */
#define RX_SPEECH_LOST              2
#define RX_SPEECH_BAD               3
#define RX_SID_FIRST                4
#define RX_SID_UPDATE               5
#define RX_SID_BAD                  6
#define RX_NO_DATA                  7
#define ISF_GAP                     128   /* 50                                  */
#define D_DTX_MAX_EMPTY_THRESH      50
#define GAIN_FACTOR                 75
#define ISF_FACTOR_LOW              256
#define ISF_FACTOR_STEP             2
#define ISF_DITH_GAP                448
#define D_DTX_HANG_CONST            7     /* yields eight frames of SP HANGOVER  */
#define D_DTX_ELAPSED_FRAMES_THRESH (24 + 7 - 1)
#define RANDOM_INITSEED             21845 /* own random init value               */
/*
 * D_DTX_reset
 *
 * Parameters:
 *    st             O: state struct
 *
 * Function:
 *    Initializes state memory
 *
 * Returns:
 *    non-zero with error, zero for ok
 */
int D_DTX_reset(D_DTX_State *st, const Word16 *isf_init)
{
   Word32 i;
   if(st == (D_DTX_State*)NULL)                                         
   {
       return(-1);
   }
   st->mem_since_last_sid = 0;
   st->mem_true_sid_period_inv = (1 << 13);   /* 0.25 in Q15 */
   st->mem_log_en = 3500;
   st->mem_log_en_prev = 3500;
   /* low level noise for better performance in  DTX handover cases */
   st->mem_cng_seed = RANDOM_INITSEED;
   st->mem_hist_ptr = 0;
   /* Init isf_hist[] and decoder log frame energy */
   memcpy(st->mem_isf, isf_init, M * sizeof(Word16));
   memcpy(st->mem_isf_prev, isf_init, M * sizeof(Word16));
   for(i = 0; i < D_DTX_HIST_SIZE; i++)                                 
   {
       memcpy(&st->mem_isf_buf[i * M], isf_init, M * sizeof(Word16));
      st->mem_log_en_buf[i] = 3500;
   }
   st->mem_dtx_hangover_count = D_DTX_HANG_CONST;
   st->mem_dec_ana_elapsed_count = 127;
   st->mem_sid_frame = 0;
   st->mem_valid_data = 0;
   st->mem_dtx_hangover_added = 0;
   st->mem_dtx_global_state = SPEECH;
   st->mem_data_updated = 0;
   st->mem_dither_seed = RANDOM_INITSEED;
   st->mem_cn_dith = 0;
   return(0);
}
/*
 * D_DTX_init
 *
 * Parameters:
 *    st           I/O: state struct
 *
 * Function:
 *    Allocates state memory and initializes state memory
 *
 * Returns:
 *    non-zero with error, zero for ok
 */
int D_DTX_init(D_DTX_State **st, const Word16 *isf_init)
{
   D_DTX_State *s;
   if(st == (D_DTX_State**)NULL)                                
   {
       return(-1);
   }
   *st = NULL;
   /* allocate memory */
   if((s = (D_DTX_State*)malloc(sizeof(D_DTX_State))) == NULL)  
   {
       return(-1);
   }
   D_DTX_reset(s, isf_init);
   *st = s;
   return(0);
}
/*
 * D_DTX_exit
 *
 * Parameters:
 *    state        I/0: State struct
 *
 * Function:
 *    The memory used for state memory is freed
 *
 * Returns:
 *    void
 */
void D_DTX_exit(D_DTX_State **st)
{                                                           
   if(st == NULL || *st == NULL)                            
   {
       return;
   }
   /* deallocate memory */
   free(*st);
   *st = NULL;
   return;
}
/*
 * D_DTX_rx_handler
 *
 * Parameters:
 *    st              I/O: State struct
 *    frame_type        I: Frame type
 *
 * Function:
 *    Analyze received frame
 *
 *    Table of new SPD synthesis states
 *
 *                          |       previous SPD_synthesis_state
 *    Incoming              |
 *    frame_type            | SPEECH       | DTX           | D_DTX_MUTE
 *    ---------------------------------------------------------------
 *    RX_SPEECH_GOOD ,      |              |               |
 *    RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
 *    ----------------------------------------------------------------
 *    RX_SPEECH_BAD,        | SPEECH       | DTX           | D_DTX_MUTE
 *    ----------------------------------------------------------------
 *    RX_SID_FIRST,         | DTX          | DTX/(D_DTX_MUTE)| D_DTX_MUTE
 *    ----------------------------------------------------------------
 *    RX_SID_UPDATE,        | DTX          | DTX           | DTX
 *    ----------------------------------------------------------------
 *    RX_SID_BAD,           | DTX          | DTX/(D_DTX_MUTE)| D_DTX_MUTE
 *    ----------------------------------------------------------------
 *    RX_NO_DATA,           | SPEECH       | DTX/(D_DTX_MUTE)| D_DTX_MUTE
 *    RX_SPARE              |(class2 garb.)|               |
 *    ----------------------------------------------------------------
 *
 * Returns:
 *    new state
 */
UWord8 D_DTX_rx_handler(D_DTX_State *st, UWord8 frame_type)
{
   UWord8 newState;
   UWord8 encState;
   /* DTX if SID frame or previously in DTX{_MUTE}
    * and (NO_RX OR BAD_SPEECH)                                                 
    */
   if((frame_type == RX_SID_FIRST) | (frame_type == RX_SID_UPDATE) |
      (frame_type == RX_SID_BAD) | (((st->mem_dtx_global_state == DTX) |
      (st->mem_dtx_global_state == D_DTX_MUTE)) & ((frame_type == RX_NO_DATA) |
      (frame_type == RX_SPEECH_BAD) | (frame_type == RX_SPEECH_LOST))))
   {
      newState = DTX;
      /* stay in mute for these input types */
      if((st->mem_dtx_global_state == D_DTX_MUTE) &                             
         ((frame_type == RX_SID_BAD) | (frame_type == RX_SID_FIRST) |
         (frame_type == RX_SPEECH_LOST) | (frame_type == RX_NO_DATA)))
      {
         newState = D_DTX_MUTE;
      }
      /* evaluate if noise parameters are too old                     */
      /* since_last_sid is reset when CN parameters have been updated */
      st->mem_since_last_sid = (UWord8)D_UTIL_saturate(st->mem_since_last_sid + 1);
      /* no update of sid parameters in DTX for a Word32 while */
      if(st->mem_since_last_sid > D_DTX_MAX_EMPTY_THRESH)                           
      {
         newState = D_DTX_MUTE;
      }
   }
   else
   {                                                                                
      newState = SPEECH;
      st->mem_since_last_sid = 0;
   }
   /*
    * reset the decAnaElapsed Counter when receiving CNI data the first
    * time, to robustify counter missmatch after handover
    * this might delay the bwd CNI analysis in the new decoder slightly.
    */
   if((st->mem_data_updated == 0) & (frame_type == RX_SID_UPDATE))                  
   {
      st->mem_dec_ana_elapsed_count = 0;
   }
   /*
    * update the SPE-SPD DTX hangover synchronization
    * to know when SPE has added dtx hangover
    */
   st->mem_dec_ana_elapsed_count++;
   /* saturate */
   if(st->mem_dec_ana_elapsed_count > 127)          
   {
      st->mem_dec_ana_elapsed_count = 127;
   }
   st->mem_dtx_hangover_added = 0;
   if((frame_type == RX_SID_FIRST) | (frame_type == RX_SID_UPDATE) |
      (frame_type == RX_SID_BAD) | (frame_type == RX_NO_DATA))
   {
      encState = DTX;
   }
   else
   {
      encState = SPEECH;
   }
   if(encState == SPEECH)
   {
      st->mem_dtx_hangover_count = D_DTX_HANG_CONST;
   }
   else
   {                                                                                
      if(st->mem_dec_ana_elapsed_count > D_DTX_ELAPSED_FRAMES_THRESH)               
      {
         st->mem_dtx_hangover_added = 1;
         st->mem_dec_ana_elapsed_count = 0;
         st->mem_dtx_hangover_count = 0;
      }
      else if(st->mem_dtx_hangover_count == 0)
      {
         st->mem_dec_ana_elapsed_count = 0;
      }
      else
      {
         st->mem_dtx_hangover_count--;
      }
   }
   if(newState != SPEECH)
   {
      /*
       * DTX or D_DTX_MUTE
       * CN data is not in a first SID, first SIDs are marked as SID_BAD
       *  but will do backwards analysis if a hangover period has been added
       *  according to the state machine above
       */
      st->mem_sid_frame = 0;
      st->mem_valid_data = 0;
      if(frame_type == RX_SID_FIRST)
      {
         st->mem_sid_frame = 1;
      }
      else if(frame_type == RX_SID_UPDATE)
      {
         st->mem_sid_frame = 1;
         st->mem_valid_data = 1;
      }
      else if(frame_type == RX_SID_BAD)
      {
         st->mem_sid_frame = 1;
         st->mem_dtx_hangover_added = 0;   /* use old data */
      }
   }
   return newState;
   /* newState is used by both SPEECH AND DTX synthesis routines */
}
/*
 * D_DTX_cn_dithering
 *
 * Parameters:
 *    isf             I/O: CN ISF vector
 *    L_log_en_int    I/O: energy parameter
 *    dither_seed     I/O: random seed
 *
 * Function:
 *    Confort noise dithering
 *
 * Returns:
 *    void
 */
static void D_DTX_cn_dithering(Word16 isf[M], Word32 *L_log_en_int,
                               Word16 *dither_seed)
{
   Word32 temp, temp1, i, dither_fac, rand_dith,rand_dith2;
   /* Insert comfort noise dithering for energy parameter */
   rand_dith = D_UTIL_random(dither_seed) >> 1;
   rand_dith2 = D_UTIL_random(dither_seed) >>1;
   rand_dith = rand_dith + rand_dith2;
   *L_log_en_int = *L_log_en_int + ((rand_dith * GAIN_FACTOR) << 1);
   if(*L_log_en_int < 0)
   {
      *L_log_en_int = 0;
   }
   /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
   dither_fac = ISF_FACTOR_LOW;
   rand_dith = D_UTIL_random(dither_seed) >> 1;
   rand_dith2 = D_UTIL_random(dither_seed) >> 1;
   rand_dith = rand_dith + rand_dith2;
   temp = isf[0] + (((rand_dith * dither_fac) + 0x4000) >> 15);
   /* Make sure that isf[0] will not get negative values */
   if(temp < ISF_GAP)
   {
      isf[0] = ISF_GAP;
   }
   else
   {
      isf[0] = (Word16)temp;
   }
   for(i = 1; i < M - 1; i++)
   {
      dither_fac = dither_fac + ISF_FACTOR_STEP;
      rand_dith = D_UTIL_random(dither_seed) >> 1;
      rand_dith2 = D_UTIL_random(dither_seed) >> 1;
      rand_dith = rand_dith + rand_dith2;
      temp = isf[i] + (((rand_dith * dither_fac) + 0x4000) >> 15);

⌨️ 快捷键说明

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