Ignore:
Timestamp:
Apr 9, 2007 7:06:08 AM (18 years ago)
Author:
bennylp
Message:

Fixed all VS6 and VS8 projects with new third party projects layout

Location:
pjproject/branches/split-3rd-party/third_party/resample/src
Files:
1 added
1 moved

Legend:

Unmodified
Added
Removed
  • pjproject/branches/split-3rd-party/third_party/resample/src/resamplesubs.c

    r1176 r1177  
    11/* $Id$ */ 
    22/* 
    3  * Based on: 
    4  * resample-1.8.tar.gz from the  
    53 * Digital Audio Resampling Home Page located at 
    64 * http://www-ccrma.stanford.edu/~jos/resample/. 
     
    4240 *  - const correctness. 
    4341 */ 
    44 #include <pjmedia/resample.h> 
    45 #include <pjmedia/errno.h> 
    46 #include <pj/assert.h> 
    47 #include <pj/log.h> 
    48 #include <pj/pool.h> 
    49  
    50  
    51 #define THIS_FILE   "resample.c" 
    52  
    53  
    54 /* 
    55  * Taken from stddefs.h 
    56  */ 
    57 #ifndef PI 
    58 #define PI (3.14159265358979232846) 
    59 #endif 
    60  
    61 #ifndef PI2 
    62 #define PI2 (6.28318530717958465692) 
    63 #endif 
    64  
    65 #define D2R (0.01745329348)          /* (2*pi)/360 */ 
    66 #define R2D (57.29577951)            /* 360/(2*pi) */ 
    67  
    68 #ifndef MAX 
    69 #define MAX(x,y) ((x)>(y) ?(x):(y)) 
    70 #endif 
    71 #ifndef MIN 
    72 #define MIN(x,y) ((x)<(y) ?(x):(y)) 
    73 #endif 
    74  
    75 #ifndef ABS 
    76 #define ABS(x)   ((x)<0   ?(-(x)):(x)) 
    77 #endif 
    78  
    79 #ifndef SGN 
    80 #define SGN(x)   ((x)<0   ?(-1):((x)==0?(0):(1))) 
    81 #endif 
    82  
    83 typedef char           RES_BOOL; 
    84 typedef short          RES_HWORD; 
    85 typedef int            RES_WORD; 
    86 typedef unsigned short RES_UHWORD; 
    87 typedef unsigned int   RES_UWORD; 
    88  
    89 #define MAX_HWORD (32767) 
    90 #define MIN_HWORD (-32768) 
    91  
    92 #ifdef DEBUG 
    93 #define INLINE 
    94 #else 
    95 #define INLINE inline 
    96 #endif 
    97  
    98 /* 
    99  * Taken from resample.h 
    100  * 
    101  * The configuration constants below govern 
    102  * the number of bits in the input sample and filter coefficients, the  
    103  * number of bits to the right of the binary-point for fixed-point math, etc. 
    104  * 
    105  */ 
    106  
    107 /* Conversion constants */ 
    108 #define Nhc       8 
    109 #define Na        7 
    110 #define Np       (Nhc+Na) 
    111 #define Npc      (1<<Nhc) 
    112 #define Amask    ((1<<Na)-1) 
    113 #define Pmask    ((1<<Np)-1) 
    114 #define Nh       16 
    115 #define Nb       16 
    116 #define Nhxn     14 
    117 #define Nhg      (Nh-Nhxn) 
    118 #define NLpScl   13 
    119  
    120 /* Description of constants: 
    121  * 
    122  * Npc - is the number of look-up values available for the lowpass filter 
    123  *    between the beginning of its impulse response and the "cutoff time" 
    124  *    of the filter.  The cutoff time is defined as the reciprocal of the 
    125  *    lowpass-filter cut off frequence in Hz.  For example, if the 
    126  *    lowpass filter were a sinc function, Npc would be the index of the 
    127  *    impulse-response lookup-table corresponding to the first zero- 
    128  *    crossing of the sinc function.  (The inverse first zero-crossing 
    129  *    time of a sinc function equals its nominal cutoff frequency in Hz.) 
    130  *    Npc must be a power of 2 due to the details of the current 
    131  *    implementation. The default value of 512 is sufficiently high that 
    132  *    using linear interpolation to fill in between the table entries 
    133  *    gives approximately 16-bit accuracy in filter coefficients. 
    134  * 
    135  * Nhc - is log base 2 of Npc. 
    136  * 
    137  * Na - is the number of bits devoted to linear interpolation of the 
    138  *    filter coefficients. 
    139  * 
    140  * Np - is Na + Nhc, the number of bits to the right of the binary point 
    141  *    in the integer "time" variable. To the left of the point, it indexes 
    142  *    the input array (X), and to the right, it is interpreted as a number 
    143  *    between 0 and 1 sample of the input X.  Np must be less than 16 in 
    144  *    this implementation. 
    145  * 
    146  * Nh - is the number of bits in the filter coefficients. The sum of Nh and 
    147  *    the number of bits in the input data (typically 16) cannot exceed 32. 
    148  *    Thus Nh should be 16.  The largest filter coefficient should nearly 
    149  *    fill 16 bits (32767). 
    150  * 
    151  * Nb - is the number of bits in the input data. The sum of Nb and Nh cannot 
    152  *    exceed 32. 
    153  * 
    154  * Nhxn - is the number of bits to right shift after multiplying each input 
    155  *    sample times a filter coefficient. It can be as great as Nh and as 
    156  *    small as 0. Nhxn = Nh-2 gives 2 guard bits in the multiply-add 
    157  *    accumulation.  If Nhxn=0, the accumulation will soon overflow 32 bits. 
    158  * 
    159  * Nhg - is the number of guard bits in mpy-add accumulation (equal to Nh-Nhxn) 
    160  * 
    161  * NLpScl - is the number of bits allocated to the unity-gain normalization 
    162  *    factor.  The output of the lowpass filter is multiplied by LpScl and 
    163  *    then right-shifted NLpScl bits. To avoid overflow, we must have  
    164  *    Nb+Nhg+NLpScl < 32. 
    165  */ 
     42 
     43#include <resamplesubs.h> 
     44#include "config.h" 
     45#include "stddefs.h" 
     46#include "resample.h" 
    16647 
    16748 
     
    17455#endif 
    17556 
    176 #if defined(PJMEDIA_HAS_SMALL_FILTER) && PJMEDIA_HAS_SMALL_FILTER!=0 
     57#if defined(RESAMPLE_HAS_SMALL_FILTER) && RESAMPLE_HAS_SMALL_FILTER!=0 
    17758#   include "smallfilter.h" 
    17859#else 
     
    18465#endif 
    18566 
    186 #if defined(PJMEDIA_HAS_LARGE_FILTER) && PJMEDIA_HAS_LARGE_FILTER!=0 
     67#if defined(RESAMPLE_HAS_LARGE_FILTER) && RESAMPLE_HAS_LARGE_FILTER!=0 
    18768#   include "largefilter.h" 
    18869#else 
     
    439320 
    440321 
    441 /* *************************************************************************** 
    442  * 
    443  * PJMEDIA RESAMPLE  
    444  * 
    445  * *************************************************************************** 
    446  */ 
    447  
    448 struct pjmedia_resample 
    449 { 
    450     double       factor;        /* Conversion factor = rate_out / rate_in.  */ 
    451     pj_bool_t    large_filter;  /* Large filter?                            */ 
    452     pj_bool_t    high_quality;  /* Not fast?                                */ 
    453     unsigned     xoff;          /* History and lookahead size, in samples   */ 
    454     unsigned     frame_size;    /* Samples per frame.                       */ 
    455     pj_int16_t  *buffer;        /* Input buffer.                            */ 
    456 }; 
    457  
    458  
    459 PJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool, 
    460                                              pj_bool_t high_quality, 
    461                                              pj_bool_t large_filter, 
    462                                              unsigned channel_count, 
    463                                              unsigned rate_in, 
    464                                              unsigned rate_out, 
    465                                              unsigned samples_per_frame, 
    466                                              pjmedia_resample **p_resample) 
    467 { 
    468     pjmedia_resample *resample; 
    469  
    470     PJ_ASSERT_RETURN(pool && p_resample && rate_in && 
    471                      rate_out && samples_per_frame, PJ_EINVAL); 
    472  
    473     resample = pj_pool_alloc(pool, sizeof(pjmedia_resample)); 
    474     PJ_ASSERT_RETURN(resample, PJ_ENOMEM); 
    475  
    476     PJ_UNUSED_ARG(channel_count); 
    477  
    478     /* 
    479      * If we're downsampling, always use the fast algorithm since it seems 
    480      * to yield the same quality. 
    481      */ 
    482     if (rate_out < rate_in) { 
    483         //no this is not a good idea. It sounds pretty good with speech, 
    484         //but very poor with background noise etc. 
    485         //high_quality = 0; 
    486     } 
    487  
    488 #if !defined(PJMEDIA_HAS_LARGE_FILTER) || PJMEDIA_HAS_LARGE_FILTER==0 
    489     /* 
    490      * If large filter is excluded in the build, then prevent application 
    491      * from using it. 
    492      */ 
    493     if (high_quality && large_filter) { 
    494         large_filter = PJ_FALSE; 
    495         PJ_LOG(5,(THIS_FILE,  
    496                   "Resample uses small filter because large filter is " 
    497                   "disabled")); 
    498     } 
    499 #endif 
    500  
    501 #if !defined(PJMEDIA_HAS_SMALL_FILTER) || PJMEDIA_HAS_SMALL_FILTER==0 
    502     /* 
    503      * If small filter is excluded in the build and application wants to 
    504      * use it, then drop to linear conversion. 
    505      */ 
    506     if (high_quality && large_filter == 0) { 
    507         high_quality = PJ_FALSE; 
    508         PJ_LOG(4,(THIS_FILE,  
    509                   "Resample uses linear because small filter is disabled")); 
    510     } 
    511 #endif 
    512  
    513     resample->factor = rate_out * 1.0 / rate_in; 
    514     resample->large_filter = large_filter; 
    515     resample->high_quality = high_quality; 
    516     resample->frame_size = samples_per_frame; 
    517  
    518     if (high_quality) { 
    519         unsigned size; 
    520  
    521         /* This is a bug in xoff calculation, thanks Stephane Lussier 
    522          * of Macadamian dot com. 
    523          *   resample->xoff = large_filter ? 32 : 6; 
    524          */ 
    525         if (large_filter) 
    526             resample->xoff = (LARGE_FILTER_NMULT + 1) / 2.0  *   
    527                              MAX(1.0, 1.0/resample->factor); 
     322int res_SrcLinear(const RES_HWORD X[], RES_HWORD Y[],  
     323                  double pFactor, RES_UHWORD nx) 
     324{ 
     325    return SrcLinear(X, Y, pFactor, nx); 
     326} 
     327 
     328int res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor,  
     329                 RES_UHWORD nx, RES_BOOL LargeF, RES_BOOL Interp) 
     330{ 
     331    if (pFactor >= 1) { 
     332 
     333        if (LargeF) 
     334            return SrcUp(X, Y, pFactor, nx, 
     335                         LARGE_FILTER_NWING, LARGE_FILTER_SCALE, 
     336                         LARGE_FILTER_IMP, LARGE_FILTER_IMPD, Interp); 
    528337        else 
    529             resample->xoff = (SMALL_FILTER_NMULT + 1) / 2.0  *   
    530                              MAX(1.0, 1.0/resample->factor); 
    531  
    532  
    533         size = (samples_per_frame + 2*resample->xoff) * sizeof(pj_int16_t); 
    534         resample->buffer = pj_pool_alloc(pool, size); 
    535         PJ_ASSERT_RETURN(resample->buffer, PJ_ENOMEM); 
    536  
    537         pjmedia_zero_samples(resample->buffer, resample->xoff*2); 
    538  
     338            return SrcUp(X, Y, pFactor, nx, 
     339                         SMALL_FILTER_NWING, SMALL_FILTER_SCALE, 
     340                         SMALL_FILTER_IMP, SMALL_FILTER_IMPD, Interp); 
    539341 
    540342    } else { 
    541         resample->xoff = 0; 
    542     } 
    543  
    544     *p_resample = resample; 
    545  
    546     PJ_LOG(5,(THIS_FILE, "resample created: %s qualiy, %s filter, in/out " 
    547                           "rate=%d/%d",  
    548                           (high_quality?"high":"low"), 
    549                           (large_filter?"large":"small"), 
    550                           rate_in, rate_out)); 
    551     return PJ_SUCCESS; 
    552 } 
    553  
    554  
    555  
    556 PJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample, 
    557                                    const pj_int16_t *input, 
    558                                    pj_int16_t *output ) 
    559 { 
    560     PJ_ASSERT_ON_FAIL(resample, return); 
    561  
    562     if (resample->high_quality) { 
    563         pj_int16_t *dst_buf; 
    564         const pj_int16_t *src_buf; 
    565  
    566         /* Okay chaps, here's how we do resampling. 
    567          * 
    568          * The original resample algorithm requires xoff samples *before* the 
    569          * input buffer as history, and another xoff samples *after* the 
    570          * end of the input buffer as lookahead. Since application can only 
    571          * supply framesize buffer on each run, PJMEDIA needs to arrange the 
    572          * buffer to meet these requirements. 
    573          * 
    574          * So here comes the trick. 
    575          * 
    576          * First of all, because of the history and lookahead requirement,  
    577          * resample->buffer need to accomodate framesize+2*xoff samples in its 
    578          * buffer. This is done when the buffer is created. 
    579          * 
    580          * On the first run, the input frame (supplied by application) is 
    581          * copied to resample->buffer at 2*xoff position. The first 2*xoff 
    582          * samples are initially zeroed (in the initialization). The resample 
    583          * algorithm then invoked at resample->buffer+xoff ONLY, thus giving 
    584          * it one xoff at the beginning as zero, and one xoff at the end 
    585          * as the end of the original input. The resample algorithm will see 
    586          * that the first xoff samples in the input as zero. 
    587          * 
    588          * So here's the layout of resample->buffer on the first run. 
    589          * 
    590          * run 0  
    591          *     +------+------+--------------+ 
    592          *     | 0000 | 0000 |  frame0...   | 
    593          *     +------+------+--------------+ 
    594          *     ^      ^      ^              ^ 
    595          *     0    xoff  2*xoff       size+2*xoff  
    596          * 
    597          * (Note again: resample algorithm is called at resample->buffer+xoff) 
    598          * 
    599          * At the end of the run, 2*xoff samples from the end of  
    600          * resample->buffer are copied to the beginning of resample->buffer. 
    601          * The first xoff part of this will be used as history for the next 
    602          * run, and the second xoff part of this is actually the start of 
    603          * resampling for the next run. 
    604          * 
    605          * And the first run completes, the function returns. 
    606          * 
    607          *  
    608          * On the next run, the input frame supplied by application is again 
    609          * copied at 2*xoff position in the resample->buffer, and the  
    610          * resample algorithm is again invoked at resample->buffer+xoff  
    611          * position. So effectively, the resample algorithm will start its 
    612          * operation on the last xoff from the previous frame, and gets the 
    613          * history from the last 2*xoff of the previous frame, and the look- 
    614          * ahead from the last xoff of current frame. 
    615          * 
    616          * So on this run, the buffer layout is: 
    617          * 
    618          * run 1 
    619          *     +------+------+--------------+ 
    620          *     | frm0 | frm0 |  frame1...   | 
    621          *     +------+------+--------------+ 
    622          *     ^      ^      ^              ^ 
    623          *     0    xoff  2*xoff       size+2*xoff  
    624          * 
    625          * As you can see from above diagram, the resampling algorithm is 
    626          * actually called from the last xoff part of previous frame (frm0). 
    627          * 
    628          * And so on the process continues for the next frame, and the next, 
    629          * and the next, ... 
    630          * 
    631          */ 
    632         dst_buf = resample->buffer + resample->xoff*2; 
    633         pjmedia_copy_samples(dst_buf, input, resample->frame_size); 
    634              
    635         if (resample->factor >= 1) { 
    636  
    637             if (resample->large_filter) { 
    638                 SrcUp(resample->buffer + resample->xoff, output, 
    639                       resample->factor, resample->frame_size, 
    640                       LARGE_FILTER_NWING, LARGE_FILTER_SCALE, 
    641                       LARGE_FILTER_IMP, LARGE_FILTER_IMPD, 
    642                       PJ_TRUE); 
    643             } else { 
    644                 SrcUp(resample->buffer + resample->xoff, output, 
    645                       resample->factor, resample->frame_size, 
    646                       SMALL_FILTER_NWING, SMALL_FILTER_SCALE, 
    647                       SMALL_FILTER_IMP, SMALL_FILTER_IMPD, 
    648                       PJ_TRUE); 
    649             } 
    650  
    651         } else { 
    652  
    653             if (resample->large_filter) { 
    654  
    655                 SrcUD( resample->buffer + resample->xoff, output, 
    656                        resample->factor, resample->frame_size, 
    657                        LARGE_FILTER_NWING,  
    658                        LARGE_FILTER_SCALE * resample->factor + 0.5, 
    659                        LARGE_FILTER_IMP, LARGE_FILTER_IMPD, 
    660                        PJ_TRUE); 
    661  
    662             } else { 
    663  
    664                 SrcUD( resample->buffer + resample->xoff, output, 
    665                        resample->factor, resample->frame_size, 
    666                        SMALL_FILTER_NWING,  
    667                        SMALL_FILTER_SCALE * resample->factor + 0.5, 
    668                        SMALL_FILTER_IMP, SMALL_FILTER_IMPD, 
    669                        PJ_TRUE); 
    670  
    671             } 
    672  
    673         } 
    674  
    675         dst_buf = resample->buffer; 
    676         src_buf = input + resample->frame_size - resample->xoff*2; 
    677         pjmedia_copy_samples(dst_buf, src_buf, resample->xoff * 2); 
    678  
    679     } else { 
    680         SrcLinear( input, output, resample->factor, resample->frame_size); 
    681     } 
    682 } 
    683  
    684 PJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample) 
    685 { 
    686     PJ_ASSERT_RETURN(resample != NULL, 0); 
    687     return resample->frame_size; 
    688 } 
    689  
    690 PJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample) 
    691 { 
    692     PJ_UNUSED_ARG(resample); 
    693 } 
    694  
    695  
     343 
     344        if (LargeF) 
     345            return SrcUD(X, Y, pFactor, nx,  
     346                         LARGE_FILTER_NWING, LARGE_FILTER_SCALE * pFactor + 0.5, 
     347                         LARGE_FILTER_IMP, LARGE_FILTER_IMPD, Interp); 
     348        else 
     349            return SrcUD(X, Y, pFactor, nx,  
     350                         SMALL_FILTER_NWING, SMALL_FILTER_SCALE * pFactor + 0.5, 
     351                         SMALL_FILTER_IMP, SMALL_FILTER_IMPD, Interp); 
     352 
     353    } 
     354} 
     355 
     356int res_GetXOFF(double pFactor, RES_BOOL LargeF) 
     357{ 
     358    if (LargeF) 
     359        return (LARGE_FILTER_NMULT + 1) / 2.0  *   
     360                MAX(1.0, 1.0/pFactor); 
     361    else 
     362        return (SMALL_FILTER_NMULT + 1) / 2.0  *   
     363                MAX(1.0, 1.0/pFactor); 
     364} 
     365 
Note: See TracChangeset for help on using the changeset viewer.