Ignore:
Timestamp:
Mar 4, 2008 3:37:45 PM (16 years ago)
Author:
bennylp
Message:

More ticket #438: improve docs, added channel_count in wsola, etc.

File:
1 edited

Legend:

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

    r1838 r1844  
    3737 
    3838/* Generate extra samples, in msec */ 
    39 #define GEN_EXTRA_PTIME (0.0) 
     39#define GEN_EXTRA_PTIME (5) 
    4040 
    4141/* Number of frames in erase buffer */ 
     
    5454 
    5555 
     56/* Buffer content: 
     57 * 
     58 *   t0   time    tn 
     59 *   ----------------> 
     60 * 
     61 * +---------+-------+-------+---          --+ 
     62 * | history | frame | extra | ...empty...   | 
     63 * +---------+-------+-------+----        ---+ 
     64 * ^         ^               ^               ^ 
     65 * buf    hist_cnt        cur_cnt          buf_cnt 
     66 *           or 
     67 *       frm pointer 
     68 * 
     69 * History count (hist_cnt) is a constant value, initialized upon  
     70 * creation. 
     71 * 
     72 * At any particular time, the buffer will contain at least  
     73 * (hist_cnt+samples_per_frame) samples. 
     74 * 
     75 * A "save" operation will append the frame to the end of the  
     76 * buffer, return the samples right after history (the frm pointer), 
     77 * and shift the buffer by one frame. 
     78 */ 
     79 
     80/* WSOLA structure */ 
    5681struct pjmedia_wsola 
    5782{ 
    5883    unsigned    clock_rate;     /* Sampling rate.                       */ 
    59     pj_uint16_t samples_per_frame;/* Samples per frame.                 */ 
     84    pj_uint16_t samples_per_frame;/* Samples per frame (const)          */ 
     85    pj_uint16_t channel_count;  /* Samples per frame (const)            */ 
    6086    pj_uint16_t options;        /* Options.                             */ 
    61     pj_uint16_t hist_cnt;       /* # of history samples.                */ 
    62     pj_uint16_t buf_cnt;        /* Total buffer capacity                */ 
     87    pj_uint16_t hist_cnt;       /* # of history samples (const)         */ 
     88    pj_uint16_t buf_cnt;        /* Total buffer capacity (const)        */ 
    6389    pj_uint16_t cur_cnt;        /* Cur # of samples, inc. history       */ 
    64     pj_uint16_t template_size;  /* Template size.                       */ 
    65     pj_uint16_t min_extra;      /* Min extra samples for merging.       */ 
    66     pj_uint16_t gen_extra;      /* Generate extra samples.              */ 
     90    pj_uint16_t template_size;  /* Template size (const)                */ 
     91    pj_uint16_t min_extra;      /* Min extra samples for merging (const)*/ 
     92    pj_uint16_t gen_extra;      /* Generate extra samples (const)       */ 
    6793    pj_uint16_t expand_cnt;     /* Number of expansion currently done   */ 
    6894 
     
    124150    } 
    125151 
    126     TRACE_((THIS_FILE, "found pitch at %u", best-beg)); 
     152    /*TRACE_((THIS_FILE, "found pitch at %u", best-beg));*/ 
    127153    return best; 
    128154} 
     
    208234    } 
    209235 
    210     TRACE_((THIS_FILE, "found pitch at %u", best-beg)); 
     236    /*TRACE_((THIS_FILE, "found pitch at %u", best-beg));*/ 
    211237    return best; 
    212238} 
     
    293319                                          unsigned clock_rate, 
    294320                                          unsigned samples_per_frame, 
     321                                          unsigned channel_count, 
    295322                                          unsigned options, 
    296323                                          pjmedia_wsola **p_wsola) 
     
    302329    PJ_ASSERT_RETURN(clock_rate <= 65535, PJ_EINVAL); 
    303330    PJ_ASSERT_RETURN(samples_per_frame < clock_rate, PJ_EINVAL); 
     331    PJ_ASSERT_RETURN(channel_count > 0, PJ_EINVAL); 
    304332 
    305333    wsola = PJ_POOL_ZALLOC_T(pool, pjmedia_wsola); 
     
    307335    wsola->clock_rate= (pj_uint16_t) clock_rate; 
    308336    wsola->samples_per_frame = (pj_uint16_t) samples_per_frame; 
     337    wsola->channel_count = (pj_uint16_t) channel_count; 
    309338    wsola->options   = (pj_uint16_t) options; 
    310339    wsola->hist_cnt  = (pj_uint16_t)(samples_per_frame * HISTSZ); 
     
    360389    PJ_UNUSED_ARG(options); 
    361390 
    362     pjmedia_zero_samples(wsola->buf, wsola->cur_cnt); 
    363391    wsola->cur_cnt = (pj_uint16_t)(wsola->hist_cnt +  
    364392                                   wsola->samples_per_frame); 
     393    pjmedia_zero_samples(wsola->buf, wsola->cur_cnt); 
    365394    return PJ_SUCCESS; 
    366395} 
     
    374403 
    375404    for (rep=1;; ++rep) { 
    376         short *start; 
    377         unsigned dist; 
    378  
    379         start = find_pitch(wsola->frm, wsola->buf,  
    380                            wsola->frm - (wsola->samples_per_frame >> 1), 
     405        short *start, *frm; 
     406        unsigned min_dist, max_dist, dist; 
     407 
     408        frm = wsola->buf + wsola->cur_cnt - frmsz; 
     409        pj_assert(frm - wsola->buf >= wsola->hist_cnt); 
     410 
     411        max_dist = wsola->hist_cnt; 
     412        min_dist = frmsz >> 1; 
     413 
     414        start = find_pitch(frm, frm - max_dist, frm - min_dist, 
    381415                           wsola->template_size, 1); 
    382416 
     417        /* Should we make sure that "start" is really aligned to 
     418         * channel #0, in case of stereo? Probably not necessary, as 
     419         * find_pitch() should have found the best match anyway. 
     420         */ 
     421 
    383422        if (wsola->options & PJMEDIA_WSOLA_NO_HANNING) { 
    384             overlapp_add_simple(wsola->mergebuf, wsola->samples_per_frame, 
    385                                 wsola->frm, start); 
     423            overlapp_add_simple(wsola->mergebuf, frmsz,frm, start); 
    386424        } else { 
    387             overlapp_add(wsola->mergebuf, wsola->samples_per_frame, 
    388                          wsola->frm, start, wsola->hanning); 
    389         } 
    390  
    391         dist = wsola->frm - start; 
    392         pjmedia_move_samples(wsola->frm + frmsz, start + frmsz,  
     425            overlapp_add(wsola->mergebuf, frmsz, frm, start, wsola->hanning); 
     426        } 
     427 
     428        /* How many new samples do we have */ 
     429        dist = frm - start; 
     430 
     431        /* Copy the "tail" (excess frame) to the end */ 
     432        pjmedia_move_samples(frm + frmsz, start + frmsz,  
    393433                             wsola->buf+wsola->cur_cnt - (start+frmsz)); 
    394434 
    395         pjmedia_copy_samples(wsola->frm, wsola->mergebuf, frmsz); 
    396  
     435        /* Copy the merged frame */ 
     436        pjmedia_copy_samples(frm, wsola->mergebuf, frmsz); 
     437 
     438        /* We have new samples */ 
    397439        wsola->cur_cnt = (pj_uint16_t)(wsola->cur_cnt + dist); 
     440 
     441        pj_assert(wsola->cur_cnt <= wsola->buf_cnt); 
     442 
    398443        generated += dist; 
    399444 
    400445        if (generated >= needed) { 
    401             assert(wsola->cur_cnt <= wsola->buf_cnt); 
    402446            TRACE_((THIS_FILE, "WSOLA frame expanded after %d iterations",  
    403447                    rep)); 
     
    469513    if (prev_lost && extra >= wsola->min_extra) { 
    470514        short *dst = wsola->buf + wsola->hist_cnt + wsola->samples_per_frame; 
    471         unsigned i; 
    472  
     515 
     516        /* Smoothen the transition. This will also erase the excess 
     517         * samples 
     518         */ 
    473519        overlapp_add_simple(dst, extra, dst, frm); 
    474520 
    475         for (i=extra; i<wsola->samples_per_frame; ++i) 
    476             dst[i] = frm[i]; 
    477  
    478          
     521        /* Copy remaining samples from the frame */ 
     522        pjmedia_copy_samples(dst+extra, frm+extra,  
     523                             wsola->samples_per_frame-extra); 
     524 
     525        /* Retrieve frame */ 
    479526        pjmedia_copy_samples(frm, wsola->frm, wsola->samples_per_frame); 
     527 
     528        /* Remove excess samples */ 
    480529        wsola->cur_cnt = (pj_uint16_t)(wsola->hist_cnt +  
    481530                                       wsola->samples_per_frame); 
     531 
     532        /* Shift buffer */ 
    482533        pjmedia_move_samples(wsola->buf, wsola->buf+wsola->samples_per_frame, 
    483534                              wsola->cur_cnt); 
     
    490541        } 
    491542 
     543        /* Append frame */ 
    492544        pjmedia_copy_samples(wsola->buf + wsola->cur_cnt, frm,  
    493545                             wsola->samples_per_frame); 
     546 
     547        /* Retrieve frame */ 
    494548        pjmedia_copy_samples(frm, wsola->frm,  
    495549                             wsola->samples_per_frame); 
     550 
     551        /* Shift buffer */ 
    496552        pjmedia_move_samples(wsola->buf, wsola->buf+wsola->samples_per_frame, 
    497553                             wsola->cur_cnt); 
Note: See TracChangeset for help on using the changeset viewer.