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

📄 vad1.c

📁 arm音频编解码库
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************************************-------------------------------------------------------------------------****                                                                         ****     GSM AMR-NB speech codec   R98   Version 7.6.0   December 12, 2001       ****                               R99   Version 3.3.0                       ****                               REL-4 Version 4.1.0                       ****                                                                         ****-------------------------------------------------------------------------*********************************************************************************      File             : vad1.c*      Purpose          : Voice Activity Detection (VAD) for AMR (option 1)*******************************************************************************//*******************************************************************************                         MODULE INCLUDE FILE AND VERSION ID******************************************************************************/#include "vad.h"const char vad1_id[] = "@(#)$Id $" vad_h; /*******************************************************************************                         INCLUDE FILES******************************************************************************/#include <stdlib.h>#include <stdio.h>#include "typedef.h"#include "basic_op.h"#include "count.h"#include "oper_32b.h"#include "cnst_vad.h"/*******************************************************************************                         LOCAL VARIABLES AND TABLES******************************************************************************//**********************************************************************************                         PRIVATE PROGRAM CODE*********************************************************************************//**************************************************************************** * *     Function     : first_filter_stage *     Purpose      : Scale input down by one bit. Calculate 5th order *                    half-band lowpass/highpass filter pair with *                    decimation. * ***************************************************************************/static void first_filter_stage(Word16 in[],  /* i   : input signal                  */                               Word16 out[], /* o   : output values, every other    */                                             /*       output is low-pass part and   */                                             /*       other is high-pass part every */                               Word16 data[] /* i/o : filter memory                 */                               ){  Word16 temp0, temp1, temp2, temp3, i;  Word16 data0, data1;  data0 = data[0];                                          move16 ();  data1 = data[1];                                          move16 ();   for (i = 0; i < FRAME_LEN/4; i++)  {     temp0 = sub(shr(in[4*i+0], 2), mult(COEFF5_1, data0));     temp1 = add(data0, mult(COEFF5_1, temp0));          temp3 = sub(shr(in[4*i+1], 2), mult(COEFF5_2, data1));     temp2 = add(data1, mult(COEFF5_2, temp3));          out[4*i+0] = add(temp1, temp2);                        move16 ();     out[4*i+1] = sub(temp1, temp2);                        move16 ();          data0 = sub(shr(in[4*i+2], 2), mult(COEFF5_1, temp0));     temp1 = add(temp0, mult(COEFF5_1, data0));          data1 = sub(shr(in[4*i+3], 2), mult(COEFF5_2, temp3));     temp2 = add(temp3, mult(COEFF5_2, data1));          out[4*i+2] = add(temp1, temp2);                       move16 ();     out[4*i+3] = sub(temp1, temp2);                       move16 ();  }     data[0] = data0;                                         move16 ();  data[1] = data1;                                         move16 ();}/**************************************************************************** * *     Function     : filter5 *     Purpose      : Fifth-order half-band lowpass/highpass filter pair with *                    decimation. * ***************************************************************************/static void filter5(Word16 *in0,    /* i/o : input values; output low-pass part  */                    Word16 *in1,    /* i/o : input values; output high-pass part */                    Word16 data[]   /* i/o : updated filter memory               */                    ){  Word16 temp0, temp1, temp2;  temp0 = sub(*in0, mult(COEFF5_1, data[0]));  temp1 = add(data[0], mult(COEFF5_1, temp0));  data[0] = temp0;                                move16 ();  temp0 = sub(*in1, mult(COEFF5_2, data[1]));  temp2 = add(data[1], mult(COEFF5_2, temp0));  data[1] = temp0;                                move16 ();  *in0 = shr(add(temp1, temp2), 1);               move16 ();  *in1 = shr(sub(temp1, temp2), 1);               move16 ();}/**************************************************************************** * *     Function     : filter3 *     Purpose      : Third-order half-band lowpass/highpass filter pair with *                    decimation. *     Return value :  * ***************************************************************************/static void filter3(Word16 *in0,   /* i/o : input values; output low-pass part  */                     Word16 *in1,   /* i/o : input values; output high-pass part */                    Word16 *data   /* i/o : updated filter memory               */                    ){  Word16 temp1, temp2;  temp1 = sub(*in1, mult(COEFF3, *data));  temp2 = add(*data, mult(COEFF3, temp1));  *data = temp1;                              move16 ();  *in1 = shr(sub(*in0, temp2), 1);            move16 ();  *in0 = shr(add(*in0, temp2), 1);            move16 ();}/**************************************************************************** * *     Function     : level_calculation *     Purpose      : Calculate signal level in a sub-band. Level is calculated *                    by summing absolute values of the input data. *     Return value : signal level * ***************************************************************************/static Word16 level_calculation(    Word16 data[],     /* i   : signal buffer                                    */    Word16 *sub_level, /* i   : level calculate at the end of the previous frame */                       /* o   : level of signal calculated from the last         */                       /*       (count2 - count1) samples                        */    Word16 count1,     /* i   : number of samples to be counted                  */    Word16 count2,     /* i   : number of samples to be counted                  */    Word16 ind_m,      /* i   : step size for the index of the data buffer       */    Word16 ind_a,      /* i   : starting index of the data buffer                */    Word16 scale       /* i   : scaling for the level calculation                */    ){  Word32 l_temp1, l_temp2;  Word16 level, i;  l_temp1 = 0L;                                           move32 ();  for (i = count1; i < count2; i++)  {     l_temp1 = L_mac(l_temp1, 1, abs_s(data[ind_m*i+ind_a]));  }    l_temp2 = L_add(l_temp1, L_shl(*sub_level, sub(16, scale)));  *sub_level = extract_h(L_shl(l_temp1, scale));    for (i = 0; i < count1; i++)  {     l_temp2 = L_mac(l_temp2, 1, abs_s(data[ind_m*i+ind_a]));  }  level = extract_h(L_shl(l_temp2, scale));    return level;}/**************************************************************************** * *     Function     : filter_bank *     Purpose      : Divides input signal into 9-bands and calculas level of *                    the signal in each band  * ***************************************************************************/static void filter_bank(vadState1 *st,  /* i/o : State struct               */                        Word16 in[],   /* i   : input frame                */                        Word16 level[] /* 0   : signal levels at each band */                        ){  Word16 i;  Word16 tmp_buf[FRAME_LEN];  /* calculate the filter bank */  first_filter_stage(in, tmp_buf, st->a_data5[0]);    for (i = 0; i < FRAME_LEN/4; i++)  {     filter5(&tmp_buf[4*i], &tmp_buf[4*i+2], st->a_data5[1]);     filter5(&tmp_buf[4*i+1], &tmp_buf[4*i+3], st->a_data5[2]);  }  for (i = 0; i < FRAME_LEN/8; i++)  {     filter3(&tmp_buf[8*i+0], &tmp_buf[8*i+4], &st->a_data3[0]);     filter3(&tmp_buf[8*i+2], &tmp_buf[8*i+6], &st->a_data3[1]);     filter3(&tmp_buf[8*i+3], &tmp_buf[8*i+7], &st->a_data3[4]);  }    for (i = 0; i < FRAME_LEN/16; i++)  {     filter3(&tmp_buf[16*i+0], &tmp_buf[16*i+8], &st->a_data3[2]);     filter3(&tmp_buf[16*i+4], &tmp_buf[16*i+12], &st->a_data3[3]);  }    /* calculate levels in each frequency band */    /* 3000 - 4000 Hz*/  level[8] = level_calculation(tmp_buf, &st->sub_level[8], FRAME_LEN/4-8,                               FRAME_LEN/4, 4, 1, 15);  move16 ();  /* 2500 - 3000 Hz*/    level[7] = level_calculation(tmp_buf, &st->sub_level[7], FRAME_LEN/8-4,                               FRAME_LEN/8, 8, 7, 16);  move16 ();  /* 2000 - 2500 Hz*/  level[6] = level_calculation(tmp_buf, &st->sub_level[6], FRAME_LEN/8-4,                               FRAME_LEN/8, 8, 3, 16);  move16 ();  /* 1500 - 2000 Hz*/  level[5] = level_calculation(tmp_buf, &st->sub_level[5], FRAME_LEN/8-4,                               FRAME_LEN/8, 8, 2, 16);  move16 ();  /* 1000 - 1500 Hz*/  level[4] = level_calculation(tmp_buf, &st->sub_level[4], FRAME_LEN/8-4,                               FRAME_LEN/8, 8, 6, 16);  move16 ();  /* 750 - 1000 Hz*/  level[3] = level_calculation(tmp_buf, &st->sub_level[3], FRAME_LEN/16-2,                               FRAME_LEN/16, 16, 4, 16);  move16 ();  /* 500 - 750 Hz*/  level[2] = level_calculation(tmp_buf, &st->sub_level[2], FRAME_LEN/16-2,                               FRAME_LEN/16, 16, 12, 16);  move16 ();  /* 250 - 500 Hz*/  level[1] = level_calculation(tmp_buf, &st->sub_level[1], FRAME_LEN/16-2,                               FRAME_LEN/16, 16, 8, 16);  move16 ();  /* 0 - 250 Hz*/  level[0] = level_calculation(tmp_buf, &st->sub_level[0], FRAME_LEN/16-2,                               FRAME_LEN/16, 16, 0, 16);  move16 ();}/**************************************************************************** * *     Function   : update_cntrl *     Purpose    : Control update of the background noise estimate. *     Inputs     : pitch:      flags for pitch detection *                  stat_count: stationary counter *                  tone:       flags indicating presence of a tone *                  complex:      flags for complex  detection *                  vadreg:     intermediate VAD flags *     Output     : stat_count: stationary counter * ***************************************************************************/static void update_cntrl(vadState1 *st,  /* i/o : State struct                       */                         Word16 level[] /* i   : sub-band levels of the input frame */                         ){  Word16 i, temp, stat_rat, exp;  Word16 num, denom;  Word16 alpha;   /* handle highband complex signal input  separately       */  /* if ther has been highband correlation for some time    */  /* make sure that the VAD update speed is low for a while */  test ();  if (st->complex_warning != 0)  {     test ();     if (sub(st->stat_count, CAD_MIN_STAT_COUNT) < 0)     {        st->stat_count = CAD_MIN_STAT_COUNT;              move16 ();         }  }  /* NB stat_count is allowed to be decreased by one below again  */  /* deadlock in speech is not possible unless the signal is very */  /* complex and need a high rate                                 */  /* if fullband pitch or tone have been detected for a while, initialize stat_count */  logic16 (); test (); logic16 (); test ();  if ((sub((st->pitch & 0x6000), 0x6000) == 0) ||      (sub((st->tone & 0x7c00), 0x7c00) == 0))  {     st->stat_count = STAT_COUNT;                          move16 ();    }  else  {     /* if 8 last vad-decisions have been "0", reinitialize stat_count */     logic16 (); test ();     if ((st->vadreg & 0x7f80) == 0)      {         st->stat_count = STAT_COUNT;                       move16 ();     }     else     {        stat_rat = 0;                                      move16 ();        for (i = 0; i < COMPLEN; i++)        {           test ();           if (sub(level[i], st->ave_level[i]) > 0)           {              num = level[i];                              move16 ();              denom = st->ave_level[i];                    move16 ();           }           else           {              num = st->ave_level[i];                      move16 ();              denom = level[i];                            move16 ();           }           /* Limit nimimum value of num and denom to STAT_THR_LEVEL */           test ();           if (sub(num, STAT_THR_LEVEL) < 0)           {              num = STAT_THR_LEVEL;                        move16 ();           }           test ();           if (sub(denom, STAT_THR_LEVEL) < 0)           {              denom = STAT_THR_LEVEL;                      move16 ();           }                      exp = norm_s(denom);           denom = shl(denom, exp);                      /* stat_rat = num/denom * 64 */           temp = div_s(shr(num, 1), denom);           stat_rat = add(stat_rat, shr(temp, sub(8, exp)));        }                /* compare stat_rat with a threshold and update stat_count */        test ();        if (sub(stat_rat, STAT_THR) > 0)        {           st->stat_count = STAT_COUNT;                    move16 ();        }        else        {           logic16 ();test ();

⌨️ 快捷键说明

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