Changeset 229 for pjproject/trunk


Ignore:
Timestamp:
Feb 25, 2006 9:15:49 PM (19 years ago)
Author:
bennylp
Message:

Fixed echo in conference, and add ability to shrink buffer in jitter buffer

Location:
pjproject/trunk/pjmedia
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/build/pjmedia.dsp

    r228 r229  
    6666# PROP Target_Dir "" 
    6767# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 
    68 # ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../src/pjmedia/portaudio" /D "_DEBUG" /D "PA_NO_ASIO" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c 
     68# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../src/pjmedia/portaudio" /D "_DEBUG" /D "PA_NO_ASIO" /D "PA_NO_WMME" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c 
    6969# SUBTRACT CPP /YX 
    7070# ADD BASE RSC /l 0x409 /d "_DEBUG" 
  • pjproject/trunk/pjmedia/include/pjmedia/silencedet.h

    r228 r229  
    8686 
    8787/** 
    88  * Calculate average signal level for the given samples. 
    89  * 
    90  * @param samples       Pointer to 16-bit PCM samples. 
    91  * @param count         Number of samples in the input. 
    92  * 
    93  * @return              The average signal level, which simply is total level 
    94  *                      divided by number of samples. 
    95  */ 
    96 PJ_DECL(pj_int32_t) pjmedia_silence_det_calc_avg_signal( const pj_int16_t samples[], 
    97                                                          pj_size_t count ); 
    98  
    99  
    100 /** 
    101  * Perform voice activity detection on the given input samples. 
     88 * Perform voice activity detection on the given input samples. This 
     89 * function uses #pjmedia_calc_avg_signal() and #pjmedia_silence_det_apply() 
     90 * for its calculation. 
    10291 * 
    10392 * @param sd            The silence detector instance. 
     
    10998 * @return              PJ_SUCCESS on success. 
    11099 */ 
    111 PJ_DECL(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 
    112                                                        const pj_int16_t samples[], 
    113                                                        pj_size_t count, 
    114                                                        pj_int32_t *p_level); 
     100PJ_DECL(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd, 
     101                                               const pj_int16_t samples[], 
     102                                               pj_size_t count, 
     103                                               pj_int32_t *p_level); 
     104 
     105 
     106/** 
     107 * Calculate average signal level for the given samples. 
     108 * 
     109 * @param samples       Pointer to 16-bit PCM samples. 
     110 * @param count         Number of samples in the input. 
     111 * 
     112 * @return              The average signal level, which simply is total level 
     113 *                      divided by number of samples. 
     114 */ 
     115PJ_DECL(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[], 
     116                                             pj_size_t count ); 
     117 
     118 
     119 
     120/** 
     121 * Perform voice activity detection, given the specified average signal 
     122 * level. 
     123 * 
     124 * @param sd            The silence detector instance. 
     125 * @param level         Signal level. 
     126 * 
     127 * @return              PJ_SUCCESS on success. 
     128 */ 
     129PJ_DECL(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd, 
     130                                              pj_uint32_t level); 
    115131 
    116132 
  • pjproject/trunk/pjmedia/src/pjmedia/conference.c

    r228 r229  
    9292    pj_snd_stream        *snd_rec;      /**< Sound recorder stream.         */ 
    9393    pj_snd_stream        *snd_player;   /**< Sound player stream.           */ 
     94    pj_mutex_t           *mutex;        /**< Conference mutex.              */ 
    9495    struct conf_port    **ports;        /**< Array of ports.                */ 
    9596    pj_uint16_t          *uns_buf;      /**< Buf for unsigned conversion    */ 
     
    100101}; 
    101102 
     103 
     104/* Extern */ 
     105unsigned char linear2ulaw(int pcm_val); 
    102106 
    103107/* Prototypes */ 
     
    261265    conf->uns_buf = pj_pool_zalloc(pool, samples_per_frame * 
    262266                                         sizeof(conf->uns_buf[0])); 
     267 
     268    /* Create mutex. */ 
     269    status = pj_mutex_create_simple(pool, "conf", &conf->mutex); 
     270    if (status != PJ_SUCCESS) 
     271        return status; 
     272 
     273 
    263274    /* Done */ 
    264275 
     
    365376    suspend_sound(conf); 
    366377    destroy_sound(conf); 
     378    pj_mutex_destroy(conf->mutex); 
    367379 
    368380    return PJ_SUCCESS; 
     
    386398                     PJ_EINVAL); 
    387399 
     400    pj_mutex_lock(conf->mutex); 
     401 
    388402    if (conf->port_cnt >= conf->max_ports) { 
    389403        pj_assert(!"Too many ports"); 
     404        pj_mutex_unlock(conf->mutex); 
    390405        return PJ_ETOOMANY; 
    391406    } 
     
    401416    /* Create port structure. */ 
    402417    status = create_conf_port(pool, conf, port_name, &conf_port); 
    403     if (status != PJ_SUCCESS) 
     418    if (status != PJ_SUCCESS) { 
     419        pj_mutex_unlock(conf->mutex); 
    404420        return status; 
     421    } 
    405422 
    406423    /* Set the port */ 
     
    413430    /* Done. */ 
    414431    *p_port = index; 
     432 
     433    pj_mutex_unlock(conf->mutex); 
    415434 
    416435    return PJ_SUCCESS; 
     
    462481    PJ_ASSERT_RETURN(conf->ports[src_slot] != NULL, PJ_EINVAL); 
    463482    PJ_ASSERT_RETURN(conf->ports[sink_slot] != NULL, PJ_EINVAL); 
     483 
     484    pj_mutex_lock(conf->mutex); 
    464485 
    465486    src_port = conf->ports[src_slot]; 
     
    481502    } 
    482503 
     504    pj_mutex_unlock(conf->mutex); 
     505 
    483506    return PJ_SUCCESS; 
    484507} 
     
    501524    PJ_ASSERT_RETURN(conf->ports[src_slot] != NULL, PJ_EINVAL); 
    502525    PJ_ASSERT_RETURN(conf->ports[sink_slot] != NULL, PJ_EINVAL); 
     526 
     527    pj_mutex_lock(conf->mutex); 
    503528 
    504529    src_port = conf->ports[src_slot]; 
     
    522547    } 
    523548 
     549    pj_mutex_unlock(conf->mutex); 
     550 
    524551    return PJ_SUCCESS; 
    525552} 
     
    545572     * device's threads! 
    546573     */ 
    547     //suspend_sound(conf); 
     574 
     575    pj_mutex_lock(conf->mutex); 
    548576 
    549577    conf_port = conf->ports[port]; 
     
    578606    --conf->port_cnt; 
    579607 
    580     /* Reactivate sound device if there are connections */ 
    581     if (conf->connect_cnt != 0) { 
    582         //resume_sound(conf); 
    583     } else { 
     608    /* Stop sound if there's no connection. */ 
     609    if (conf->connect_cnt == 0) { 
    584610        destroy_sound(conf); 
    585611    } 
    586612 
    587     pj_thread_sleep(60); 
     613    pj_mutex_unlock(conf->mutex); 
     614 
    588615    return PJ_SUCCESS; 
    589616} 
     
    659686    pjmedia_conf *conf = user_data; 
    660687    pj_int16_t *output_buf = output; 
    661     unsigned i, j; 
     688    unsigned ci, cj, i, j; 
    662689     
    663690    PJ_UNUSED_ARG(timestamp); 
     
    666693    TRACE_(("p")); 
    667694 
    668     /* Clear all port's tmp buffers. */ 
    669     for (i=0; i<conf->max_ports; ++i) { 
     695    pj_mutex_lock(conf->mutex); 
     696 
     697    /* Zero all port's temporary buffers. */ 
     698    for (i=0, ci=0; i<conf->max_ports && ci < conf->port_cnt; ++i) { 
    670699        struct conf_port *conf_port = conf->ports[i]; 
    671700        pj_uint32_t *sum_buf; 
    672701 
     702        /* Skip empty slot. */ 
    673703        if (!conf_port) 
    674704            continue; 
     705 
     706        ++ci; 
    675707 
    676708        conf_port->sources = 0; 
     
    681713    } 
    682714 
    683     /* Get frames from all ports, and "add" the signal  
     715    /* Get frames from all ports, and "mix" the signal  
    684716     * to sum_buf of all listeners of the port. 
    685717     */ 
    686     for (i=0; i<conf->max_ports; ++i) { 
     718    for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 
    687719        struct conf_port *conf_port = conf->ports[i]; 
    688720        pj_int32_t level; 
    689         pj_bool_t silence; 
    690721 
    691722        /* Skip empty port. */ 
     
    693724            continue; 
    694725 
     726        ++ci; 
     727 
    695728        /* Skip if we're not allowed to receive from this port. */ 
    696729        if (conf_port->rx_setting == PJMEDIA_PORT_DISABLE) { 
    697             TRACE_(("rxdis:%d ", i)); 
    698730            continue; 
    699731        } 
    700732 
    701733        /* Get frame from this port.  
    702          * If port has rx_buffer (e.g. sound port), then get the frame  
    703          * from the rx_buffer instead. 
     734         * For port zero (sound port), get the frame  from the rx_buffer 
     735         * instead. 
    704736         */ 
    705737        if (i==0) { 
     
    712744            } 
    713745 
     746            /* Skip if this port is muted/disabled. */ 
     747            if (conf_port->rx_setting != PJMEDIA_PORT_ENABLE) { 
     748                continue; 
     749            } 
     750 
     751 
     752            /* Skip if no port is listening to the microphone */ 
     753            if (conf_port->listener_cnt == 0) { 
     754                continue; 
     755            } 
     756 
    714757            rx_buf = conf_port->rx_buf[conf_port->rx_read]; 
    715758            for (j=0; j<conf->samples_per_frame; ++j) { 
     
    726769            pjmedia_port_get_frame(conf_port->port, &frame); 
    727770 
    728             if (frame.type == PJMEDIA_FRAME_TYPE_NONE) 
     771           if (frame.type == PJMEDIA_FRAME_TYPE_NONE) 
    729772                continue; 
    730773        } 
     
    738781            continue; 
    739782 
    740         /* Do we have signal? */ 
    741         silence = pjmedia_silence_det_detect_silence(conf_port->vad, 
    742                                                      output,  
    743                                                      conf->samples_per_frame, 
    744                                                      &level); 
    745  
    746         /* Skip if we don't have signal. */ 
    747         if (silence) { 
    748             TRACE_(("sil:%d ", i)); 
    749             continue; 
    750         } 
    751  
    752         /* Convert the buffer to unsigned value */ 
     783        /* Get the signal level. */ 
     784        level = pjmedia_calc_avg_signal(output, conf->samples_per_frame); 
     785 
     786        /* Convert level to 8bit complement ulaw */ 
     787        level = linear2ulaw(level) ^ 0xff; 
     788 
     789        /* Convert the buffer to unsigned 16bit value */ 
    753790        for (j=0; j<conf->samples_per_frame; ++j) 
    754791            conf->uns_buf[j] = pcm2unsigned(((pj_int16_t*)output)[j]); 
    755792 
    756793        /* Add the signal to all listeners. */ 
    757         for (j=0; j<conf->max_ports; ++j) { 
     794        for (j=0, cj=0;  
     795             j<conf->max_ports && cj<(unsigned)conf_port->listener_cnt; 
     796             ++j)  
     797        { 
    758798            struct conf_port *listener = conf->ports[j]; 
    759799            pj_uint32_t *sum_buf; 
     
    763803                continue; 
    764804 
     805            /* Skip if this is not the listener. */ 
     806            if (!conf_port->listeners[j]) 
     807                continue; 
     808 
     809            ++cj; 
     810 
    765811            /* Skip if this listener doesn't want to receive audio */ 
    766812            if (listener->tx_setting != PJMEDIA_PORT_ENABLE) 
    767813                continue; 
    768814 
    769             //TRACE_(("mix:%d->%d ", i, j)); 
    770  
     815            /* Mix the buffer */ 
    771816            sum_buf = listener->sum_buf; 
    772817            for (k=0; k<conf->samples_per_frame; ++k) 
    773                 sum_buf[k] += conf->uns_buf[k]; 
    774  
    775             listener->sources++; 
     818                sum_buf[k] += (conf->uns_buf[k] * level); 
     819 
     820            listener->sources += level; 
    776821        } 
    777822    } 
    778823 
    779824    /* For all ports, calculate avg signal. */ 
    780     for (i=0; i<conf->max_ports; ++i) { 
     825    for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 
    781826        struct conf_port *conf_port = conf->ports[i]; 
    782827        pjmedia_frame frame; 
     
    785830        if (!conf_port) 
    786831            continue; 
     832 
     833        ++ci; 
    787834 
    788835        if (conf_port->tx_setting == PJMEDIA_PORT_MUTE) { 
     
    800847        } 
    801848 
    802         // 
    803         // TODO: 
    804         //  When there's no source, not transmit the frame, but instead 
    805         //  transmit a 'silence' frame. This is to allow the 'port' to 
    806         //  do some processing, such as updating timestamp for RTP session 
    807         //  or transmit signal when it's in the middle of transmitting DTMF. 
    808         // 
    809  
    810849        target_buf = (conf_port->cur_tx_buf==conf_port->tx_buf1? 
    811850                        conf_port->tx_buf2 : conf_port->tx_buf1); 
     
    813852        if (conf_port->sources) { 
    814853            for (j=0; j<conf->samples_per_frame; ++j) { 
    815                 target_buf[j] = unsigned2pcm(conf_port->sum_buf[j] / conf_port->sources); 
     854                target_buf[j] = unsigned2pcm(conf_port->sum_buf[j] /  
     855                                             conf_port->sources); 
    816856            } 
    817857        } 
     
    821861 
    822862        pj_memset(&frame, 0, sizeof(frame)); 
    823         if (conf_port->sources) 
    824             frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 
    825         else 
     863        if (conf_port->sources) { 
     864 
     865            pj_bool_t is_silence = PJ_FALSE; 
     866 
     867            /* Apply silence detection. */ 
     868#if 0 
     869            is_silence = pjmedia_silence_det_detect(conf_port->vad, 
     870                                                    target_buf, 
     871                                                    conf->samples_per_frame, 
     872                                                    NULL); 
     873#endif 
     874            frame.type = is_silence ? PJMEDIA_FRAME_TYPE_NONE :  
     875                                      PJMEDIA_FRAME_TYPE_AUDIO; 
     876 
     877        } else 
    826878            frame.type = PJMEDIA_FRAME_TYPE_NONE; 
    827879 
     
    836888 
    837889    /* Return sound playback frame. */ 
    838     for (j=0; j<conf->samples_per_frame; ++j) 
    839         output_buf[j] = conf->ports[0]->cur_tx_buf[j]; 
     890    if (conf->ports[0]->sources) { 
     891        for (j=0; j<conf->samples_per_frame; ++j) 
     892            output_buf[j] = conf->ports[0]->cur_tx_buf[j]; 
     893    } else { 
     894        for (j=0; j<conf->samples_per_frame; ++j) 
     895            output_buf[j] = 0; 
     896    } 
     897 
     898    pj_mutex_unlock(conf->mutex); 
    840899 
    841900    return PJ_SUCCESS; 
     
    863922        TRACE_(("rxerr ")); 
    864923    } 
     924 
     925    /* Skip if this port is muted/disabled. */ 
     926    if (snd_port->rx_setting != PJMEDIA_PORT_ENABLE) 
     927        return PJ_SUCCESS; 
     928 
     929    /* Skip if no port is listening to the microphone */ 
     930    if (snd_port->listener_cnt == 0) 
     931        return PJ_SUCCESS; 
    865932 
    866933 
  • pjproject/trunk/pjmedia/src/pjmedia/jbuf.c

    r228 r229  
    2424#include <pj/pool.h> 
    2525#include <pj/assert.h> 
     26#include <pj/log.h> 
    2627#include <pj/string.h> 
    2728 
     29 
     30#define THIS_FILE   "jbuf.c" 
    2831 
    2932 
     
    5558    int             jb_max_hist_jitter;   // max jitter during the last jitter calculations 
    5659    int             jb_stable_hist;       // num of times the delay has been lower then the prefetch num 
     60    unsigned        jb_op_count;          // of of operations. 
    5761    int             jb_last_op;           // last operation executed on the framelist->flist_buffer (put/get) 
    5862    int             jb_last_seq_no;       // seq no. of the last frame inserted to the framelist->flist_buffer 
     
    293297    jb->jb_last_level = jb->jb_level; 
    294298    jb->jb_max_hist_jitter = PJ_MAX(jb->jb_max_hist_jitter,jb->jb_last_jitter); 
    295      
    296     if (jb->jb_last_jitter< jb->jb_prefetch) { 
     299    jb->jb_op_count++; 
     300 
     301    if (jb->jb_last_jitter < jb->jb_prefetch) { 
    297302        jb->jb_stable_hist += jb->jb_last_jitter; 
    298303        if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { 
     
    305310            jb->jb_stable_hist = 0; 
    306311            jb->jb_max_hist_jitter = 0; 
     312 
     313            if (jb->jb_op_count >= 100 && 
     314                (int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2)  
     315            { 
     316                jb_framelist_remove_head(&jb->jb_framelist,1); 
     317 
     318                PJ_LOG(5,(THIS_FILE, "jbuf prefetch: %d, size=%d",  
     319                                 jb->jb_prefetch, 
     320                                 jb_framelist_size(&jb->jb_framelist))); 
     321                jb->jb_op_count = 0; 
     322            } 
     323 
    307324        } 
    308325    } else { 
     
    310327        jb->jb_stable_hist = 0; 
    311328        jb->jb_max_hist_jitter = 0; 
     329 
     330        if (jb->jb_op_count >= 100) { 
     331            if ((int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2) { 
     332                jb_framelist_remove_head(&jb->jb_framelist,1); 
     333 
     334                PJ_LOG(5,(THIS_FILE, "jbuf prefetch: %d, size=%d",  
     335                                 jb->jb_prefetch, 
     336                                 jb_framelist_size(&jb->jb_framelist))); 
     337            } 
     338 
     339            jb->jb_op_count = 0; 
     340        } 
    312341    } 
    313342} 
  • pjproject/trunk/pjmedia/src/pjmedia/silencedet.c

    r228 r229  
    120120 
    121121 
    122 PJ_DEF(pj_int32_t) pjmedia_silence_det_calc_avg_signal(const pj_int16_t samples[], 
    123                                                        pj_size_t count) 
     122PJ_DEF(pj_int32_t) pjmedia_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_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) 
    147 { 
    148     pj_uint32_t level; 
     143PJ_DEF(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd, 
     144                                             pj_uint32_t level) 
     145{ 
    149146    pj_bool_t have_signal; 
    150147 
    151148    /* Always return false if VAD is disabled */ 
    152     if (sd->mode == VAD_MODE_NONE) { 
    153         if (p_level) 
    154             *p_level = -1; 
     149    if (sd->mode == VAD_MODE_NONE) 
    155150        return PJ_FALSE; 
    156     } 
    157      
    158     /* Calculate average signal level. */ 
    159     level = pjmedia_silence_det_calc_avg_signal(samples, count); 
    160      
    161     /* Report to caller, if required. */ 
    162     if (p_level) 
    163         *p_level = level; 
    164151 
    165152    /* Convert PCM level to ulaw */ 
     
    266253     
    267254    return !sd->in_talk; 
    268 } 
    269  
     255 
     256} 
     257 
     258 
     259PJ_DEF(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd, 
     260                                              const pj_int16_t samples[], 
     261                                              pj_size_t count, 
     262                                              pj_int32_t *p_level) 
     263{ 
     264    pj_uint32_t level; 
     265     
     266    /* Calculate average signal level. */ 
     267    level = pjmedia_calc_avg_signal(samples, count); 
     268     
     269    /* Report to caller, if required. */ 
     270    if (p_level) 
     271        *p_level = level; 
     272 
     273    return pjmedia_silence_det_apply(sd, level); 
     274} 
     275 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r228 r229  
    305305            return status; 
    306306        } 
     307 
     308        //printf("p"); fflush(stdout); 
    307309 
    308310        /* Encapsulate. */ 
Note: See TracChangeset for help on using the changeset viewer.