dec_dtx.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:20k
源码类别:

Symbian

开发平台:

Visual C++

  1. /*
  2.  *===================================================================
  3.  *  3GPP AMR Wideband Floating-point Speech Codec
  4.  *===================================================================
  5.  */
  6. #include "hlxclib/stdlib.h"
  7. #include "hlxclib/memory.h"
  8. #include "hlxclib/math.h"
  9. #include "typedef.h"
  10. #include "dec_dtx.h"
  11. #include "dec_lpc.h"
  12. #include "dec_util.h"
  13. #define MAX_31                      (Word32)0x3FFFFFFF
  14. #define L_FRAME                     256   /* Frame size                          */
  15. #define RX_SPEECH_LOST              2
  16. #define RX_SPEECH_BAD               3
  17. #define RX_SID_FIRST                4
  18. #define RX_SID_UPDATE               5
  19. #define RX_SID_BAD                  6
  20. #define RX_NO_DATA                  7
  21. #define ISF_GAP                     128   /* 50                                  */
  22. #define D_DTX_MAX_EMPTY_THRESH      50
  23. #define GAIN_FACTOR                 75
  24. #define ISF_FACTOR_LOW              256
  25. #define ISF_FACTOR_STEP             2
  26. #define ISF_DITH_GAP                448
  27. #define D_DTX_HANG_CONST            7     /* yields eight frames of SP HANGOVER  */
  28. #define D_DTX_ELAPSED_FRAMES_THRESH (24 + 7 - 1)
  29. #define RANDOM_INITSEED             21845 /* own random init value               */
  30. /*
  31.  * D_DTX_reset
  32.  *
  33.  * Parameters:
  34.  *    st             O: state struct
  35.  *
  36.  * Function:
  37.  *    Initializes state memory
  38.  *
  39.  * Returns:
  40.  *    non-zero with error, zero for ok
  41.  */
  42. int D_DTX_reset(D_DTX_State *st, const Word16 *isf_init)
  43. {
  44.    Word32 i;
  45.    if(st == (D_DTX_State*)NULL)
  46.    {
  47.       return(-1);
  48.    }
  49.    st->mem_since_last_sid = 0;
  50.    st->mem_true_sid_period_inv = (1 << 13);   /* 0.25 in Q15 */
  51.    st->mem_log_en = 3500;
  52.    st->mem_log_en_prev = 3500;
  53.    /* low level noise for better performance in  DTX handover cases */
  54.    st->mem_cng_seed = RANDOM_INITSEED;
  55.    st->mem_hist_ptr = 0;
  56.    /* Init isf_hist[] and decoder log frame energy */
  57.    memcpy(st->mem_isf, isf_init, M * sizeof(Word16));
  58.    memcpy(st->mem_isf_prev, isf_init, M * sizeof(Word16));
  59.    for(i = 0; i < D_DTX_HIST_SIZE; i++)
  60.    {
  61.       memcpy(&st->mem_isf_buf[i * M], isf_init, M * sizeof(Word16));
  62.       st->mem_log_en_buf[i] = 3500;
  63.    }
  64.    st->mem_dtx_hangover_count = D_DTX_HANG_CONST;
  65.    st->mem_dec_ana_elapsed_count = 127;
  66.    st->mem_sid_frame = 0;
  67.    st->mem_valid_data = 0;
  68.    st->mem_dtx_hangover_added = 0;
  69.    st->mem_dtx_global_state = SPEECH;
  70.    st->mem_data_updated = 0;
  71.    st->mem_dither_seed = RANDOM_INITSEED;
  72.    st->mem_cn_dith = 0;
  73.    return(0);
  74. }
  75. /*
  76.  * D_DTX_init
  77.  *
  78.  * Parameters:
  79.  *    st           I/O: state struct
  80.  *
  81.  * Function:
  82.  *    Allocates state memory and initializes state memory
  83.  *
  84.  * Returns:
  85.  *    non-zero with error, zero for ok
  86.  */
  87. int D_DTX_init(D_DTX_State **st, const Word16 *isf_init)
  88. {
  89.    D_DTX_State *s;
  90.    if(st == (D_DTX_State**)NULL)
  91.    {
  92.       return(-1);
  93.    }
  94.    *st = NULL;
  95.    /* allocate memory */
  96.    if((s = (D_DTX_State*)malloc(sizeof(D_DTX_State))) == NULL)
  97.    {
  98.       return(-1);
  99.    }
  100.    D_DTX_reset(s, isf_init);
  101.    *st = s;
  102.    return(0);
  103. }
  104. /*
  105.  * D_DTX_exit
  106.  *
  107.  * Parameters:
  108.  *    state        I/0: State struct
  109.  *
  110.  * Function:
  111.  *    The memory used for state memory is freed
  112.  *
  113.  * Returns:
  114.  *    void
  115.  */
  116. void D_DTX_exit(D_DTX_State **st)
  117. {
  118.    if(st == NULL || *st == NULL)
  119.    {
  120.       return;
  121.    }
  122.    /* deallocate memory */
  123.    free(*st);
  124.    *st = NULL;
  125.    return;
  126. }
  127. /*
  128.  * D_DTX_rx_handler
  129.  *
  130.  * Parameters:
  131.  *    st              I/O: State struct
  132.  *    frame_type        I: Frame type
  133.  *
  134.  * Function:
  135.  *    Analyze received frame
  136.  *
  137.  *    Table of new SPD synthesis states
  138.  *
  139.  *                          |       previous SPD_synthesis_state
  140.  *    Incoming              |
  141.  *    frame_type            | SPEECH       | DTX           | D_DTX_MUTE
  142.  *    ---------------------------------------------------------------
  143.  *    RX_SPEECH_GOOD ,      |              |               |
  144.  *    RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
  145.  *    ----------------------------------------------------------------
  146.  *    RX_SPEECH_BAD,        | SPEECH       | DTX           | D_DTX_MUTE
  147.  *    ----------------------------------------------------------------
  148.  *    RX_SID_FIRST,         | DTX          | DTX/(D_DTX_MUTE)| D_DTX_MUTE
  149.  *    ----------------------------------------------------------------
  150.  *    RX_SID_UPDATE,        | DTX          | DTX           | DTX
  151.  *    ----------------------------------------------------------------
  152.  *    RX_SID_BAD,           | DTX          | DTX/(D_DTX_MUTE)| D_DTX_MUTE
  153.  *    ----------------------------------------------------------------
  154.  *    RX_NO_DATA,           | SPEECH       | DTX/(D_DTX_MUTE)| D_DTX_MUTE
  155.  *    RX_SPARE              |(class2 garb.)|               |
  156.  *    ----------------------------------------------------------------
  157.  *
  158.  * Returns:
  159.  *    new state
  160.  */
  161. UWord8 D_DTX_rx_handler(D_DTX_State *st, UWord8 frame_type)
  162. {
  163.    UWord8 newState;
  164.    UWord8 encState;
  165.    /* DTX if SID frame or previously in DTX{_MUTE}
  166.     * and (NO_RX OR BAD_SPEECH)
  167.     */
  168.    if((frame_type == RX_SID_FIRST) | (frame_type == RX_SID_UPDATE) |
  169.       (frame_type == RX_SID_BAD) | (((st->mem_dtx_global_state == DTX) |
  170.       (st->mem_dtx_global_state == D_DTX_MUTE)) & ((frame_type == RX_NO_DATA) |
  171.       (frame_type == RX_SPEECH_BAD) | (frame_type == RX_SPEECH_LOST))))
  172.    {
  173.       newState = DTX;
  174.       /* stay in mute for these input types */
  175.       if((st->mem_dtx_global_state == D_DTX_MUTE) &
  176.          ((frame_type == RX_SID_BAD) | (frame_type == RX_SID_FIRST) |
  177.          (frame_type == RX_SPEECH_LOST) | (frame_type == RX_NO_DATA)))
  178.       {
  179.          newState = D_DTX_MUTE;
  180.       }
  181.       /* evaluate if noise parameters are too old                     */
  182.       /* since_last_sid is reset when CN parameters have been updated */
  183.       st->mem_since_last_sid++;
  184.       /* no update of sid parameters in DTX for a Word32 while */
  185.       if(st->mem_since_last_sid > D_DTX_MAX_EMPTY_THRESH)
  186.       {
  187.          newState = D_DTX_MUTE;
  188.       }
  189.    }
  190.    else
  191.    {
  192.       newState = SPEECH;
  193.       st->mem_since_last_sid = 0;
  194.    }
  195.    /*
  196.     * reset the decAnaElapsed Counter when receiving CNI data the first
  197.     * time, to robustify counter missmatch after handover
  198.     * this might delay the bwd CNI analysis in the new decoder slightly.
  199.     */
  200.    if((st->mem_data_updated == 0) & (frame_type == RX_SID_UPDATE))
  201.    {
  202.       st->mem_dec_ana_elapsed_count = 0;
  203.    }
  204.    /*
  205.     * update the SPE-SPD DTX hangover synchronization
  206.     * to know when SPE has added dtx hangover
  207.     */
  208.    st->mem_dec_ana_elapsed_count++;
  209.    /* saturate */
  210.    if(st->mem_dec_ana_elapsed_count > 127)
  211.    {
  212.       st->mem_dec_ana_elapsed_count = 127;
  213.    }
  214.    st->mem_dtx_hangover_added = 0;
  215.    if((frame_type == RX_SID_FIRST) | (frame_type == RX_SID_UPDATE) |
  216.       (frame_type == RX_SID_BAD) | (frame_type == RX_NO_DATA))
  217.    {
  218.       encState = DTX;
  219.    }
  220.    else
  221.    {
  222.       encState = SPEECH;
  223.    }
  224.    if(encState == SPEECH)
  225.    {
  226.       st->mem_dtx_hangover_count = D_DTX_HANG_CONST;
  227.    }
  228.    else
  229.    {
  230.       if(st->mem_dec_ana_elapsed_count > D_DTX_ELAPSED_FRAMES_THRESH)
  231.       {
  232.          st->mem_dtx_hangover_added = 1;
  233.          st->mem_dec_ana_elapsed_count = 0;
  234.          st->mem_dtx_hangover_count = 0;
  235.       }
  236.       else if(st->mem_dtx_hangover_count == 0)
  237.       {
  238.          st->mem_dec_ana_elapsed_count = 0;
  239.       }
  240.       else
  241.       {
  242.          st->mem_dtx_hangover_count--;
  243.       }
  244.    }
  245.    if(newState != SPEECH)
  246.    {
  247.       /*
  248.        * DTX or D_DTX_MUTE
  249.        * CN data is not in a first SID, first SIDs are marked as SID_BAD
  250.        *  but will do backwards analysis if a hangover period has been added
  251.        *  according to the state machine above
  252.        */
  253.       st->mem_sid_frame = 0;
  254.       st->mem_valid_data = 0;
  255.       if(frame_type == RX_SID_FIRST)
  256.       {
  257.          st->mem_sid_frame = 1;
  258.       }
  259.       else if(frame_type == RX_SID_UPDATE)
  260.       {
  261.          st->mem_sid_frame = 1;
  262.          st->mem_valid_data = 1;
  263.       }
  264.       else if(frame_type == RX_SID_BAD)
  265.       {
  266.          st->mem_sid_frame = 1;
  267.          st->mem_dtx_hangover_added = 0;   /* use old data */
  268.       }
  269.    }
  270.    return newState;
  271.    /* newState is used by both SPEECH AND DTX synthesis routines */
  272. }
  273. /*
  274.  * D_DTX_cn_dithering
  275.  *
  276.  * Parameters:
  277.  *    isf             I/O: CN ISF vector
  278.  *    L_log_en_int    I/O: energy parameter
  279.  *    dither_seed     I/O: random seed
  280.  *
  281.  * Function:
  282.  *    Confort noise dithering
  283.  *
  284.  * Returns:
  285.  *    void
  286.  */
  287. static void D_DTX_cn_dithering(Word16 isf[M], Word32 *L_log_en_int,
  288.                                Word16 *dither_seed)
  289. {
  290.    Word32 temp, temp1, i, dither_fac, rand_dith,rand_dith2;
  291.    /* Insert comfort noise dithering for energy parameter */
  292.    rand_dith = D_UTIL_random(dither_seed) >> 1;
  293.    rand_dith2 = D_UTIL_random(dither_seed) >>1;
  294.    rand_dith = rand_dith + rand_dith2;
  295.    *L_log_en_int = *L_log_en_int + ((rand_dith * GAIN_FACTOR) << 1);
  296.    if(*L_log_en_int < 0)
  297.    {
  298.       *L_log_en_int = 0;
  299.    }
  300.    /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
  301.    dither_fac = ISF_FACTOR_LOW;
  302.    rand_dith = D_UTIL_random(dither_seed) >> 1;
  303.    rand_dith2 = D_UTIL_random(dither_seed) >> 1;
  304.    rand_dith = rand_dith + rand_dith2;
  305.    temp = isf[0] + (((rand_dith * dither_fac) + 0x4000) >> 15);
  306.    /* Make sure that isf[0] will not get negative values */
  307.    if(temp < ISF_GAP)
  308.    {
  309.       isf[0] = ISF_GAP;
  310.    }
  311.    else
  312.    {
  313.       isf[0] = (Word16)temp;
  314.    }
  315.    for(i = 1; i < M - 1; i++)
  316.    {
  317.       dither_fac = dither_fac + ISF_FACTOR_STEP;
  318.       rand_dith = D_UTIL_random(dither_seed) >> 1;
  319.       rand_dith2 = D_UTIL_random(dither_seed) >> 1;
  320.       rand_dith = rand_dith + rand_dith2;
  321.       temp = isf[i] + (((rand_dith * dither_fac) + 0x4000) >> 15);
  322.       temp1 = temp - isf[i - 1];
  323.       /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */
  324.       if(temp1 < ISF_DITH_GAP)
  325.       {
  326.          isf[i] = (Word16)(isf[i - 1] + ISF_DITH_GAP);
  327.       }
  328.       else
  329.       {
  330.          isf[i] = (Word16)temp;
  331.       }
  332.    }
  333.    /* Make sure that isf[M-2] will not get values above 16384 */
  334.    if(isf[M - 2] > 16384)
  335.    {
  336.       isf[M - 2] = 16384;
  337.    }
  338.    return;
  339. }
  340. /*
  341.  * D_DTX_exe
  342.  *
  343.  * Parameters:
  344.  *    st           I/O: state struct
  345.  *    exc2           O: CN excitation
  346.  *    new_state      I: New DTX state
  347.  *    prms           I: Vector of synthesis parameters
  348.  *    isf            O: CN ISF vector
  349.  *
  350.  * Function:
  351.  *    Confort noise generation
  352.  *
  353.  * Returns:
  354.  *    void
  355.  */
  356. void D_DTX_exe(D_DTX_State *st, Word16 *exc2, Word16 new_state, Word16 isf[],
  357.                Word16 **prms)
  358. {
  359.    Word32 i, j, L_tmp, ptr;
  360.    Word32 exp0, int_fac;
  361.    Word32 gain;
  362.    Word32 L_isf[M], L_log_en_int, level32, ener32;
  363.    Word16 log_en_index;
  364.    Word16 tmp_int_length;
  365.    Word16 exp, log_en_int_e, log_en_int_m, level;
  366.    /*
  367.     * This function is called if synthesis state is not SPEECH.
  368.     * The globally passed inputs to this function are
  369.     *    st->sid_frame
  370.     *    st->valid_data
  371.     *    st->dtxHangoverAdded
  372.     *    new_state (SPEECH, DTX, D_DTX_MUTE)
  373.     */
  374.    if((st->mem_dtx_hangover_added != 0) & (st->mem_sid_frame != 0))
  375.    {
  376.       /* sid_first after dtx hangover period
  377.        * or sid_upd after dtxhangover
  378.        * consider twice the last frame
  379.        */
  380.       ptr = st->mem_hist_ptr + 1;
  381.       if(ptr == D_DTX_HIST_SIZE)
  382.       {
  383.          ptr = 0;
  384.       }
  385.       memcpy(&st->mem_isf_buf[ptr * M], &st->mem_isf_buf[st->mem_hist_ptr * M],
  386.          M * sizeof(Word16));
  387.       st->mem_log_en_buf[ptr] = st->mem_log_en_buf[st->mem_hist_ptr];
  388.       /* compute mean log energy and isf from decoded signal (SID_FIRST) */
  389.       st->mem_log_en = 0;
  390.       memset(L_isf, 0, M * sizeof(Word32));
  391.       /* average energy and isf */
  392.       for(i = 0; i < D_DTX_HIST_SIZE; i++)
  393.       {
  394.          /*
  395.           * Division by D_DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en
  396.           * is in Q10
  397.           */
  398.          st->mem_log_en = (Word16)(st->mem_log_en + st->mem_log_en_buf[i]);
  399.          for(j = 0; j < M; j++)
  400.          {
  401.             L_isf[j] = L_isf[j] + st->mem_isf_buf[i * M + j];
  402.          }
  403.       }
  404.       /* st->log_en in Q9 */
  405.       st->mem_log_en = (Word16)(st->mem_log_en >> 1);
  406.       /*
  407.        * Add 2 in Q9, in order to have only positive values for Pow2
  408.        * this value is subtracted back after Pow2 function
  409.        */
  410.       st->mem_log_en = (Word16)(st->mem_log_en + 1024);
  411.       if(st->mem_log_en < 0)
  412.       {
  413.          st->mem_log_en = 0;
  414.       }
  415.       for(j = 0; j < M; j++)
  416.       {
  417.          st->mem_isf[j] = (Word16)(L_isf[j]>>3);   /* divide by 8 */
  418.       }
  419.    }
  420.    if(st->mem_sid_frame != 0)
  421.    {
  422.       /*
  423.        * Set old SID parameters, always shift
  424.        * even if there is no new valid_data
  425.        */
  426.       memcpy(st->mem_isf_prev, st->mem_isf, M * sizeof(Word16));
  427.       st->mem_log_en_prev = st->mem_log_en;
  428.       if(st->mem_valid_data != 0) /* new data available (no CRC) */
  429.       {
  430.          /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */
  431.          /*
  432.           * Compute interpolation factor, since the division only works
  433.           * for values of since_last_sid < 32 we have to limit
  434.           * the interpolation to 32 frames
  435.           */
  436.          tmp_int_length = st->mem_since_last_sid;
  437.          if(tmp_int_length > 32)
  438.          {
  439.             tmp_int_length = 32;
  440.          }
  441.          if(tmp_int_length >= 2)
  442.          {
  443.             st->mem_true_sid_period_inv =
  444.                (Word16)(0x2000000 / (tmp_int_length << 10));
  445.          }
  446.          else
  447.          {
  448.             st->mem_true_sid_period_inv = 1 << 14;   /* 0.5 it Q15 */
  449.          }
  450.          D_LPC_isf_noise_d(*prms, st->mem_isf);
  451.          (*prms) += 5;
  452.          log_en_index = *(*prms)++;
  453.          /* read background noise stationarity information */
  454.          st->mem_cn_dith = *(*prms)++;
  455.          /*
  456.           * st->log_en = (Float32)log_en_index / 2.625 - 2.0;
  457.           * log2(E) in Q9 (log2(E) lies in between -2:22)
  458.           */
  459.          st->mem_log_en = (Word16)(log_en_index << (15 - 6));
  460.          /* Divide by 2.625  */
  461.          st->mem_log_en = (Word16)((st->mem_log_en * 12483) >> 15);
  462.          /*
  463.           * Subtract 2 in Q9 is done later, after Pow2 function
  464.           * no interpolation at startup after coder reset
  465.           * or when SID_UPD has been received right after SPEECH
  466.           */
  467.          if((st->mem_data_updated == 0) ||
  468.             (st->mem_dtx_global_state == SPEECH))
  469.          {
  470.             memcpy(st->mem_isf_prev, st->mem_isf, M * sizeof(Word16));
  471.             st->mem_log_en_prev = st->mem_log_en;
  472.          }
  473.       }   /* endif valid_data */
  474.    }   /* endif sid_frame */
  475.    if((st->mem_sid_frame != 0) && (st->mem_valid_data != 0))
  476.    {
  477.       st->mem_since_last_sid = 0;
  478.    }
  479.    /* Interpolate SID info */
  480.    if(st->mem_since_last_sid < 32)
  481.    {
  482.       int_fac = st->mem_since_last_sid << 10;   /* Q10 */
  483.    }
  484.    else
  485.    {
  486.       int_fac = 32767;
  487.    }
  488.    /* Q10 * Q15 -> Q10 */
  489.    int_fac = (int_fac * st->mem_true_sid_period_inv) >> 15;
  490.    /* Maximize to 1.0 in Q10 */
  491.    if(int_fac > 1024)
  492.    {
  493.       int_fac = 1024;
  494.    }
  495.    int_fac = int_fac << 4;   /* Q10 -> Q14 */
  496.    L_log_en_int = (int_fac * st->mem_log_en) << 1;   /* Q14 * Q9 -> Q24 */
  497.    for(i = 0; i < M; i++)
  498.    {
  499.       /* Q14 * Q15 -> Q14 */
  500.       isf[i] = (Word16)((int_fac * st->mem_isf[i]) >> 15);
  501.    }
  502.    int_fac = 16384 - int_fac;   /* 1-k in Q14 */
  503.    /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */
  504.    L_log_en_int = L_log_en_int + ((int_fac * st->mem_log_en_prev) << 1);
  505.    for(i = 0; i < M; i++)
  506.    {
  507.       /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
  508.       L_tmp = isf[i] + ((int_fac * st->mem_isf_prev[i]) >> 15);
  509.       isf[i] = (Word16)(L_tmp << 1);   /* Q14 -> Q15 */
  510.    }
  511.    /* If background noise is non-stationary, insert comfort noise dithering */
  512.    if(st->mem_cn_dith != 0)
  513.    {
  514.       D_DTX_cn_dithering(isf, &L_log_en_int, &st->mem_dither_seed);
  515.    }
  516.    /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */
  517.    L_log_en_int = (L_log_en_int >> 9); /* Q25 -> Q16 */
  518.    /* Find integer part  */
  519.    log_en_int_e = (Word16)((L_log_en_int)>>16);
  520.    /* Find fractional part */
  521.    log_en_int_m = (Word16)((L_log_en_int - (log_en_int_e << 16)) >> 1);
  522.    /*
  523.     * Subtract 2 from L_log_en_int in Q9,
  524.     * i.e divide the gain by 2 (energy by 4)
  525.     * Add 16 in order to have the result of pow2 in Q16
  526.     */
  527.    log_en_int_e = (Word16)(log_en_int_e + (16 - 1));
  528.    /* level = (Float32)( pow( 2.0f, log_en ) );  */
  529.    level32 = D_UTIL_pow2(log_en_int_e, log_en_int_m);   /* Q16 */
  530.    exp0 = D_UTIL_norm_l(level32);
  531.    level32 = (level32 << exp0);   /* level in Q31 */
  532.    exp0 = (15 - exp0);
  533.    level = (Word16)(level32 >> 16);   /* level in Q15 */
  534.    /* generate white noise vector */
  535.    for(i = 0; i < L_FRAME; i++)
  536.    {
  537.       exc2[i] = (Word16)((D_UTIL_random(&(st->mem_cng_seed)) >> 4));
  538.    }
  539.    /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
  540.    /* energy of generated excitation */
  541.    ener32 = D_UTIL_dot_product12(exc2, exc2, L_FRAME, &exp);
  542.    D_UTIL_normalised_inverse_sqrt(&ener32, &exp);
  543.    gain = ener32 >>16;
  544.    gain = (level * gain) >> 15;   /* gain in Q15 */
  545.    /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
  546.    exp = (Word16)(exp0 + exp  + 4);
  547.    if(exp >= 0)
  548.    {
  549.       for(i = 0; i < L_FRAME; i++)
  550.       {
  551.          L_tmp = (exc2[i] * gain) >> 15;   /* Q0 * Q15 */
  552.          exc2[i] = (Word16)(L_tmp << exp);
  553.       }
  554.    }
  555.    else
  556.    {
  557.       exp = (Word16)-exp;
  558.       for(i = 0; i < L_FRAME; i++)
  559.       {
  560.          L_tmp = (exc2[i] * gain) >> 15;   /* Q0 * Q15 */
  561.          exc2[i] = (Word16)(L_tmp >> exp);
  562.       }
  563.    }
  564.    if(new_state == D_DTX_MUTE)
  565.    {
  566.       /*
  567.        * mute comfort noise as it has been quite a long time since
  568.        * last SID update was performed
  569.        */
  570.       tmp_int_length = st->mem_since_last_sid;
  571.       if(tmp_int_length > 32)
  572.       {
  573.          tmp_int_length = 32;
  574.       }
  575.       st->mem_true_sid_period_inv = (Word16)(0x7FFFFFFF / tmp_int_length);
  576.       st->mem_since_last_sid = 0;
  577.       st->mem_log_en_prev = st->mem_log_en;
  578.       /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */
  579.       st->mem_log_en = (Word16)(st->mem_log_en - 64);
  580.    }
  581.    /* reset interpolation length timer if data has been updated.        */
  582.    if((st->mem_sid_frame != 0) && ((st->mem_valid_data != 0) ||
  583.       ((st->mem_valid_data == 0) && (st->mem_dtx_hangover_added) != 0)))
  584.    {
  585.       st->mem_since_last_sid = 0;
  586.       st->mem_data_updated = 1;
  587.    }
  588.    return;
  589. }
  590. /*
  591.  * D_DTX_activity_update
  592.  *
  593.  * Parameters:
  594.  *    st           I/O: state struct
  595.  *    isf            O: ISF vector
  596.  *    exc            O: excitation
  597.  *
  598.  * Function:
  599.  *    Confort noise generation
  600.  *
  601.  * Returns:
  602.  *    void
  603.  */
  604. void D_DTX_activity_update(D_DTX_State *st, Word16 isf[], Word16 exc[])
  605. {
  606.    Word32 L_frame_en, log_en;
  607.    Word32 i;
  608.    Word16 log_en_e, log_en_m;
  609.    st->mem_hist_ptr = (Word16)(st->mem_hist_ptr + 1);
  610.    if(st->mem_hist_ptr == D_DTX_HIST_SIZE)
  611.    {
  612.       st->mem_hist_ptr = 0;
  613.    }
  614.    memcpy(&st->mem_isf_buf[st->mem_hist_ptr * M], isf, M * sizeof(Word16));
  615.    /* compute log energy based on excitation frame energy in Q0 */
  616.    L_frame_en = 0;
  617.    for(i = 0; i < L_FRAME; i++)
  618.    {
  619.       L_frame_en = L_frame_en + (exc[i] * exc[i]);
  620.       if (L_frame_en > MAX_31)
  621.       {
  622.          L_frame_en = MAX_31;
  623.          break;
  624.       }
  625.    }
  626.    /*
  627.     * log_en =
  628.     * (Float32)log10(L_frame_en/(Float32)L_FRAME)/(Float32)log10(2.0f);
  629.     */
  630.    D_UTIL_log2(L_frame_en, &log_en_e, &log_en_m);
  631.    /*
  632.     * convert exponent and mantissa to Word16 Q7.
  633.     * Q7 is used to simplify averaging in dtx_enc
  634.     */
  635.    log_en = log_en_e << 7;   /* Q7 */
  636.    log_en = log_en + (log_en_m >> (15 - 7));
  637.    /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */
  638.    log_en = log_en - 1024;
  639.    /* insert into log energy buffer */
  640.    st->mem_log_en_buf[st->mem_hist_ptr] = (Word16)log_en;
  641.    return;
  642. }