Changeset 1746

Show
Ignore:
Timestamp:
07/03/98 17:43:25 (16 years ago)
Author:
ucacoxh
Message:

- Start of downsampling re-implementation.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • rat/trunk/convert.c

    r1744 r1746  
    6161} converter_fmt_t; 
    6262 
     63/* Mono-Stereo Conversion ****************************************************/  
     64/* Note src_len is length block in number of samples i.e 
     65 *                                              nChannels * nSamplingIntervals  
     66 */ 
     67 
     68static void 
     69converter_change_channels (sample *src,  
     70                           int src_len,  
     71                           int src_channels,  
     72                           sample *dst,  
     73                           int dst_len,  
     74                           int dst_channels) 
     75{ 
     76        int i; 
     77        sample *s, *d; 
     78        int t; 
     79        assert(src_channels == 1 || src_channels == 2); 
     80        assert(dst_channels == 1 || dst_channels == 2); 
     81        assert(dst_channels != src_channels); 
     82        assert(src_len/src_channels == dst_len/dst_channels); 
     83         
     84        /* nb we run backwards through bufs so inplace conversion 
     85         * works if necessary. 
     86         */ 
     87 
     88        switch(src_channels) { 
     89        case 1: 
     90                s = src + src_len - 1;  
     91                d = dst + dst_len - 1; 
     92                for(i = 0; i < src_len; i++) { 
     93                        *d-- = *s; 
     94                        *d-- = *s--; 
     95                } 
     96                break; 
     97        case 2: 
     98                s = src + src_len - 1; 
     99                d = dst + dst_len - 1; 
     100                for(i = 0; i < src_len; i++) { 
     101                        t    = *s--; 
     102                        t   += *s--; 
     103                        t   /= 2; 
     104                        *d-- = t; 
     105                } 
     106                break; 
     107        } 
     108} 
     109 
     110static int 
     111gcd (int a, int b) 
     112{ 
     113        if (b) return gcd(b, a%b); 
     114        return 0; 
     115} 
     116 
    63117#ifdef WIN32 
    64118 
     
    68122 
    69123static BOOL CALLBACK  
    70 getPCMConverter(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport) 
     124getPCMConverter (HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport) 
    71125{ 
    72126        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) { 
     
    82136 
    83137static int  
    84 acm_conv_load(void) 
     138acm_conv_load (void) 
    85139{ 
    86140     acmDriverEnum(getPCMConverter, 0L, 0L); 
     
    90144 
    91145static void  
    92 acm_conv_unload(void) 
     146acm_conv_unload (void) 
    93147{ 
    94148        if (hDrv) acmDriverClose(hDrv, 0); 
     
    97151 
    98152void 
    99 acm_conv_init_fmt(WAVEFORMATEX *pwfx, u_int16 nChannels, u_int16 nSamplesPerSec) 
    100 { 
    101        pwfx->wFormatTag = WAVE_FORMAT_PCM; 
     153acm_conv_init_fmt (WAVEFORMATEX *pwfx, u_int16 nChannels, u_int16 nSamplesPerSec) 
     154{ 
     155       pwfx->wFormatTag      = WAVE_FORMAT_PCM; 
    102156       pwfx->nChannels       = nChannels; 
    103157       pwfx->nSamplesPerSec  = nSamplesPerSec; 
     
    108162 
    109163static int 
    110 acm_conv_init(converter_t *c) 
     164acm_conv_init (converter_t *c) 
    111165{ 
    112166        LPHACMSTREAM lpa; 
     
    124178 
    125179static void 
    126 acm_conv_do(converter_t *c, sample *src_buf, int src_len, sample *dst_buf, int dst_len) 
     180acm_convert (converter_t *c, sample *src_buf, int src_len, sample *dst_buf, int dst_len) 
    127181{ 
    128182        ACMSTREAMHEADER ash; 
     
    142196                memset(dst_buf, 0, dst_len * sizeof(sample)); 
    143197        } 
    144         xmemchk(); 
    145198        return; 
    146199} 
     
    157210 
    158211#endif /* WIN32 */ 
     212 
     213/* FILTERED SAMPLE RATE CONVERSION CODE *************************************/ 
     214 
     215#define SRF_FILTW_SCALE  6  
     216#define SRF_NTABLES      5 
     217#define SRF_SCALE        256 
     218 
     219/* Tables are for M = 2, 3, 4, 5(not used), 6 */ 
     220int **srf_tbl_up; 
     221int **srf_tbl_dn; 
     222 
     223/* If you want better quality make tbl sizes bigger (costs more), 
     224 * stick to multiples of these sizes otherwise converter becomes 
     225 * a noise generator. 
     226 */ 
     227 
     228int tbl_sz_up[] = {8, 12, 16, 20, 24}; 
     229int tbl_sz_dn[] = {8, 12, 16, 20, 24}; 
     230 
     231#define SF2IDX(x) ((x)-2) 
     232#define IDX2SF(x) ((x)+2) 
     233 
     234typedef void (*srf_cf)(int offset, int channels, sample* src_buf, int src_len, sample* dst_buf, struct s_srf_filter_state *sf); 
     235 
     236typedef struct s_srf_filter_state { 
     237        short   scale; 
     238        short   tbl_idx; 
     239        int*    tbl; 
     240        srf_cf  convert_f; 
     241        sample *last; 
     242        short   last_sz; 
     243        short   phase; 
     244        short   dst_freq; 
     245} srf_filter_state_t; 
     246 
     247typedef struct s_srf_state { 
     248        srf_filter_state_t *fs; 
     249        int                 steps;      /* number of steps conversion takes */ 
     250        sample             *tmp_buf; 
     251        int                 tmp_sz; 
     252} srf_state_t; 
     253 
     254static int  
     255srf_tbl_init(void) 
     256{ 
     257        int i,j; 
     258        double f; 
     259        srf_tbl_up = (int**)xmalloc(sizeof(int*)*SRF_NTABLES); 
     260        srf_tbl_dn = (int**)xmalloc(sizeof(int*)*SRF_NTABLES); 
     261 
     262        for(i = 0; i < SRF_NTABLES; i++) { 
     263                srf_tbl_up[i] = (int*)xmalloc(sizeof(int)*tbl_sz_up[i]); 
     264                srf_tbl_dn[i] = (int*)xmalloc(sizeof(int)*tbl_sz_dn[i]); 
     265                srf_tbl_up[i][0] = SRF_SCALE; 
     266                for(j = 1; j < tbl_sz_up[i]; j++) { 
     267                        f = M_PI * (double)j / (double)IDX2SF(i); 
     268                        srf_tbl_up[i][j] = (int)((double)SRF_SCALE * sin(f)/ f); 
     269                } 
     270                srf_tbl_dn[i][0] = (int)((double)SRF_SCALE * (1.0 / (double)(i+2)));  
     271                for(j = 1; j < tbl_sz_dn[i]; j++) { 
     272                        f = M_PI * (double)j / (double)IDX2SF(i); 
     273                        srf_tbl_up[i][j] = (int)((double)SRF_SCALE * sin(f)/ f); 
     274                        srf_tbl_dn[i][j] = IDX2SF(i) * ((int)((double)SRF_SCALE * sin(f)/ f)); 
     275                } 
     276        } 
     277 
     278        return TRUE; 
     279} 
     280 
     281static void 
     282srf_tbl_free (void) 
     283{ 
     284        int i; 
     285        for(i = 0; i < SRF_NTABLES; i++) { 
     286                xfree(srf_tbl_up[i]); 
     287                xfree(srf_tbl_dn[i]); 
     288        } 
     289        xfree(srf_tbl_up); 
     290        xfree(srf_tbl_dn); 
     291} 
     292 
     293static void 
     294srf_downsample(int offset, int channels, sample *src, int src_len, sample *dst, srf_filter_state_t *sf) 
     295{ 
     296        sample *src_c, *src_l, *src_r, *src_e; 
     297        int *h_c, *h, *h_e; 
     298        int win_sz, result, i; 
     299        int src_step; 
     300 
     301        win_sz = 2 * tbl_sz_dn[sf->tbl_idx] - 1; 
     302        h_c = srf_tbl_dn[sf->tbl_idx]; 
     303        h_e = srf_tbl_dn[sf->tbl_idx] + tbl_sz_dn[sf->tbl_idx]; 
     304         
     305        src_c    = sf->last + offset + (tbl_sz_dn[sf->tbl_idx] * channels)/2; 
     306        src_e    = sf->last + win_sz * channels;      
     307        src_step = channels * IDX2SF(sf->tbl_idx); 
     308 
     309        assert(win_sz * channels == sf->last_sz); 
     310        dst   += offset; 
     311 
     312        /* Stage 1: RHS of filter overlaps with last and current block */ 
     313 
     314        /* Stage 2: LHS of filter overlaps last and current */ 
     315 
     316        /* Stage 3: Filter completely within last block */ 
     317        UNUSED(result); 
     318        UNUSED(src_l); 
     319        UNUSED(h); 
     320        UNUSED(src_r); 
     321        UNUSED(i); 
     322} 
     323 
     324static void 
     325srf_upsample(int offset, int channels, sample *src, int src_len, sample *dst, srf_filter_state_t *sf) 
     326{ 
     327        sample *src_c, *src_l = NULL, *src_r = NULL, *src_e = NULL; 
     328        int win_sz, result, i; 
     329        int *h_c, *h_l, *h_r, *h_e; 
     330         
     331        win_sz = 2 * tbl_sz_up[sf->tbl_idx] - 1; 
     332        h_c = srf_tbl_up[sf->tbl_idx]; 
     333        h_e = srf_tbl_up[sf->tbl_idx] + tbl_sz_up[sf->tbl_idx]; 
     334 
     335        src_c  = sf->last + offset + (tbl_sz_up[sf->tbl_idx] * channels)/2;  
     336        src_e  = sf->last + win_sz * channels; 
     337        assert(win_sz * channels == sf->last_sz); 
     338 
     339        dst   += offset; 
     340 
     341        /* Stage One: Right hand side of window overlaps with last buffer and current, 
     342         *            left hand side of window completely within last. 
     343         */ 
     344        assert(sf->phase == 0); 
     345         
     346        while(src_c < src_e) { 
     347                if (sf->phase == 0) { 
     348                        *dst      = *src_c; 
     349                        dst      += channels; 
     350                        sf->phase = 1; 
     351                } 
     352                h_l = h_c + sf->phase; 
     353                h_r = h_c + sf->scale - sf->phase; 
     354                src_l = src_c; 
     355                result = 0; 
     356                 
     357                while(h_l < h_e) { 
     358                        result += (*h_l) * (*src_l); 
     359                        src_l  -= channels; 
     360                        h_l++; 
     361                } 
     362                src_r = src_c + channels; 
     363                assert(src_r < src_e); 
     364                i = (src_e - src_c)/channels; 
     365                 
     366                while(i) { 
     367                        assert(src_r < src_e); 
     368                        result += (*src_r) * (*h_r); 
     369                        src_r++; 
     370                        h_r++; 
     371                        i--; 
     372                } 
     373                 
     374                src_r = src + offset; 
     375                while(h_r < h_e) { 
     376                        result += (*src_r) * (*h_r); 
     377                        src_r++; 
     378                        h_r++; 
     379                } 
     380 
     381                *dst = (short)(result/SRF_SCALE); 
     382                dst += channels; 
     383                sf->phase++; 
     384                if (sf->phase == sf->scale) { 
     385                        sf->phase =0;  
     386                        src_c+= channels; 
     387                } 
     388        } 
     389 
     390        /* Stage Two: Left hand side of window overlaps with last buffer and current, 
     391         *            right hand side of window completely within current. 
     392         */ 
     393        assert(sf->phase == 0); 
     394 
     395        src_c = src   + offset; 
     396        src_e = src_c + win_sz * channels; 
     397 
     398        while(src_c < src_e) { 
     399                if (sf->phase == 0) { 
     400                        *dst      = *src_c; 
     401                        dst      += channels; 
     402                        sf->phase = 1; 
     403                } 
     404                h_l = h_c + sf->phase; 
     405                h_r = h_c + sf->scale - sf->phase; 
     406                src_r = src_c + channels; 
     407                 
     408                result = 0; 
     409                while(h_r < h_e) { 
     410                        result += (*src_r) * (*h_r); 
     411                        src_r  += channels; 
     412                        h_r    ++; 
     413                } 
     414 
     415                src_l = src_c; 
     416                while(src_l >= src) { 
     417                        result += (*src_l) * (*h_l); 
     418                        src_l  -= channels; 
     419                        h_l    ++; 
     420                } 
     421 
     422                src_l = sf->last + sf->last_sz - channels + offset; 
     423                while(h_l < h_e) { 
     424                        result += (*src_l) * (*h_l); 
     425                        src_l  -= channels; 
     426                        h_l    ++; 
     427                } 
     428                 
     429                *dst = (short)(result/SRF_SCALE); 
     430                dst += channels; 
     431                sf->phase++; 
     432                if (sf->phase == sf->scale) { 
     433                        sf->phase = 0; 
     434                        src_c += channels; 
     435                } 
     436        } 
     437 
     438        /* Stage Three: All of window within current buffer. */ 
     439        assert(sf->phase == 0); 
     440        src_e = src + src_len - tbl_sz_up[sf->tbl_idx] * channels; 
     441 
     442        while(src_c < src_e) { 
     443                if (sf->phase == 0) { 
     444                        *dst = *src_c; 
     445                        dst += channels; 
     446                } 
     447                src_l = src_c; 
     448                src_r = src_c + channels; 
     449                h_l   = h_c   + sf->phase; 
     450                h_r   = h_c   + sf->scale - sf->phase; 
     451                result = 0; 
     452                while (h_r != h_e) { 
     453                        result += (*src_l)*(*h_l) + (*src_r)*(*h_r); 
     454                        src_l  -= channels; 
     455                        src_r  += channels; 
     456                        h_l++; 
     457                        h_r++; 
     458                } 
     459                *dst = (short)(result / SRF_SCALE); 
     460                dst += channels; 
     461                sf->phase++; 
     462                if (sf->phase == sf->scale) { 
     463                        sf->phase = 1; 
     464                        src_c += channels; 
     465                } 
     466        } 
     467 
     468        src_c = src + src_len - win_sz; 
     469        if (offset == 0) { 
     470                memcpy(sf->last,src_c,win_sz); 
     471        } else { 
     472                src_c++; 
     473                dst = sf->last++; 
     474                while(src_c < src + src_len) { 
     475                        *dst = *src_c; 
     476                        src_c += channels; 
     477                        dst   += channels; 
     478                } 
     479        } 
     480        xmemchk(); 
     481} 
     482 
     483static  
     484void srf_init_filter(srf_filter_state_t *sf, int src_freq, int dst_freq, int channels) 
     485{ 
     486        if (src_freq > dst_freq) { 
     487                sf->scale     = src_freq / dst_freq; 
     488                sf->tbl_idx   = (SF2IDX(src_freq/dst_freq)); 
     489                sf->tbl       = srf_tbl_dn[sf->tbl_idx]; 
     490                sf->convert_f = srf_downsample; 
     491                sf->last_sz   = (2 * tbl_sz_dn[sf->tbl_idx] - 1) * channels; 
     492                sf->last      = (sample *) xmalloc (sf->last_sz * sizeof(sample)); 
     493                sf->phase     = 0; 
     494                sf->dst_freq  = dst_freq; 
     495        } else { 
     496                sf->scale     = dst_freq / src_freq; 
     497                sf->tbl_idx   = (SF2IDX(dst_freq/src_freq)); 
     498                sf->tbl       = srf_tbl_up[sf->tbl_idx]; 
     499                sf->convert_f = srf_upsample; 
     500                sf->last_sz   = (2 * tbl_sz_up[sf->tbl_idx] - 1) * channels; 
     501                sf->last      = (sample *) xmalloc (sf->last_sz * sizeof(sample)); 
     502                sf->phase     = 0; 
     503                sf->dst_freq  = dst_freq; 
     504        } 
     505        memset(sf->last, 0, sizeof(sample) * sf->last_sz); 
     506} 
     507 
     508/* This code is written so that if we do non-integer rate conversion  
     509 * we downsample to lowest common divisor, and then upsample again. 
     510 *  
     511 * This is really the wrong thing to do, we should upsample to a  
     512 * common multiple, then downsample, but this requires much more 
     513 * work and memory.  The reality for RAT is that we only ever convert  
     514 * between multiples of 8K, so the only problem is with conversion  
     515 * between 32K and 48K.  For sake of argument, most computer audio  
     516 * hardware isn't good enough too tell either way, so we'll take the  
     517 * cheap ticket. 
     518 */ 
     519 
     520static int  
     521srf_init (converter_t *c) 
     522{ 
     523        srf_state_t *s; 
     524        int denom, src_freq, dst_freq, src_channels, dst_channels; 
     525 
     526        assert(c->conv_fmt->from_freq % 8000 == 0); 
     527        assert(c->conv_fmt->to_freq   % 8000 == 0); 
     528         
     529        if (c->conv_fmt->to_freq == c->conv_fmt->from_freq) { 
     530                c->data     = NULL; 
     531                c->data_len = 0; 
     532                return TRUE; 
     533        } 
     534 
     535        s = (srf_state_t*) xmalloc(sizeof(srf_state_t)); 
     536        memset(s, 0, sizeof(srf_state_t)); 
     537         
     538        c->data     = (char*)s; 
     539        c->data_len = sizeof(srf_state_t); 
     540         
     541        src_freq     = c->conv_fmt->from_freq; 
     542        src_channels = c->conv_fmt->from_channels;  
     543        dst_freq     = c->conv_fmt->to_freq; 
     544        dst_channels = c->conv_fmt->to_channels;  
     545 
     546        denom = gcd(src_freq, dst_freq); 
     547        if (denom == 8000) { 
     548                s->fs    = (srf_filter_state_t*)xmalloc(sizeof(srf_filter_state_t)); 
     549                s->steps = 1; 
     550                srf_init_filter(s->fs,    src_freq, dst_freq, src_channels); 
     551        } else { 
     552                s->fs    = (srf_filter_state_t*)xmalloc(sizeof(srf_filter_state_t) * 2); 
     553                s->steps = 2; 
     554                srf_init_filter(s->fs,    src_freq, denom,    src_channels); 
     555                srf_init_filter(s->fs+ 1, denom,    dst_freq, dst_channels); 
     556        } 
     557 
     558        return TRUE; 
     559} 
     560 
     561static void 
     562srf_convert (converter_t  *c, sample* src_buf, int src_len, sample *dst_buf, int dst_len) 
     563{ 
     564        int channels = c->conv_fmt->from_channels; 
     565         
     566        if (c->conv_fmt->from_channels == 2 && c->conv_fmt->to_channels == 1) { 
     567                /* stereo->mono then sample rate change */ 
     568                converter_change_channels(src_buf, src_len, 2, src_buf, src_len / 2, 1);  
     569                src_len /= 2; 
     570                channels = 1; 
     571        } 
     572 
     573        if (c->data) { 
     574                srf_state_t *s = (srf_state_t*)c->data; 
     575                int i; 
     576                if (s->steps == 1) { 
     577                        for (i = 0; i < channels; i++)  { 
     578                                s->fs[0].convert_f(i, channels, src_buf, src_len, dst_buf, s->fs); 
     579                        } 
     580                } else { 
     581                        assert(s->steps == 2); 
     582                        if (s->tmp_buf == NULL) { 
     583                                s->tmp_sz  = src_len * c->conv_fmt->from_freq / s->fs->dst_freq; 
     584                                s->tmp_buf = (sample*)xmalloc(sizeof(sample) * s->tmp_sz); 
     585                        } 
     586                        for(i = 0; i < channels; i++) { 
     587                                s->fs[0].convert_f(i, channels, src_buf, src_len, s->tmp_buf, s->fs); 
     588                        } 
     589                        for(i = 0; i < channels; i++) { 
     590                                s->fs[1].convert_f(i, channels, s->tmp_buf, s->tmp_sz, dst_buf, s->fs); 
     591                        } 
     592                } 
     593        } 
     594 
     595        if (c->conv_fmt->from_channels == 2 && c->conv_fmt->to_channels == 1) { 
     596                /* sample rate change before mono-> stereo */ 
     597                converter_change_channels(dst_buf, dst_len, 1, dst_buf, dst_len * 2, 2); 
     598        } 
     599} 
     600 
     601static void  
     602srf_free (converter_t *c) 
     603{ 
     604        int i; 
     605        srf_state_t *s = (srf_state_t*)c->data; 
     606        assert(c->data_len == sizeof(srf_state_t)); 
     607        for(i = 0; i < s->steps; i++)  { 
     608                if (s->fs[i].last) xfree(s->fs[i].last); 
     609        } 
     610        xfree(s->fs); 
     611        if (s->tmp_buf) xfree(s->tmp_buf); 
     612        xfree(s); 
     613        c->data     = NULL; 
     614        c->data_len = 0; 
     615} 
    159616 
    160617static int  
     
    180637        UNUSED(c); 
    181638} 
     639 
    182640 
    183641typedef int  (*pcm_startup)     (void);  /* converter specific one time initialization */ 
     
    199657} pcm_converter_t; 
    200658 
    201 #define CONVERT_NONE     0 
     659#define CONVERT_NONE     255 
    202660#define CONVERT_PLATFORM 1 
    203 #define CONVERT_LINEAR   2 
    204 #define CONVERT_LINEARF  3 
     661#define CONVERT_SRF      2 
     662#define CONVERT_LINEAR   3 
    205663#define CONVERT_CUBIC    4 
    206664 
     
    213671pcm_converter_t converter_tbl[] = { 
    214672#ifdef WIN32 
    215         {CONVERT_PLATFORM, "MS PCM Converter", FALSE, acm_conv_load, acm_conv_unload, acm_conv_init, acm_conv_do,  acm_conv_free, sizeof(HACMSTREAM)}, 
     673        {CONVERT_PLATFORM, "MS Converter", FALSE, acm_conv_load, acm_conv_unload, acm_conv_init, acm_convert,  acm_conv_free, sizeof(HACMSTREAM)}, 
    216674#endif 
    217         {CONVERT_LINEAR  , "Linear",           TRUE , NULL,          NULL,            linear_init, linear_convert, linear_free,   0}, 
    218         {CONVERT_NONE    , "None",             FALSE, NULL,          NULL,            NULL,        NULL,           NULL,          0} 
     675        {CONVERT_SRF     , "Filtered",     TRUE,  srf_tbl_init,  srf_tbl_free,    srf_init,    srf_convert,       srf_free,      0}, 
     676        {CONVERT_LINEAR  , "Linear",       TRUE , NULL,          NULL,            linear_init, linear_convert, linear_free,   0}, 
     677        {CONVERT_NONE    , "None",         FALSE, NULL,          NULL,            NULL,        NULL,           NULL,          0} 
    219678}; 
    220679