Changeset 3567


Ignore:
Timestamp:
May 15, 2011 12:54:28 PM (9 years ago)
Author:
ming
Message:

Fixed #1257: Option for using simple FIFO delay buffer in echo canceller.

Location:
pjproject/branches/1.x/pjmedia
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/1.x/pjmedia/include/pjmedia/delaybuf.h

    r3553 r3567  
    6565 
    6666/** 
     67 * Delay buffer options. 
     68 */ 
     69typedef enum pjmedia_delay_buf_flag 
     70{ 
     71    /** 
     72     * Use simple FIFO mechanism for the delay buffer, i.e. 
     73     * without WSOLA for expanding and shrinking audio samples. 
     74     */ 
     75    PJMEDIA_DELAY_BUF_SIMPLE_FIFO = 1 
     76 
     77} pjmedia_delay_buf_flag; 
     78 
     79/** 
    6780 * Create the delay buffer. Once the delay buffer is created, it will 
    6881 * enter learning state unless the delay argument is specified, which 
     
    8093 *                          one frame time, default maximum delay used is 
    8194 *                          400 ms. 
    82  * @param options           Option flags, must be zero for now. 
     95 * @param options           Options. If PJMEDIA_DELAY_BUF_SIMPLE_FIFO is 
     96 *                          specified, then a simple FIFO mechanism 
     97 *                          will be used instead of the adaptive 
     98 *                          implementation (which uses WSOLA to expand 
     99 *                          or shrink audio samples). 
     100 *                          See #pjmedia_delay_buf_flag for other options. 
    83101 * @param p_b               Pointer to receive the delay buffer instance. 
    84102 * 
  • pjproject/branches/1.x/pjmedia/include/pjmedia/echo.h

    r3553 r3567  
    8989     * canceller will not be called by different threads at the same time. 
    9090     */ 
    91     PJMEDIA_ECHO_NO_LOCK = 16 
     91    PJMEDIA_ECHO_NO_LOCK = 16, 
     92 
     93    /** 
     94     * If PJMEDIA_ECHO_USE_SIMPLE_FIFO flag is specified, the delay buffer 
     95     * created for the echo canceller will use simple FIFO mechanism, i.e. 
     96     * without using WSOLA to expand and shrink audio samples. 
     97     */ 
     98    PJMEDIA_ECHO_USE_SIMPLE_FIFO = 32 
     99 
    92100 
    93101} pjmedia_echo_flag; 
  • pjproject/branches/1.x/pjmedia/src/pjmedia/delaybuf.c

    r3553 r3567  
    100100    PJ_ASSERT_RETURN(pool && samples_per_frame && clock_rate && channel_count && 
    101101                     p_b, PJ_EINVAL); 
    102     PJ_ASSERT_RETURN(options==0, PJ_EINVAL); 
    103  
    104     PJ_UNUSED_ARG(options); 
    105102 
    106103    if (!name) { 
     
    127124        return status; 
    128125 
    129     /* Create WSOLA */ 
    130     status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1, 
    131                                   PJMEDIA_WSOLA_NO_FADING, &b->wsola); 
    132     if (status != PJ_SUCCESS) 
    133         return status; 
     126    if (!(options & PJMEDIA_DELAY_BUF_SIMPLE_FIFO)) { 
     127        /* Create WSOLA */ 
     128        status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1, 
     129                                      PJMEDIA_WSOLA_NO_FADING, &b->wsola); 
     130        if (status != PJ_SUCCESS) 
     131            return status; 
     132        PJ_LOG(5, (b->obj_name, "Using delay buffer with WSOLA.")); 
     133    } else { 
     134        PJ_LOG(5, (b->obj_name, "Using simple FIFO delay buffer.")); 
     135    } 
    134136 
    135137    /* Finally, create mutex */ 
     
    148150PJ_DEF(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b) 
    149151{ 
    150     pj_status_t status; 
     152    pj_status_t status = PJ_SUCCESS; 
    151153 
    152154    PJ_ASSERT_RETURN(b, PJ_EINVAL); 
     
    154156    pj_lock_acquire(b->lock); 
    155157 
    156     status = pjmedia_wsola_destroy(b->wsola); 
    157     if (status == PJ_SUCCESS) 
    158         b->wsola = NULL; 
     158    if (b->wsola) { 
     159        status = pjmedia_wsola_destroy(b->wsola); 
     160        if (status == PJ_SUCCESS) 
     161            b->wsola = NULL; 
     162    } 
    159163 
    160164    pj_lock_release(b->lock); 
     
    265269    pj_lock_acquire(b->lock); 
    266270 
    267     update(b, OP_PUT); 
     271    if (b->wsola) { 
     272        update(b, OP_PUT); 
    268273     
    269     status = pjmedia_wsola_save(b->wsola, frame, PJ_FALSE); 
    270     if (status != PJ_SUCCESS) { 
    271         pj_lock_release(b->lock); 
    272         return status; 
     274        status = pjmedia_wsola_save(b->wsola, frame, PJ_FALSE); 
     275        if (status != PJ_SUCCESS) { 
     276            pj_lock_release(b->lock); 
     277            return status; 
     278        } 
    273279    } 
    274280 
     
    278284    { 
    279285        unsigned erase_cnt; 
    280          
    281         /* shrink one frame or just the diff? */ 
    282         //erase_cnt = b->samples_per_frame; 
    283         erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) +  
    284                     b->samples_per_frame - b->max_cnt; 
    285  
    286         shrink_buffer(b, erase_cnt); 
     286 
     287        if (b->wsola) { 
     288            /* shrink one frame or just the diff? */ 
     289            //erase_cnt = b->samples_per_frame; 
     290            erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) +  
     291                        b->samples_per_frame - b->max_cnt; 
     292 
     293            shrink_buffer(b, erase_cnt); 
     294        } 
    287295 
    288296        /* Check if shrinking failed or erased count is less than requested, 
     
    298306            pjmedia_circ_buf_adv_read_ptr(b->circ_buf, erase_cnt); 
    299307 
    300             PJ_LOG(4,(b->obj_name,"Shrinking failed or insufficient, dropping" 
    301                       " %d eldest samples, buf_cnt=%d", erase_cnt,  
    302                       pjmedia_circ_buf_get_len(b->circ_buf))); 
     308            PJ_LOG(4,(b->obj_name,"%sDropping %d eldest samples, buf_cnt=%d", 
     309                      (b->wsola? "Shrinking failed or insufficient. ": ""), 
     310                      erase_cnt, pjmedia_circ_buf_get_len(b->circ_buf))); 
    303311        } 
    304312    } 
     
    313321                                           pj_int16_t frame[]) 
    314322{ 
    315     pj_status_t status; 
     323    pj_status_t status = PJ_SUCCESS; 
    316324 
    317325    PJ_ASSERT_RETURN(b && frame, PJ_EINVAL); 
     
    319327    pj_lock_acquire(b->lock); 
    320328 
    321     update(b, OP_GET); 
     329    if (b->wsola) 
     330        update(b, OP_GET); 
    322331 
    323332    /* Starvation checking */ 
     
    327336                  pjmedia_circ_buf_get_len(b->circ_buf))); 
    328337 
    329         status = pjmedia_wsola_generate(b->wsola, frame); 
    330  
    331         if (status == PJ_SUCCESS) { 
    332             TRACE__((b->obj_name,"Successfully generate 1 frame")); 
    333             if (pjmedia_circ_buf_get_len(b->circ_buf) == 0) { 
    334                 pj_lock_release(b->lock); 
    335                 return PJ_SUCCESS; 
    336             } 
    337  
    338             /* Put generated frame into buffer */ 
    339             pjmedia_circ_buf_write(b->circ_buf, frame, b->samples_per_frame); 
    340  
    341         } else { 
     338        if (b->wsola) { 
     339            status = pjmedia_wsola_generate(b->wsola, frame); 
     340 
     341            if (status == PJ_SUCCESS) { 
     342                TRACE__((b->obj_name,"Successfully generate 1 frame")); 
     343                if (pjmedia_circ_buf_get_len(b->circ_buf) == 0) { 
     344                    pj_lock_release(b->lock); 
     345                    return PJ_SUCCESS; 
     346                } 
     347 
     348                /* Put generated frame into buffer */ 
     349                pjmedia_circ_buf_write(b->circ_buf, frame, 
     350                                       b->samples_per_frame); 
     351            } 
     352        } 
     353 
     354        if (!b->wsola || status != PJ_SUCCESS) { 
    342355            unsigned buf_len = pjmedia_circ_buf_get_len(b->circ_buf); 
    343356             
    344357            /* Give all what delay buffer has, then pad with zeroes */ 
    345             PJ_LOG(4,(b->obj_name,"Error generating frame, status=%d",  
    346                       status)); 
     358            if (b->wsola) 
     359                PJ_LOG(4,(b->obj_name,"Error generating frame, status=%d",  
     360                          status)); 
    347361 
    348362            pjmedia_circ_buf_read(b->circ_buf, frame, buf_len); 
     
    379393 
    380394    /* Reset WSOLA */ 
    381     pjmedia_wsola_reset(b->wsola, 0); 
     395    if (b->wsola) 
     396        pjmedia_wsola_reset(b->wsola, 0); 
    382397 
    383398    pj_lock_release(b->lock); 
  • pjproject/branches/1.x/pjmedia/src/pjmedia/echo_common.c

    r3553 r3567  
    145145{ 
    146146    unsigned ptime, lat_cnt; 
     147    unsigned delay_buf_opt = 0; 
    147148    pjmedia_echo_state *ec; 
    148149    pj_status_t status; 
     
    212213 
    213214    /* Create delay buffer to compensate drifts */ 
     215    if (options & PJMEDIA_ECHO_USE_SIMPLE_FIFO) 
     216        delay_buf_opt |= PJMEDIA_DELAY_BUF_SIMPLE_FIFO; 
    214217    status = pjmedia_delay_buf_create(ec->pool, ec->obj_name, clock_rate,  
    215218                                      samples_per_frame, channel_count, 
    216219                                      (PJMEDIA_SOUND_BUFFER_COUNT+1) * ptime, 
    217                                       0, &ec->delay_buf); 
     220                                      delay_buf_opt, &ec->delay_buf); 
    218221    if (status != PJ_SUCCESS) { 
    219222        pj_pool_release(pool); 
Note: See TracChangeset for help on using the changeset viewer.