Ignore:
Timestamp:
Apr 7, 2007 4:01:41 PM (18 years ago)
Author:
bennylp
Message:

Changed resample to use speex (for now)

Location:
pjproject/branches/split-3rd-party
Files:
2 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/split-3rd-party/pjmedia/build/pjmedia.dsp

    r1168 r1171  
    430430# End Source File 
    431431# End Group 
    432 # Begin Group "Resample Files" 
    433  
    434 # PROP Default_Filter "" 
    435 # Begin Source File 
    436  
    437 SOURCE=..\src\pjmedia\largefilter.h 
    438 # End Source File 
    439 # Begin Source File 
    440  
    441 SOURCE=..\src\pjmedia\smallfilter.h 
    442 # End Source File 
    443 # End Group 
    444432# End Target 
    445433# End Project 
  • pjproject/branches/split-3rd-party/pjmedia/include/pjmedia/resample.h

    r974 r1171  
    6767 *                              because temporary buffer needs to be created. 
    6868 * @param large_filter          If true, large filter size will be used. 
     69 * @param channel_count         Number of channels. 
    6970 * @param rate_in               Clock rate of the input samples. 
    7071 * @param rate_out              Clock rate of the output samples. 
     
    7778                                             pj_bool_t high_quality, 
    7879                                             pj_bool_t large_filter, 
     80                                             unsigned channel_count, 
    7981                                             unsigned rate_in, 
    8082                                             unsigned rate_out, 
     
    106108PJ_DECL(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample); 
    107109 
     110 
     111/** 
     112 * Destroy the resample. 
     113 * 
     114 * @param resample              The resample session. 
     115 */ 
     116PJ_DECL(void) pjmedia_resample_destroy(pjmedia_resample *resample); 
    108117 
    109118/** 
  • pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/conference.c

    r974 r1171  
    299299                                          high_quality, 
    300300                                          large_filter, 
     301                                          conf->channel_count, 
    301302                                          conf_port->clock_rate,/* Rate in */ 
    302303                                          conf->clock_rate, /* Rate out */ 
     
    313314                                         high_quality, 
    314315                                         large_filter, 
     316                                         conf->channel_count, 
    315317                                         conf->clock_rate,  /* Rate in */ 
    316318                                         conf_port->clock_rate, /* Rate out */ 
  • pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/resample.c

    r1170 r1171  
    2424#include <pj/pool.h> 
    2525 
    26 #include "../../third_party/build/resample/resamplesubs.h" 
     26#include <speex/speex_resampler.h> 
    2727 
    2828#define THIS_FILE   "resample.c" 
     
    3131struct pjmedia_resample 
    3232{ 
    33     double       factor;        /* Conversion factor = rate_out / rate_in.  */ 
    34     pj_bool_t    large_filter;  /* Large filter?                            */ 
    35     pj_bool_t    high_quality;  /* Not fast?                                */ 
    36     unsigned     xoff;          /* History and lookahead size, in samples   */ 
    37     unsigned     frame_size;    /* Samples per frame.                       */ 
    38     pj_int16_t  *buffer;        /* Input buffer.                            */ 
     33    SpeexResamplerState *state; 
     34#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 
     35    float               *in_buffer; 
     36    float               *out_buffer; 
     37#endif 
     38    unsigned             in_samples_per_frame; 
     39    unsigned             out_samples_per_frame; 
    3940}; 
    40  
    41  
    42 #ifndef MAX 
    43 #   define MAX(a,b) ((a) >= (b) ? (a) : (b)) 
    44 #endif 
    4541 
    4642 
     
    4844                                             pj_bool_t high_quality, 
    4945                                             pj_bool_t large_filter, 
     46                                             unsigned channel_count, 
    5047                                             unsigned rate_in, 
    5148                                             unsigned rate_out, 
     
    5451{ 
    5552    pjmedia_resample *resample; 
     53    int quality; 
     54    int err; 
    5655 
    5756    PJ_ASSERT_RETURN(pool && p_resample && rate_in && 
    5857                     rate_out && samples_per_frame, PJ_EINVAL); 
    5958 
    60     resample = pj_pool_alloc(pool, sizeof(pjmedia_resample)); 
     59    resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample); 
    6160    PJ_ASSERT_RETURN(resample, PJ_ENOMEM); 
    6261 
    63     /* 
    64      * If we're downsampling, always use the fast algorithm since it seems 
    65      * to yield the same quality. 
    66      */ 
    67     if (rate_out < rate_in) { 
    68         //no this is not a good idea. It sounds pretty good with speech, 
    69         //but very poor with background noise etc. 
    70         //high_quality = 0; 
     62    if (high_quality) { 
     63        if (large_filter) 
     64            quality = 8; 
     65        else 
     66            quality = 7; 
     67    } else { 
     68        quality = 3; 
    7169    } 
    7270 
    73 #if !defined(PJMEDIA_HAS_LARGE_FILTER) || PJMEDIA_HAS_LARGE_FILTER==0 
    74     /* 
    75      * If large filter is excluded in the build, then prevent application 
    76      * from using it. 
    77      */ 
    78     if (high_quality && large_filter) { 
    79         large_filter = PJ_FALSE; 
    80         PJ_LOG(5,(THIS_FILE,  
    81                   "Resample uses small filter because large filter is " 
    82                   "disabled")); 
    83     } 
     71    resample->in_samples_per_frame = samples_per_frame; 
     72    resample->out_samples_per_frame = rate_out / (rate_in / samples_per_frame); 
     73    resample->state = speex_resampler_init(channel_count,  rate_in, rate_out,  
     74                                           quality, &err); 
     75    if (resample->state == NULL || err != RESAMPLER_ERR_SUCCESS) 
     76        return PJ_ENOMEM; 
     77 
     78#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 
     79    resample->in_buffer = pj_pool_calloc(pool, resample->in_samples_per_frame,  
     80                                         sizeof(float)); 
     81    resample->out_buffer=pj_pool_calloc(pool, resample->out_samples_per_frame, 
     82                                        sizeof(float)); 
    8483#endif 
    85  
    86 #if !defined(PJMEDIA_HAS_SMALL_FILTER) || PJMEDIA_HAS_SMALL_FILTER==0 
    87     /* 
    88      * If small filter is excluded in the build and application wants to 
    89      * use it, then drop to linear conversion. 
    90      */ 
    91     if (high_quality && large_filter == 0) { 
    92         high_quality = PJ_FALSE; 
    93         PJ_LOG(4,(THIS_FILE,  
    94                   "Resample uses linear because small filter is disabled")); 
    95     } 
    96 #endif 
    97  
    98     resample->factor = rate_out * 1.0 / rate_in; 
    99     resample->large_filter = large_filter; 
    100     resample->high_quality = high_quality; 
    101     resample->frame_size = samples_per_frame; 
    102  
    103     if (high_quality) { 
    104         unsigned size; 
    105  
    106         /* This is a bug in xoff calculation, thanks Stephane Lussier 
    107          * of Macadamian dot com. 
    108          *   resample->xoff = large_filter ? 32 : 6; 
    109          */ 
    110         if (large_filter) 
    111             resample->xoff = (unsigned) 
    112                              ((resample_LARGE_FILTER_NMULT + 1) / 2.0  *   
    113                                MAX(1.0, 1.0/resample->factor)); 
    114         else 
    115             resample->xoff = (unsigned) 
    116                              ((resample_SMALL_FILTER_NMULT + 1) / 2.0  *   
    117                                MAX(1.0, 1.0/resample->factor)); 
    118  
    119  
    120         size = (samples_per_frame + 2*resample->xoff) * sizeof(pj_int16_t); 
    121         resample->buffer = pj_pool_alloc(pool, size); 
    122         PJ_ASSERT_RETURN(resample->buffer, PJ_ENOMEM); 
    123  
    124         pjmedia_zero_samples(resample->buffer, resample->xoff*2); 
    125  
    126  
    127     } else { 
    128         resample->xoff = 0; 
    129     } 
    13084 
    13185    *p_resample = resample; 
    13286 
    133     PJ_LOG(5,(THIS_FILE, "resample created: %s qualiy, %s filter, in/out " 
    134                           "rate=%d/%d",  
    135                           (high_quality?"high":"low"), 
    136                           (large_filter?"large":"small"), 
    137                           rate_in, rate_out)); 
     87    PJ_LOG(5,(THIS_FILE,  
     88              "resample created: quality=%d, ch=%d, in/out rate=%d/%d",  
     89              quality, channel_count, rate_in, rate_out)); 
    13890    return PJ_SUCCESS; 
    13991} 
    140  
    14192 
    14293 
     
    14596                                   pj_int16_t *output ) 
    14697{ 
     98    spx_uint32_t in_length, out_length; 
     99    float *fp; 
     100    unsigned i; 
     101 
    147102    PJ_ASSERT_ON_FAIL(resample, return); 
    148103 
    149     if (resample->high_quality) { 
    150         pj_int16_t *dst_buf; 
    151         const pj_int16_t *src_buf; 
     104    in_length = resample->in_samples_per_frame; 
     105    out_length = resample->out_samples_per_frame; 
    152106 
    153         /* Okay chaps, here's how we do resampling. 
    154          * 
    155          * The original resample algorithm requires xoff samples *before* the 
    156          * input buffer as history, and another xoff samples *after* the 
    157          * end of the input buffer as lookahead. Since application can only 
    158          * supply framesize buffer on each run, PJMEDIA needs to arrange the 
    159          * buffer to meet these requirements. 
    160          * 
    161          * So here comes the trick. 
    162          * 
    163          * First of all, because of the history and lookahead requirement,  
    164          * resample->buffer need to accomodate framesize+2*xoff samples in its 
    165          * buffer. This is done when the buffer is created. 
    166          * 
    167          * On the first run, the input frame (supplied by application) is 
    168          * copied to resample->buffer at 2*xoff position. The first 2*xoff 
    169          * samples are initially zeroed (in the initialization). The resample 
    170          * algorithm then invoked at resample->buffer+xoff ONLY, thus giving 
    171          * it one xoff at the beginning as zero, and one xoff at the end 
    172          * as the end of the original input. The resample algorithm will see 
    173          * that the first xoff samples in the input as zero. 
    174          * 
    175          * So here's the layout of resample->buffer on the first run. 
    176          * 
    177          * run 0  
    178          *     +------+------+--------------+ 
    179          *     | 0000 | 0000 |  frame0...   | 
    180          *     +------+------+--------------+ 
    181          *     ^      ^      ^              ^ 
    182          *     0    xoff  2*xoff       size+2*xoff  
    183          * 
    184          * (Note again: resample algorithm is called at resample->buffer+xoff) 
    185          * 
    186          * At the end of the run, 2*xoff samples from the end of  
    187          * resample->buffer are copied to the beginning of resample->buffer. 
    188          * The first xoff part of this will be used as history for the next 
    189          * run, and the second xoff part of this is actually the start of 
    190          * resampling for the next run. 
    191          * 
    192          * And the first run completes, the function returns. 
    193          * 
    194          *  
    195          * On the next run, the input frame supplied by application is again 
    196          * copied at 2*xoff position in the resample->buffer, and the  
    197          * resample algorithm is again invoked at resample->buffer+xoff  
    198          * position. So effectively, the resample algorithm will start its 
    199          * operation on the last xoff from the previous frame, and gets the 
    200          * history from the last 2*xoff of the previous frame, and the look- 
    201          * ahead from the last xoff of current frame. 
    202          * 
    203          * So on this run, the buffer layout is: 
    204          * 
    205          * run 1 
    206          *     +------+------+--------------+ 
    207          *     | frm0 | frm0 |  frame1...   | 
    208          *     +------+------+--------------+ 
    209          *     ^      ^      ^              ^ 
    210          *     0    xoff  2*xoff       size+2*xoff  
    211          * 
    212          * As you can see from above diagram, the resampling algorithm is 
    213          * actually called from the last xoff part of previous frame (frm0). 
    214          * 
    215          * And so on the process continues for the next frame, and the next, 
    216          * and the next, ... 
    217          * 
    218          */ 
    219         dst_buf = resample->buffer + resample->xoff*2; 
    220         pjmedia_copy_samples(dst_buf, input, resample->frame_size); 
    221              
    222         if (resample->factor >= 1) { 
     107#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 
     108    fp = resample->in_buffer; 
     109    for (i=0; i<in_length; ++i) { 
     110        fp[i] = input[i]; 
     111    } 
     112    speex_resampler_process_interleaved_float(resample->state, 
     113                                              resample->in_buffer, &in_length, 
     114                                              resample->out_buffer, &out_length); 
     115    fp = resample->out_buffer; 
     116    for (i=0; i<out_length; ++i) { 
     117        output[i] = (pj_int16_t)fp[i]; 
     118    } 
     119#else 
     120    PJ_UNUSED_ARG(dst); 
     121    PJ_UNUSED_ARG(i); 
     122    speex_resampler_process_interleaved_int(resample->state, 
     123                                            (const __int16 *)input, &in_length, 
     124                                            (__int16 *)output, &out_length); 
     125#endif 
    223126 
    224             if (resample->large_filter) { 
    225                 SrcUp(resample->buffer + resample->xoff, output, 
    226                       resample->factor, resample->frame_size, 
    227                       resample_LARGE_FILTER_NWING, resample_LARGE_FILTER_SCALE, 
    228                       resample_LARGE_FILTER_IMP, resample_LARGE_FILTER_IMPD, 
    229                       PJ_TRUE); 
    230             } else { 
    231                 SrcUp(resample->buffer + resample->xoff, output, 
    232                       resample->factor, resample->frame_size, 
    233                       resample_SMALL_FILTER_NWING, resample_SMALL_FILTER_SCALE, 
    234                       resample_SMALL_FILTER_IMP, resample_SMALL_FILTER_IMPD, 
    235                       PJ_TRUE); 
    236             } 
     127    pj_assert(in_length == resample->in_samples_per_frame); 
     128    pj_assert(out_length == resample->out_samples_per_frame); 
     129} 
    237130 
    238         } else { 
    239  
    240             if (resample->large_filter) { 
    241  
    242                 SrcUD( resample->buffer + resample->xoff, output, 
    243                        resample->factor, resample->frame_size, 
    244                        resample_LARGE_FILTER_NWING,  
    245                        resample_LARGE_FILTER_SCALE * resample->factor + 0.5, 
    246                        resample_LARGE_FILTER_IMP, resample_LARGE_FILTER_IMPD, 
    247                        PJ_TRUE); 
    248  
    249             } else { 
    250  
    251                 SrcUD( resample->buffer + resample->xoff, output, 
    252                        resample->factor, resample->frame_size, 
    253                        resample_SMALL_FILTER_NWING,  
    254                        resample_SMALL_FILTER_SCALE * resample->factor + 0.5, 
    255                        resample_SMALL_FILTER_IMP, resample_SMALL_FILTER_IMPD, 
    256                        PJ_TRUE); 
    257  
    258             } 
    259  
    260         } 
    261  
    262         dst_buf = resample->buffer; 
    263         src_buf = input + resample->frame_size - resample->xoff*2; 
    264         pjmedia_copy_samples(dst_buf, src_buf, resample->xoff * 2); 
    265  
    266     } else { 
    267         SrcLinear( input, output, resample->factor, resample->frame_size); 
    268     } 
    269 } 
    270131 
    271132PJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample) 
    272133{ 
    273134    PJ_ASSERT_RETURN(resample != NULL, 0); 
    274     return resample->frame_size; 
     135    return resample->in_samples_per_frame; 
    275136} 
    276137 
     138 
     139PJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample) 
     140{ 
     141    PJ_ASSERT_ON_FAIL(resample, return); 
     142    if (resample->state) { 
     143        speex_resampler_destroy(resample->state); 
     144        resample->state = NULL; 
     145    } 
     146} 
     147 
  • pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/resample_port.c

    r974 r1171  
    9696                                     (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0, 
    9797                                     (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0, 
     98                                     dn_port->info.channel_count, 
    9899                                     dn_port->info.clock_rate,  
    99100                                     rport->base.info.clock_rate, 
     
    107108                                     (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,  
    108109                                     (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0, 
     110                                     dn_port->info.channel_count, 
    109111                                     rport->base.info.clock_rate,  
    110112                                     dn_port->info.clock_rate, 
     
    205207    } 
    206208 
    207     /* Nothing else to do */ 
     209    if (rport->resample_get) { 
     210        pjmedia_resample_destroy(rport->resample_get); 
     211        rport->resample_get = NULL; 
     212    } 
     213 
     214    if (rport->resample_put) { 
     215        pjmedia_resample_destroy(rport->resample_put); 
     216        rport->resample_put = NULL; 
     217    } 
    208218 
    209219    return PJ_SUCCESS; 
  • pjproject/branches/split-3rd-party/pjproject.dsw

    r1170 r1171  
    4040############################################################################### 
    4141 
    42 Project: "libresample"=".\THIRD_PARTY\BUILD\RESAMPLE\libresample.dsp" - Package Owner=<4> 
    43  
    44 Package=<5> 
    45 {{{ 
    46 }}} 
    47  
    48 Package=<4> 
    49 {{{ 
    50 }}} 
    51  
    52 ############################################################################### 
    53  
    5442Project: "libspeex"=".\third_party\build\speex\libspeex.dsp" - Package Owner=<4> 
    5543 
  • pjproject/branches/split-3rd-party/third_party/build/speex/libspeex.dsp

    r1168 r1171  
    6767F90=df.exe 
    6868# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c 
    69 # ADD CPP /nologo /MTd /W3 /GX /Ox /Ot /Og /Oi /Ob2 /I "." /I "../../speex/include" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c 
     69# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /Ob0 /I "." /I "../../speex/include" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c 
    7070# ADD BASE RSC /l 0x809 /d "_DEBUG" 
    7171# ADD RSC /l 0x809 /d "_DEBUG" 
Note: See TracChangeset for help on using the changeset viewer.