Changeset 203


Ignore:
Timestamp:
Feb 20, 2006 1:28:25 AM (18 years ago)
Author:
bennylp
Message:

Added conference bridge prototype

Location:
pjproject/trunk/pjmedia
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/build

    • Property svn:ignore
      •  

        old new  
        22*.opt 
        33.pjmedia* 
         4*.plg 
  • pjproject/trunk/pjmedia/build/pjmedia.dsp

    r202 r203  
    8888# Begin Source File 
    8989 
     90SOURCE=..\src\pjmedia\audio_conf.c 
     91# End Source File 
     92# Begin Source File 
     93 
    9094SOURCE=..\src\pjmedia\codec.c 
    9195# End Source File 
     
    156160 
    157161# PROP Default_Filter "h;hpp;hxx;hm;inl" 
     162# Begin Source File 
     163 
     164SOURCE=..\include\pjmedia\audio_conf.h 
     165# End Source File 
    158166# Begin Source File 
    159167 
  • pjproject/trunk/pjmedia/include/pjmedia/stream.h

    r189 r203  
    9999 
    100100/** 
     101 * Stream ports. 
     102 */ 
     103struct pjmedia_stream_port 
     104{ 
     105    /** 
     106     * Sink port. 
     107     */ 
     108    pj_status_t (*put_frame)(const pj_int16_t *frame, pj_size_t frame_cnt); 
     109 
     110    /** 
     111     * Source port. 
     112     */ 
     113    pj_status_t (*get_frame)(pj_int16_t *frame, pj_size_t frame_cnt); 
     114}; 
     115 
     116 
     117/** 
    101118 * Create a media stream based on the specified stream parameter. 
    102119 * All channels in the stream initially will be inactive. 
  • pjproject/trunk/pjmedia/include/pjmedia/types.h

    r188 r203  
    152152 
    153153/** 
     154 * @see pjmedia_stream_port 
     155 */ 
     156typedef struct pjmedia_stream_port pjmedia_stream_port; 
     157 
     158/** 
    154159 * Typedef for media stream. 
    155160 */ 
  • pjproject/trunk/pjmedia/include/pjmedia/vad.h

    r202 r203  
    2727#include <pjmedia/types.h> 
    2828 
     29PJ_BEGIN_DECL 
     30 
    2931 
    3032/** 
    31  * Opaque data type for pjmedia vad. 
     33 * @see pjmedia_vad 
    3234 */ 
    3335typedef struct pjmedia_vad  pjmedia_vad; 
     
    4951 
    5052/** 
     53 * Set the vad to operate in adaptive mode. 
     54 * 
     55 * @param vad               The vad 
     56 * @param frame_size Number of samplse per frame. 
     57 * 
     58 * @return                  PJ_SUCCESS on success. 
     59 */ 
     60PJ_DECL(pj_status_t) pjmedia_vad_set_adaptive( pjmedia_vad *vad, 
     61                                               unsigned frame_size); 
     62 
     63 
     64/** 
     65 * Set the vad to operate in fixed threshold mode. 
     66 * 
     67 * @param vad               The vad 
     68 * @param frame_size Number of samplse per frame. 
     69 * @param threshold         The silence threshold. 
     70 * 
     71 * @return                  PJ_SUCCESS on success. 
     72 */ 
     73PJ_DECL(pj_status_t) pjmedia_vad_set_fixed( pjmedia_vad *vad, 
     74                                            unsigned frame_size, 
     75                                            unsigned threshold ); 
     76 
     77/** 
     78 * Disable the vad. 
     79 * 
     80 * @param vad           The vad 
     81 * 
     82 * @return              PJ_SUCCESS on success. 
     83 */ 
     84PJ_DECL(pj_status_t) pjmedia_vad_disable( pjmedia_vad *vad ); 
     85 
     86 
     87/** 
    5188 * Calculate average signal level for the given samples. 
    5289 * 
     
    5794 *                      divided by number of samples. 
    5895 */ 
    59 PJ_DECL(pj_uint32_t) pjmedia_vad_calc_avg_signal_level( pj_int16_t samples[], 
    60                                                         pj_size_t count ); 
     96PJ_DECL(pj_int32_t) pjmedia_vad_calc_avg_signal( const pj_int16_t samples[], 
     97                                                 pj_size_t count ); 
    6198 
    6299 
     
    67104 * @param samples       Pointer to 16-bit PCM input samples. 
    68105 * @param count         Number of samples in the input. 
    69  * @param p_silence     Pointer to receive the silence detection result. 
    70  *                      Non-zero value indicates that that input is considered 
    71  *                      as silence. 
     106 * @param p_level       Optional pointer to receive average signal level 
     107 *                      of the input samples. 
    72108 * 
    73109 * @return              PJ_SUCCESS on success. 
    74110 */ 
    75 PJ_DECL(pj_status_t) pjmedia_vad_detect_silence( pjmedia_vad *vad, 
    76                                                 pj_int16_t samples[], 
    77                                                 pj_size_t count, 
    78                                                  pj_bool_t *p_silence); 
     111PJ_DECL(pj_bool_t) pjmedia_vad_detect_silence( pjmedia_vad *vad, 
     112                                               const pj_int16_t samples[], 
     113                                              pj_size_t count, 
     114                                               pj_int32_t *p_level); 
    79115 
    80116 
     117PJ_END_DECL 
    81118 
    82119#endif  /* __PJMEDIA_VAD_H__ */ 
  • pjproject/trunk/pjmedia/src/pjmedia/g711.c

    r176 r203  
    3535 
    3636/* Algorithm prototypes. */ 
    37 static unsigned char linear2alaw(int            pcm_val);   /* 2's complement (16-bit range) */ 
    38 static int           alaw2linear(unsigned char  a_val); 
    39 static unsigned char linear2ulaw(int            pcm_val); 
    40 static int           ulaw2linear(unsigned char  u_val); 
     37unsigned char linear2alaw(int           pcm_val);   /* 2's complement (16-bit range) */ 
     38int           alaw2linear(unsigned char a_val); 
     39unsigned char linear2ulaw(int           pcm_val); 
     40int           ulaw2linear(unsigned char u_val); 
    4141 
    4242/* Prototypes for G711 factory */ 
     
    594594 * John Wiley & Sons, pps 98-111 and 472-476. 
    595595 */ 
    596 static unsigned char 
     596unsigned char 
    597597linear2ulaw( 
    598598        int             pcm_val)        /* 2's complement (16-bit range) */ 
  • pjproject/trunk/pjmedia/src/pjmedia/vad.c

    r202 r203  
    1919#include <pjmedia/vad.h> 
    2020#include <pjmedia/errno.h> 
    21  
     21#include <pj/assert.h> 
     22#include <pj/log.h> 
     23#include <pj/pool.h> 
     24 
     25 
     26#define THIS_FILE   "vad.c" 
     27 
     28typedef enum pjmedia_vad_mode { 
     29    VAD_MODE_NONE, 
     30    VAD_MODE_FIXED, 
     31    VAD_MODE_ADAPTIVE 
     32} pjmedia_vad_mode; 
     33 
     34 
     35/** 
     36 * This structure holds the vad state. 
     37 */ 
     38struct pjmedia_vad 
     39{ 
     40    int       mode;             /**< VAD mode.                              */ 
     41    unsigned  frame_size;       /**< Samples per frame.                     */ 
     42 
     43 
     44    unsigned  min_signal_cnt;   /**< # of signal frames.before talk burst   */ 
     45    unsigned  min_silence_cnt;  /**< # of silence frames before silence.    */ 
     46    unsigned  recalc_cnt;       /**< # of frames before adaptive recalc.    */ 
     47 
     48    pj_bool_t in_talk;          /**< In talk burst?                         */ 
     49    unsigned  cur_cnt;          /**< # of frames in current mode.           */ 
     50    unsigned  signal_cnt;       /**< # of signal frames received.           */ 
     51    unsigned  silence_cnt;      /**< # of silence frames received           */ 
     52    unsigned  cur_threshold;    /**< Current silence threshold.             */ 
     53    unsigned  weakest_signal;   /**< Weakest signal detected.               */ 
     54    unsigned  loudest_silence;  /**< Loudest silence detected.              */ 
     55}; 
     56 
     57 
     58 
     59unsigned char linear2ulaw(int           pcm_val); 
    2260 
    2361PJ_DEF(pj_status_t) pjmedia_vad_create( pj_pool_t *pool, 
    2462                                        pjmedia_vad **p_vad) 
    2563{ 
    26     return PJ_EINVALIDOP; 
    27 } 
    28  
    29 PJ_DEF(pj_uint32_t) pjmedia_vad_calc_avg_signal_level(pj_int16_t samples[], 
    30                                                       pj_size_t count) 
    31 { 
    32     return PJ_EINVALIDOP; 
    33 } 
    34  
    35 PJ_DEF(pj_status_t) pjmedia_vad_detect_silence( pjmedia_vad *vad, 
    36                                                 pj_int16_t samples[], 
    37                                                 pj_size_t count, 
    38                                                 pj_bool_t *p_silence) 
    39 { 
    40     return PJ_EINVALIDOP; 
    41 } 
    42  
     64    pjmedia_vad *vad; 
     65 
     66    PJ_ASSERT_RETURN(pool && p_vad, PJ_EINVAL); 
     67 
     68    vad = pj_pool_zalloc(pool, sizeof(struct pjmedia_vad)); 
     69 
     70    vad->weakest_signal = 0xFFFFFFFFUL; 
     71    vad->loudest_silence = 0; 
     72    vad->signal_cnt = 0; 
     73    vad->silence_cnt = 0; 
     74     
     75    /* Restart in adaptive, silent mode */ 
     76    vad->in_talk = PJ_FALSE; 
     77    pjmedia_vad_set_adaptive( vad, 160 ); 
     78 
     79    *p_vad = vad; 
     80    return PJ_SUCCESS; 
     81} 
     82 
     83PJ_DEF(pj_status_t) pjmedia_vad_set_adaptive( pjmedia_vad *vad, 
     84                                              unsigned frame_size) 
     85{ 
     86    PJ_ASSERT_RETURN(vad && frame_size, PJ_EINVAL); 
     87 
     88    vad->frame_size = frame_size; 
     89    vad->mode = VAD_MODE_ADAPTIVE; 
     90    vad->min_signal_cnt = 3; 
     91    vad->min_silence_cnt = 20; 
     92    vad->recalc_cnt = 30; 
     93    vad->cur_threshold = 20; 
     94 
     95    return PJ_SUCCESS; 
     96} 
     97 
     98PJ_DEF(pj_status_t) pjmedia_vad_set_fixed( pjmedia_vad *vad, 
     99                                           unsigned frame_size, 
     100                                           unsigned threshold ) 
     101{ 
     102    PJ_ASSERT_RETURN(vad && frame_size, PJ_EINVAL); 
     103 
     104    vad->mode = VAD_MODE_FIXED; 
     105    vad->frame_size = frame_size; 
     106    vad->cur_threshold = threshold; 
     107 
     108    return PJ_SUCCESS; 
     109} 
     110 
     111PJ_DEF(pj_status_t) pjmedia_vad_disable( pjmedia_vad *vad ) 
     112{ 
     113    PJ_ASSERT_RETURN(vad, PJ_EINVAL); 
     114 
     115    vad->mode = VAD_MODE_NONE; 
     116 
     117    return PJ_SUCCESS; 
     118} 
     119 
     120 
     121PJ_DEF(pj_int32_t) pjmedia_vad_calc_avg_signal(const pj_int16_t samples[], 
     122                                               pj_size_t count) 
     123{ 
     124    pj_uint32_t sum = 0; 
     125     
     126    const pj_int16_t * pcm = samples; 
     127    const pj_int16_t * end = samples + count; 
     128 
     129    if (count==0) 
     130        return 0; 
     131 
     132    while (pcm != end) { 
     133        if (*pcm < 0) 
     134            sum -= *pcm++; 
     135        else 
     136            sum += *pcm++; 
     137    } 
     138     
     139    return (pj_int32_t)(sum / count); 
     140} 
     141 
     142PJ_DEF(pj_bool_t) pjmedia_vad_detect_silence( pjmedia_vad *vad, 
     143                                              const pj_int16_t samples[], 
     144                                              pj_size_t count, 
     145                                              pj_int32_t *p_level) 
     146{ 
     147    pj_uint32_t level; 
     148    pj_bool_t have_signal; 
     149 
     150    /* Always return false if VAD is disabled */ 
     151    if (vad->mode == VAD_MODE_NONE) { 
     152        if (p_level) 
     153            *p_level = -1; 
     154        return PJ_FALSE; 
     155    } 
     156     
     157    /* Calculate average signal level. */ 
     158    level = pjmedia_vad_calc_avg_signal(samples, count); 
     159     
     160    /* Report to caller, if required. */ 
     161    if (p_level) 
     162        *p_level = level; 
     163 
     164    /* Convert PCM level to ulaw */ 
     165    level = linear2ulaw(level) ^ 0xff; 
     166     
     167    /* Do we have signal? */ 
     168    have_signal = level > vad->cur_threshold; 
     169     
     170    /* We we're in transition between silence and signel, increment the  
     171     * current frame counter. We will only switch mode when we have enough 
     172     * frames. 
     173     */ 
     174    if (vad->in_talk != have_signal) { 
     175        unsigned limit; 
     176 
     177        vad->cur_cnt++; 
     178 
     179        limit = (vad->in_talk ? vad->min_silence_cnt :  
     180                                vad->min_signal_cnt); 
     181 
     182        if (vad->cur_cnt > limit) { 
     183 
     184            /* Swap mode */ 
     185            vad->in_talk = !vad->in_talk; 
     186             
     187            /* Restart adaptive cur_threshold measurements */ 
     188            vad->weakest_signal = 0xFFFFFFFFUL; 
     189            vad->loudest_silence = 0; 
     190            vad->signal_cnt = 0; 
     191            vad->silence_cnt = 0; 
     192        } 
     193 
     194    } else { 
     195        /* Reset frame count */ 
     196        vad->cur_cnt = 0; 
     197    } 
     198     
     199    /* For fixed threshold vad, everything is done. */ 
     200    if (vad->mode == VAD_MODE_FIXED) { 
     201        return !vad->in_talk; 
     202    } 
     203     
     204 
     205    /* Count the number of silent and signal frames and calculate min/max */ 
     206    if (have_signal) { 
     207        if (level < vad->weakest_signal) 
     208            vad->weakest_signal = level; 
     209        vad->signal_cnt++; 
     210    } 
     211    else { 
     212        if (level > vad->loudest_silence) 
     213            vad->loudest_silence = level; 
     214        vad->silence_cnt++; 
     215    } 
     216 
     217    /* See if we have had enough frames to look at proportions of  
     218     * silence/signal frames. 
     219     */ 
     220    if ((vad->signal_cnt + vad->silence_cnt) > vad->recalc_cnt) { 
     221         
     222        /* Adjust silence threshold by looking at the proportions of 
     223         * signal and silence frames. 
     224         */ 
     225        if (vad->signal_cnt >= vad->recalc_cnt) { 
     226            /* All frames where signal frames. 
     227             * Increase silence threshold. 
     228             */ 
     229            vad->cur_threshold += (vad->weakest_signal - vad->cur_threshold)/4; 
     230            PJ_LOG(5,(THIS_FILE, "Vad cur_threshold increased to %d", 
     231                      vad->cur_threshold)); 
     232        } 
     233        else if (vad->silence_cnt >= vad->recalc_cnt) { 
     234            /* All frames where silence frames. 
     235             * Decrease silence threshold. 
     236             */ 
     237            vad->cur_threshold = (vad->cur_threshold+vad->loudest_silence)/2+1; 
     238            PJ_LOG(5,(THIS_FILE, "Vad cur_threshold decreased to %d", 
     239                      vad->cur_threshold)); 
     240        } 
     241        else {  
     242            pj_bool_t updated = PJ_TRUE; 
     243 
     244            /* Adjust according to signal/silence proportions. */ 
     245            if (vad->signal_cnt > vad->silence_cnt * 2) 
     246                vad->cur_threshold++; 
     247            else if (vad->silence_cnt >  vad->signal_cnt* 2) 
     248                vad->cur_threshold--; 
     249            else 
     250                updated = PJ_FALSE; 
     251 
     252            if (updated) { 
     253                PJ_LOG(5,(THIS_FILE, 
     254                          "Vad cur_threshold updated to %d", 
     255                          vad->cur_threshold)); 
     256            } 
     257        } 
     258 
     259        /* Reset. */ 
     260        vad->weakest_signal = 0xFFFFFFFFUL; 
     261        vad->loudest_silence = 0; 
     262        vad->signal_cnt = 0; 
     263        vad->silence_cnt = 0; 
     264    } 
     265     
     266    return !vad->in_talk; 
     267} 
     268 
Note: See TracChangeset for help on using the changeset viewer.