Ignore:
Timestamp:
Feb 25, 2006 2:04:42 AM (18 years ago)
Author:
bennylp
Message:

Synched with documentation

File:
1 moved

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/silencedet.c

    r222 r228  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
    19 #include <pjmedia/vad.h> 
     19#include <pjmedia/silencedet.h> 
    2020#include <pjmedia/errno.h> 
    2121#include <pj/assert.h> 
     
    2424 
    2525 
    26 #define THIS_FILE   "vad.c" 
    27  
    28 typedef enum pjmedia_vad_mode { 
     26#define THIS_FILE   "silencedet.c" 
     27 
     28typedef enum pjmedia_silence_det_mode { 
    2929    VAD_MODE_NONE, 
    3030    VAD_MODE_FIXED, 
    3131    VAD_MODE_ADAPTIVE 
    32 } pjmedia_vad_mode; 
     32} pjmedia_silence_det_mode; 
    3333 
    3434 
    3535/** 
    36  * This structure holds the vad state. 
     36 * This structure holds the silence detector state. 
    3737 */ 
    38 struct pjmedia_vad 
     38struct pjmedia_silence_det 
    3939{ 
    4040    int       mode;             /**< VAD mode.                              */ 
     
    6060 
    6161 
    62 PJ_DEF(pj_status_t) pjmedia_vad_create( pj_pool_t *pool, 
    63                                         pjmedia_vad **p_vad) 
    64 { 
    65     pjmedia_vad *vad; 
    66  
    67     PJ_ASSERT_RETURN(pool && p_vad, PJ_EINVAL); 
    68  
    69     vad = pj_pool_zalloc(pool, sizeof(struct pjmedia_vad)); 
    70  
    71     vad->weakest_signal = 0xFFFFFFFFUL; 
    72     vad->loudest_silence = 0; 
    73     vad->signal_cnt = 0; 
    74     vad->silence_cnt = 0; 
     62PJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool, 
     63                                                pjmedia_silence_det **p_sd) 
     64{ 
     65    pjmedia_silence_det *sd; 
     66 
     67    PJ_ASSERT_RETURN(pool && p_sd, PJ_EINVAL); 
     68 
     69    sd = pj_pool_zalloc(pool, sizeof(struct pjmedia_silence_det)); 
     70 
     71    sd->weakest_signal = 0xFFFFFFFFUL; 
     72    sd->loudest_silence = 0; 
     73    sd->signal_cnt = 0; 
     74    sd->silence_cnt = 0; 
    7575     
    7676    /* Restart in adaptive, silent mode */ 
    77     vad->in_talk = PJ_FALSE; 
    78     pjmedia_vad_set_adaptive( vad, 160 ); 
    79  
    80     *p_vad = vad; 
    81     return PJ_SUCCESS; 
    82 } 
    83  
    84 PJ_DEF(pj_status_t) pjmedia_vad_set_adaptive( pjmedia_vad *vad, 
    85                                               unsigned frame_size) 
    86 { 
    87     PJ_ASSERT_RETURN(vad && frame_size, PJ_EINVAL); 
    88  
    89     vad->frame_size = frame_size; 
    90     vad->mode = VAD_MODE_ADAPTIVE; 
    91     vad->min_signal_cnt = 10; 
    92     vad->min_silence_cnt = 64; 
    93     vad->recalc_cnt = 250; 
    94     vad->cur_threshold = 20; 
    95  
    96     return PJ_SUCCESS; 
    97 } 
    98  
    99 PJ_DEF(pj_status_t) pjmedia_vad_set_fixed( pjmedia_vad *vad, 
    100                                            unsigned frame_size, 
    101                                            unsigned threshold ) 
    102 { 
    103     PJ_ASSERT_RETURN(vad && frame_size, PJ_EINVAL); 
    104  
    105     vad->mode = VAD_MODE_FIXED; 
    106     vad->frame_size = frame_size; 
    107     vad->cur_threshold = threshold; 
    108  
    109     return PJ_SUCCESS; 
    110 } 
    111  
    112 PJ_DEF(pj_status_t) pjmedia_vad_disable( pjmedia_vad *vad ) 
    113 { 
    114     PJ_ASSERT_RETURN(vad, PJ_EINVAL); 
    115  
    116     vad->mode = VAD_MODE_NONE; 
    117  
    118     return PJ_SUCCESS; 
    119 } 
    120  
    121  
    122 PJ_DEF(pj_int32_t) pjmedia_vad_calc_avg_signal(const pj_int16_t samples[], 
    123                                                pj_size_t count) 
     77    sd->in_talk = PJ_FALSE; 
     78    pjmedia_silence_det_set_adaptive( sd, 160 ); 
     79 
     80    *p_sd = sd; 
     81    return PJ_SUCCESS; 
     82} 
     83 
     84PJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive( pjmedia_silence_det *sd, 
     85                                                      unsigned frame_size) 
     86{ 
     87    PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 
     88 
     89    sd->frame_size = frame_size; 
     90    sd->mode = VAD_MODE_ADAPTIVE; 
     91    sd->min_signal_cnt = 10; 
     92    sd->min_silence_cnt = 64; 
     93    sd->recalc_cnt = 250; 
     94    sd->cur_threshold = 20; 
     95 
     96    return PJ_SUCCESS; 
     97} 
     98 
     99PJ_DEF(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd, 
     100                                                   unsigned frame_size, 
     101                                                   unsigned threshold ) 
     102{ 
     103    PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 
     104 
     105    sd->mode = VAD_MODE_FIXED; 
     106    sd->frame_size = frame_size; 
     107    sd->cur_threshold = threshold; 
     108 
     109    return PJ_SUCCESS; 
     110} 
     111 
     112PJ_DEF(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd ) 
     113{ 
     114    PJ_ASSERT_RETURN(sd, PJ_EINVAL); 
     115 
     116    sd->mode = VAD_MODE_NONE; 
     117 
     118    return PJ_SUCCESS; 
     119} 
     120 
     121 
     122PJ_DEF(pj_int32_t) pjmedia_silence_det_calc_avg_signal(const pj_int16_t samples[], 
     123                                                       pj_size_t count) 
    124124{ 
    125125    pj_uint32_t sum = 0; 
     
    141141} 
    142142 
    143 PJ_DEF(pj_bool_t) pjmedia_vad_detect_silence( pjmedia_vad *vad, 
    144                                               const pj_int16_t samples[], 
    145                                               pj_size_t count, 
    146                                               pj_int32_t *p_level) 
     143PJ_DEF(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 
     144                                                      const pj_int16_t samples[], 
     145                                                      pj_size_t count, 
     146                                                      pj_int32_t *p_level) 
    147147{ 
    148148    pj_uint32_t level; 
     
    150150 
    151151    /* Always return false if VAD is disabled */ 
    152     if (vad->mode == VAD_MODE_NONE) { 
     152    if (sd->mode == VAD_MODE_NONE) { 
    153153        if (p_level) 
    154154            *p_level = -1; 
     
    157157     
    158158    /* Calculate average signal level. */ 
    159     level = pjmedia_vad_calc_avg_signal(samples, count); 
     159    level = pjmedia_silence_det_calc_avg_signal(samples, count); 
    160160     
    161161    /* Report to caller, if required. */ 
     
    167167     
    168168    /* Do we have signal? */ 
    169     have_signal = level > vad->cur_threshold; 
     169    have_signal = level > sd->cur_threshold; 
    170170     
    171171    /* We we're in transition between silence and signel, increment the  
     
    173173     * frames. 
    174174     */ 
    175     if (vad->in_talk != have_signal) { 
     175    if (sd->in_talk != have_signal) { 
    176176        unsigned limit; 
    177177 
    178         vad->cur_cnt++; 
    179  
    180         limit = (vad->in_talk ? vad->min_silence_cnt :  
    181                                 vad->min_signal_cnt); 
    182  
    183         if (vad->cur_cnt > limit) { 
     178        sd->cur_cnt++; 
     179 
     180        limit = (sd->in_talk ? sd->min_silence_cnt :  
     181                                sd->min_signal_cnt); 
     182 
     183        if (sd->cur_cnt > limit) { 
    184184 
    185185            /* Swap mode */ 
    186             vad->in_talk = !vad->in_talk; 
     186            sd->in_talk = !sd->in_talk; 
    187187             
    188188            /* Restart adaptive cur_threshold measurements */ 
    189             vad->weakest_signal = 0xFFFFFFFFUL; 
    190             vad->loudest_silence = 0; 
    191             vad->signal_cnt = 0; 
    192             vad->silence_cnt = 0; 
     189            sd->weakest_signal = 0xFFFFFFFFUL; 
     190            sd->loudest_silence = 0; 
     191            sd->signal_cnt = 0; 
     192            sd->silence_cnt = 0; 
    193193        } 
    194194 
    195195    } else { 
    196196        /* Reset frame count */ 
    197         vad->cur_cnt = 0; 
    198     } 
    199      
    200     /* For fixed threshold vad, everything is done. */ 
    201     if (vad->mode == VAD_MODE_FIXED) { 
    202         return !vad->in_talk; 
     197        sd->cur_cnt = 0; 
     198    } 
     199     
     200    /* For fixed threshold sd, everything is done. */ 
     201    if (sd->mode == VAD_MODE_FIXED) { 
     202        return !sd->in_talk; 
    203203    } 
    204204     
     
    206206    /* Count the number of silent and signal frames and calculate min/max */ 
    207207    if (have_signal) { 
    208         if (level < vad->weakest_signal) 
    209             vad->weakest_signal = level; 
    210         vad->signal_cnt++; 
     208        if (level < sd->weakest_signal) 
     209            sd->weakest_signal = level; 
     210        sd->signal_cnt++; 
    211211    } 
    212212    else { 
    213         if (level > vad->loudest_silence) 
    214             vad->loudest_silence = level; 
    215         vad->silence_cnt++; 
     213        if (level > sd->loudest_silence) 
     214            sd->loudest_silence = level; 
     215        sd->silence_cnt++; 
    216216    } 
    217217 
     
    219219     * silence/signal frames. 
    220220     */ 
    221     if ((vad->signal_cnt + vad->silence_cnt) > vad->recalc_cnt) { 
     221    if ((sd->signal_cnt + sd->silence_cnt) > sd->recalc_cnt) { 
    222222         
    223223        /* Adjust silence threshold by looking at the proportions of 
    224224         * signal and silence frames. 
    225225         */ 
    226         if (vad->signal_cnt >= vad->recalc_cnt) { 
     226        if (sd->signal_cnt >= sd->recalc_cnt) { 
    227227            /* All frames where signal frames. 
    228228             * Increase silence threshold. 
    229229             */ 
    230             vad->cur_threshold += (vad->weakest_signal - vad->cur_threshold)/4; 
     230            sd->cur_threshold += (sd->weakest_signal - sd->cur_threshold)/4; 
    231231            PJ_LOG(6,(THIS_FILE, "Vad cur_threshold increased to %d", 
    232                       vad->cur_threshold)); 
    233         } 
    234         else if (vad->silence_cnt >= vad->recalc_cnt) { 
     232                      sd->cur_threshold)); 
     233        } 
     234        else if (sd->silence_cnt >= sd->recalc_cnt) { 
    235235            /* All frames where silence frames. 
    236236             * Decrease silence threshold. 
    237237             */ 
    238             vad->cur_threshold = (vad->cur_threshold+vad->loudest_silence)/2+1; 
     238            sd->cur_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1; 
    239239            PJ_LOG(6,(THIS_FILE, "Vad cur_threshold decreased to %d", 
    240                       vad->cur_threshold)); 
     240                      sd->cur_threshold)); 
    241241        } 
    242242        else {  
     
    244244 
    245245            /* Adjust according to signal/silence proportions. */ 
    246             if (vad->signal_cnt > vad->silence_cnt * 2) 
    247                 vad->cur_threshold++; 
    248             else if (vad->silence_cnt >  vad->signal_cnt* 2) 
    249                 vad->cur_threshold--; 
     246            if (sd->signal_cnt > sd->silence_cnt * 2) 
     247                sd->cur_threshold++; 
     248            else if (sd->silence_cnt >  sd->signal_cnt* 2) 
     249                sd->cur_threshold--; 
    250250            else 
    251251                updated = PJ_FALSE; 
     
    254254                PJ_LOG(6,(THIS_FILE, 
    255255                          "Vad cur_threshold updated to %d", 
    256                           vad->cur_threshold)); 
     256                          sd->cur_threshold)); 
    257257            } 
    258258        } 
    259259 
    260260        /* Reset. */ 
    261         vad->weakest_signal = 0xFFFFFFFFUL; 
    262         vad->loudest_silence = 0; 
    263         vad->signal_cnt = 0; 
    264         vad->silence_cnt = 0; 
    265     } 
    266      
    267     return !vad->in_talk; 
    268 } 
    269  
     261        sd->weakest_signal = 0xFFFFFFFFUL; 
     262        sd->loudest_silence = 0; 
     263        sd->signal_cnt = 0; 
     264        sd->silence_cnt = 0; 
     265    } 
     266     
     267    return !sd->in_talk; 
     268} 
     269 
Note: See TracChangeset for help on using the changeset viewer.