Ignore:
Timestamp:
Feb 28, 2008 8:22:16 PM (11 years ago)
Author:
bennylp
Message:

Modify WSOLA discard to support erasing frame from non-contiguous buffer

File:
1 edited

Legend:

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

    r1826 r1827  
    3939#define GEN_EXTRA_PTIME (0.0) 
    4040 
     41/* Number of frames in erase buffer */ 
     42#define ERASE_CNT       ((unsigned)3) 
     43 
    4144 
    4245#ifndef M_PI 
     
    6770    short    *frm;              /* Pointer to next frame to play in buf */ 
    6871    short    *mergebuf;         /* Temporary merge buffer.              */ 
     72    short    *erasebuf;         /* Temporary erase buffer.              */ 
    6973#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0 
    7074    float    *hanning;          /* Hanning window.                      */ 
     
    330334    } 
    331335 
     336    if ((options & PJMEDIA_WSOLA_NO_DISCARD) == 0) { 
     337        wsola->erasebuf = (short*)pj_pool_calloc(pool, samples_per_frame * 
     338                                                       ERASE_CNT, 
     339                                                 sizeof(short)); 
     340    } 
     341 
    332342    *p_wsola = wsola; 
    333343    return PJ_SUCCESS; 
     
    366376 
    367377        dist = wsola->frm - start; 
    368         memmove(wsola->frm + frmsz, start + frmsz,  
    369                 (wsola->buf+wsola->cur_cnt - (start+frmsz)) << 1); 
    370  
    371         memcpy(wsola->frm, wsola->mergebuf, frmsz << 1); 
     378        pjmedia_move_samples(wsola->frm + frmsz, start + frmsz,  
     379                             wsola->buf+wsola->cur_cnt - (start+frmsz)); 
     380 
     381        pjmedia_copy_samples(wsola->frm, wsola->mergebuf, frmsz); 
    372382 
    373383        wsola->cur_cnt = (pj_uint16_t)(wsola->cur_cnt + dist); 
     
    385395 
    386396static unsigned compress(pjmedia_wsola *wsola, short *buf, unsigned count, 
    387                          unsigned erase_cnt) 
     397                         unsigned del_cnt) 
    388398{ 
    389399    unsigned samples_del = 0, rep; 
     
    394404        unsigned dist; 
    395405 
    396         if (count <= (erase_cnt << 1)) { 
     406        if (count <= (del_cnt << 1)) { 
    397407            TRACE_((THIS_FILE, "Not enough samples to compress!")); 
    398408            return samples_del; 
     
    415425        } 
    416426 
    417         memmove(buf + frmsz, buf + frmsz + dist, 
    418                 (count - frmsz - dist) * 2); 
     427        pjmedia_move_samples(buf + frmsz, buf + frmsz + dist, 
     428                             count - frmsz - dist); 
    419429 
    420430        count -= dist; 
    421431        samples_del += dist; 
    422432 
    423         if (samples_del >= erase_cnt) { 
     433        if (samples_del >= del_cnt) { 
    424434            TRACE_((THIS_FILE,  
    425435                    "Erased %d of %d requested after %d iteration(s)", 
    426                     samples_del, erase_cnt, rep)); 
     436                    samples_del, del_cnt, rep)); 
    427437            break; 
    428438        } 
     
    453463 
    454464         
    455         memcpy(frm, wsola->frm, wsola->samples_per_frame << 1); 
     465        pjmedia_copy_samples(frm, wsola->frm, wsola->samples_per_frame); 
    456466        wsola->cur_cnt = (pj_uint16_t)(wsola->hist_cnt +  
    457467                                       wsola->samples_per_frame); 
    458         memmove(wsola->buf, wsola->buf+wsola->samples_per_frame,  
    459                 wsola->cur_cnt << 1); 
     468        pjmedia_move_samples(wsola->buf, wsola->buf+wsola->samples_per_frame, 
     469                              wsola->cur_cnt); 
    460470 
    461471    } else { 
     
    466476        } 
    467477 
    468         memcpy(wsola->buf + wsola->cur_cnt, frm,  
    469                wsola->samples_per_frame << 1); 
    470         memcpy(frm, wsola->frm,  
    471                wsola->samples_per_frame << 1); 
    472         memmove(wsola->buf, wsola->buf+wsola->samples_per_frame,  
    473                 wsola->cur_cnt << 1); 
     478        pjmedia_copy_samples(wsola->buf + wsola->cur_cnt, frm,  
     479                             wsola->samples_per_frame); 
     480        pjmedia_copy_samples(frm, wsola->frm,  
     481                             wsola->samples_per_frame); 
     482        pjmedia_move_samples(wsola->buf, wsola->buf+wsola->samples_per_frame, 
     483                             wsola->cur_cnt); 
    474484    } 
    475485     
     
    493503         * rather than generating a new one. 
    494504         */ 
    495         memcpy(frm, wsola->frm, wsola->samples_per_frame << 1); 
    496         memmove(wsola->buf, wsola->buf+wsola->samples_per_frame,  
    497                 (wsola->cur_cnt - wsola->samples_per_frame) << 1); 
     505        pjmedia_copy_samples(frm, wsola->frm, wsola->samples_per_frame); 
     506        pjmedia_move_samples(wsola->buf, wsola->buf+wsola->samples_per_frame, 
     507                             wsola->cur_cnt - wsola->samples_per_frame); 
    498508 
    499509        pj_assert(wsola->cur_cnt >=  
     
    512522        expand(wsola, new_samples); 
    513523 
    514         memcpy(frm, wsola->frm, wsola->samples_per_frame << 1); 
    515         memmove(wsola->buf, wsola->buf+wsola->samples_per_frame,  
    516                 (wsola->cur_cnt - wsola->samples_per_frame) << 1); 
     524        pjmedia_copy_samples(frm, wsola->frm, wsola->samples_per_frame); 
     525        pjmedia_move_samples(wsola->buf, wsola->buf+wsola->samples_per_frame, 
     526                             wsola->cur_cnt - wsola->samples_per_frame); 
    517527 
    518528        pj_assert(wsola->cur_cnt >=  
     
    531541 
    532542PJ_DEF(pj_status_t) pjmedia_wsola_discard( pjmedia_wsola *wsola,  
    533                                            short buf[], 
    534                                            unsigned buf_cnt,  
    535                                            unsigned *erase_cnt) 
    536 { 
    537     PJ_ASSERT_RETURN(wsola && buf && buf_cnt && erase_cnt, PJ_EINVAL); 
    538     PJ_ASSERT_RETURN(*erase_cnt, PJ_EINVAL); 
    539  
    540     *erase_cnt = compress(wsola, buf, buf_cnt, *erase_cnt); 
    541     return (*erase_cnt) > 0 ? PJ_SUCCESS : PJ_ETOOSMALL; 
    542 } 
    543  
    544  
     543                                           short buf1[], 
     544                                           unsigned buf1_cnt,  
     545                                           short buf2[], 
     546                                           unsigned buf2_cnt, 
     547                                           unsigned *del_cnt) 
     548{ 
     549    PJ_ASSERT_RETURN(wsola && buf1 && buf1_cnt && del_cnt, PJ_EINVAL); 
     550    PJ_ASSERT_RETURN(*del_cnt, PJ_EINVAL); 
     551 
     552    if (buf2_cnt == 0) { 
     553        /* Buffer is contiguous space, no need to use temporary 
     554         * buffer. 
     555         */ 
     556        *del_cnt = compress(wsola, buf1, buf1_cnt, *del_cnt); 
     557 
     558    } else { 
     559        PJ_ASSERT_RETURN(buf2, PJ_EINVAL); 
     560 
     561        if (buf1_cnt < ERASE_CNT * wsola->samples_per_frame && 
     562            buf2_cnt < ERASE_CNT * wsola->samples_per_frame && 
     563            wsola->erasebuf == NULL) 
     564        { 
     565            /* We need erasebuf but WSOLA was created with  
     566             * PJMEDIA_WSOLA_NO_DISCARD flag. 
     567             */ 
     568            pj_assert(!"WSOLA need erase buffer!"); 
     569            return PJ_EINVALIDOP; 
     570        } 
     571 
     572        if (buf2_cnt >= ERASE_CNT * wsola->samples_per_frame) { 
     573            *del_cnt = compress(wsola, buf2, buf2_cnt, *del_cnt); 
     574        } else if (buf1_cnt >= ERASE_CNT * wsola->samples_per_frame) { 
     575            unsigned max; 
     576 
     577            *del_cnt = compress(wsola, buf1, buf1_cnt, *del_cnt); 
     578 
     579            max = *del_cnt; 
     580            if (max > buf2_cnt) 
     581                max = buf2_cnt; 
     582 
     583            pjmedia_move_samples(buf1+buf1_cnt-(*del_cnt), buf2,  
     584                                 max); 
     585            if (max < buf2_cnt) { 
     586                pjmedia_move_samples(buf2, buf2+(*del_cnt),  
     587                                     buf2_cnt-max); 
     588            } 
     589 
     590        } else { 
     591            unsigned buf_cnt = buf1_cnt + buf2_cnt; 
     592            unsigned max; 
     593 
     594            if (buf_cnt > ERASE_CNT * wsola->samples_per_frame) 
     595                buf_cnt = ERASE_CNT * wsola->samples_per_frame; 
     596 
     597            pjmedia_copy_samples(wsola->erasebuf, buf1, buf1_cnt); 
     598            pjmedia_copy_samples(wsola->erasebuf+buf1_cnt, buf2,  
     599                                 buf_cnt-buf1_cnt); 
     600 
     601            *del_cnt = compress(wsola, wsola->erasebuf, buf_cnt, *del_cnt); 
     602 
     603            buf_cnt -= (*del_cnt); 
     604 
     605            max = buf_cnt; 
     606            if (max > buf1_cnt) 
     607                max = buf1_cnt; 
     608            pjmedia_copy_samples(buf1, wsola->erasebuf, max); 
     609 
     610            if (max < buf_cnt) { 
     611                pjmedia_copy_samples(buf2, wsola->erasebuf+max, buf_cnt-max); 
     612            } 
     613        } 
     614    } 
     615 
     616    return (*del_cnt) > 0 ? PJ_SUCCESS : PJ_ETOOSMALL; 
     617} 
     618 
     619 
Note: See TracChangeset for help on using the changeset viewer.