Ignore:
Timestamp:
May 30, 2008 11:24:37 AM (16 years ago)
Author:
nanang
Message:

Added another WSOLA implementation, PJMEDIA_WSOLA_IMP_WSOLA_LITE, this is used by small devices by default (replacing PJMEDIA_WSOLA_IMP_NULL)

File:
1 edited

Legend:

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

    r1941 r1971  
    2929#define THIS_FILE   "wsola.c" 
    3030 
    31  
    32 #if PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA 
     31#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA) || \ 
     32    (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA_LITE) 
     33 
    3334/* 
    3435 * WSOLA implementation using WSOLA 
     
    114115}; 
    115116 
     117#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA_LITE) 
     118 
     119/* In this implementation, waveform similarity comparison is done by calculating 
     120 * the difference of total level between template frame and the target buffer  
     121 * for each template_cnt samples. The smallest difference value assumed to be  
     122 * the most similar block. This seems to be naive, however some tests show 
     123 * acceptable results and the processing speed is amazing. 
     124 * 
     125 * diff level = (template[1]+..+template[n]) - (target[1]+..+target[n]) 
     126 */ 
     127static short *find_pitch(short *frm, short *beg, short *end,  
     128                         unsigned template_cnt, int first) 
     129{ 
     130    short *sr, *best=beg; 
     131    int best_corr = 0x7FFFFFFF; 
     132    int frm_sum = 0; 
     133    unsigned i; 
     134 
     135    for (i = 0; i<template_cnt; ++i) 
     136        frm_sum += frm[i]; 
     137 
     138    for (sr=beg; sr!=end; ++sr) { 
     139        int corr = frm_sum; 
     140        int abs_corr = 0; 
     141 
     142        /* Do calculation on 8 samples at once */ 
     143        for (i = 0; i<template_cnt; i+=8) { 
     144            corr -= (int)sr[i+0] + 
     145                    (int)sr[i+1] + 
     146                    (int)sr[i+2] + 
     147                    (int)sr[i+3] + 
     148                    (int)sr[i+4] + 
     149                    (int)sr[i+5] + 
     150                    (int)sr[i+6] + 
     151                    (int)sr[i+7]; 
     152        } 
     153 
     154        /* Reverse back i if template_cnt is not multiplication of 8, 
     155         * the remaining samples will be processed below. 
     156         */ 
     157        if (i != template_cnt) 
     158            i -= 8; 
     159 
     160        for (; i<template_cnt; ++i) 
     161            corr -= (int)sr[i]; 
     162 
     163        abs_corr = corr > 0? corr : -corr; 
     164 
     165        if (first) { 
     166            if (abs_corr < best_corr) { 
     167                best_corr = abs_corr; 
     168                best = sr; 
     169            } 
     170        } else { 
     171            if (abs_corr <= best_corr) { 
     172                best_corr = abs_corr; 
     173                best = sr; 
     174            } 
     175        } 
     176    } 
     177 
     178    /*TRACE_((THIS_FILE, "found pitch at %u", best-beg));*/ 
     179    return best; 
     180} 
     181 
     182#endif 
    116183 
    117184#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0 
     
    121188#include <math.h> 
    122189 
     190#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA) 
     191 
    123192static short *find_pitch(short *frm, short *beg, short *end,  
    124193                         unsigned template_cnt, int first) 
     
    131200        unsigned i; 
    132201 
     202        /* Do calculation on 8 samples at once */ 
    133203        for (i=0; i<template_cnt; i += 8) { 
    134204            corr += ((float)frm[i+0]) * ((float)sr[i+0]) +  
     
    141211                    ((float)frm[i+7]) * ((float)sr[i+7]); 
    142212        } 
     213 
     214        /* Reverse back i if template_cnt is not multiplication of 8, 
     215         * the remaining samples will be processed below. 
     216         */ 
     217        if (i != template_cnt) 
     218            i -= 8; 
     219 
    143220        for (; i<template_cnt; ++i) { 
    144221            corr += ((float)frm[i]) * ((float)sr[i]); 
     
    162239} 
    163240 
     241#endif 
     242 
    164243static void overlapp_add(short dst[], unsigned count, 
    165244                         short l[], short r[], 
     
    204283enum { WINDOW_MAX_VAL = (1 << WINDOW_BITS)-1 }; 
    205284 
     285#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA) 
     286 
    206287static short *find_pitch(short *frm, short *beg, short *end,  
    207288                         unsigned template_cnt, int first) 
     
    215296        unsigned i; 
    216297 
     298        /* Do calculation on 8 samples at once */ 
    217299        for (i=0; i<template_cnt; i+=8) { 
    218300            corr += ((int)frm[i+0]) * ((int)sr[i+0]) +  
     
    225307                    ((int)frm[i+7]) * ((int)sr[i+7]); 
    226308        } 
     309 
     310        /* Reverse back i if template_cnt is not multiplication of 8, 
     311         * the remaining samples will be processed below. 
     312         */ 
     313        if (i != template_cnt) 
     314            i -= 8; 
     315 
    227316        for (; i<template_cnt; ++i) { 
    228317            corr += ((int)frm[i]) * ((int)sr[i]); 
     
    246335} 
    247336 
     337#endif 
     338 
     339 
    248340static void overlapp_add(short dst[], unsigned count, 
    249341                         short l[], short r[], 
     
    360452        wsola->template_size = wsola->samples_per_frame; 
    361453 
     454    /* Make sure minimal template size is 8, this is required by waveform  
     455     * similarity calculation (find_pitch()). Moreover, smaller template size 
     456     * will reduce accuracy. 
     457     */ 
     458    if (wsola->template_size < 8) 
     459        wsola->template_size = 8; 
     460 
    362461    wsola->buf = (short*)pj_pool_calloc(pool, wsola->buf_cnt,  
    363462                                        sizeof(short)); 
     
    470569        unsigned dist; 
    471570 
    472         if (count <= (del_cnt << 1)) { 
     571        if ((count - del_cnt) <= frmsz) { 
     572        //if (count <= (del_cnt << 1)) { 
    473573            TRACE_((THIS_FILE, "Not enough samples to compress!")); 
    474574            return samples_del; 
    475575        } 
    476576 
    477         start = buf + (frmsz >> 1); 
     577        //start = buf + (frmsz >> 1); 
     578        start = buf + del_cnt - samples_del; 
    478579        end = start + frmsz; 
    479580 
    480581        if (end + frmsz > buf + count) 
    481582            end = buf+count-frmsz; 
     583 
     584        pj_assert(start < end); 
    482585 
    483586        start = find_pitch(buf, start, end, wsola->template_size, 0); 
     
    818921} 
    819922 
    820  
    821923#endif  /* #if PJMEDIA_WSOLA_IMP.. */ 
    822924 
Note: See TracChangeset for help on using the changeset viewer.