Mercurial > mplayer.hg
changeset 4171:585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
author | anders |
---|---|
date | Tue, 15 Jan 2002 13:21:45 +0000 |
parents | 32ad3c2833cf |
children | 8c17f26ec41a |
files | libao2/fir.h libao2/pl_resample.c |
diffstat | 2 files changed, 93 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/libao2/fir.h Tue Jan 15 12:35:16 2002 +0000 +++ b/libao2/fir.h Tue Jan 15 13:21:45 2002 +0000 @@ -111,7 +111,7 @@ #define SAVE_QUE(x) #define UPDATE_QUE(inm) \ xi=(--xi)&(L-1); \ - x[xi]=x[xi+L]=*inm; + x[xi]=x[xi+L]=*(inm); #ifdef L4 #define FIR(x,w,y) \
--- a/libao2/pl_resample.c Tue Jan 15 12:35:16 2002 +0000 +++ b/libao2/pl_resample.c Tue Jan 15 13:21:45 2002 +0000 @@ -24,7 +24,7 @@ #include "audio_plugin.h" #include "audio_plugin_internal.h" #include "afmt.h" -//#include "../config.h" +// #include "../config.h" static ao_info_t info = { @@ -46,15 +46,16 @@ memory usage. For now the filterlenght is choosen to 4 and without assembly optimization if no SSE is present. */ -#ifdef HAVE_SSE + +// #ifdef HAVE_SSE #define L8 1 // Filter bank type #define W W8 // Filter bank parameters #define L 8 // Filter length -#else -#define L4 1 -#define W W4 -#define L 4 -#endif +// #else +// #define L4 1 +// #define W W4 +// #define L 4 +// #endif #define CH 6 // Max number of channels #define UP 128 /* Up sampling factor. Increasing this value will @@ -73,12 +74,11 @@ uint16_t up; // Up sampling factor int channels; // Number of channels int len; // Lenght of buffer - int bypass; // Bypass this plugin int16_t ws[UP*L]; // List of all available filters int16_t xs[CH][L*2]; // Circular buffers } pl_resample_t; -static pl_resample_t pl_resample = {NULL,NULL,1,1,1,0,0,W}; +static pl_resample_t pl_resample = {NULL,NULL,1,1,1,0,W}; // to set/get/query special features/parameters static int control(int cmd,int arg){ @@ -117,11 +117,7 @@ return 0; } pl_resample.dn=(int)(0.5+((float)(fin*pl_resample.up))/((float)fout)); - if(pl_resample.dn == pl_resample.up){ - fprintf(stderr,"[pl_resample] Fin is too close to fout no conversion is needed.\n"); - pl_resample.bypass=1; - return 1; - } + pl_resample.channels=ao_plugin_data.channels; if(ao_plugin_data.channels>CH){ fprintf(stderr,"[pl_resample] Too many channels, max is 6.\n"); @@ -155,12 +151,79 @@ // called for every block of data // FIXME: this routine needs to be optimized (it is probably possible to do a lot here) static int play(){ + if(pl_resample.up==pl_resample.dn){ + register int16_t* in = ((int16_t*)ao_plugin_data.data); + register int16_t* end = in+ao_plugin_data.len/2; + while(in < end) *in=(*in++)>>1; + return 1; + } + if(pl_resample.up>pl_resample.dn) + return upsample(); + if(pl_resample.up<pl_resample.dn) + return downsample(); +} + +int upsample(){ + static uint16_t pwi = 0; // Index for w + static uint16_t pxi = 0; // Index for circular queue + + uint16_t ci = pl_resample.channels; // Index for channels + uint16_t nch = pl_resample.channels; // Number of channels + uint16_t len = 0; // Number of input samples + uint16_t inc = pl_resample.up/pl_resample.dn; + uint16_t level = pl_resample.up%pl_resample.dn; + uint16_t up = pl_resample.up; + uint16_t dn = pl_resample.dn; + + register int16_t* w = pl_resample.w; + register uint16_t wi,xi; // Temporary indexes + + // Index current channel + while(ci--){ + // Temporary pointers + register int16_t* x = pl_resample.xs[ci]; + register int16_t* in = ((int16_t*)ao_plugin_data.data)+ci; + register int16_t* out = pl_resample.data+ci; + int16_t* end = in+ao_plugin_data.len/2; // Block loop end + + wi = pwi; xi = pxi; + + LOAD_QUE(x); + while(in < end){ + register uint16_t i = inc; + if(wi<level) i++; + + UPDATE_QUE(in); + in+=nch; + + while(i--){ + // Run the FIR filter + FIR((&x[xi]),(&w[wi*L]),out); + len++; out+=nch; + // Update wi to point at the correct polyphase component + wi=(wi+dn)%up; + } + } + SAVE_QUE(x); + } + + // Save values that needs to be kept for next time + pwi = wi; + pxi = xi; + + // Set new data + ao_plugin_data.len=len*2; + ao_plugin_data.data=pl_resample.data; + return 1; +} + +int downsample(){ static uint16_t pwi = 0; // Index for w static uint16_t pxi = 0; // Index for circular queue static uint16_t pi = 1; // Number of new samples to put in x queue uint16_t ci = pl_resample.channels; // Index for channels - uint16_t len = 0; // Number of output samples + uint16_t len = 0; // Number of input samples uint16_t nch = pl_resample.channels; // Number of channels uint16_t inc = pl_resample.dn/pl_resample.up; uint16_t level = pl_resample.dn%pl_resample.up; @@ -169,8 +232,6 @@ register uint16_t i,wi,xi; // Temporary indexes - if(pl_resample.bypass) - return 1; // Index current channel while(ci--){ @@ -183,33 +244,26 @@ i = pi; wi = pwi; xi = pxi; LOAD_QUE(x); - if(0!=i) goto L1; while(in < end){ - // Update wi to point at the correct polyphase component - wi=(wi+dn)%up; - /* Update circular buffer x. This loop will be updated 0 or 1 time - for upsamling and inc or inc + 1 times for downsampling */ - if(wi<level) goto L3; - if(0==i) goto L2; - L1: i--; - L3: UPDATE_QUE(in); - in+=nch; - if(in >= end) goto L2; - if(i) goto L1; - L2: if(i) goto L5; - i=inc; + UPDATE_QUE(in); + in+=nch; + + if(!--i){ + // Run the FIR filter + FIR((&x[xi]),(&pl_resample.w[wi*L]),out); + len++; out+=nch; - /* Get the correct polyphase component and the correct startpoint - in the circular bufer and run the FIR filter */ - FIR((&x[xi]),(&pl_resample.w[wi*L]),out); - len++; - out+=nch; + // Update wi to point at the correct polyphase component + wi=(wi+dn)%up; + + // Insert i number of new samples in queue + i = inc; + if(wi<level) i++; + } } -L5: SAVE_QUE(x); } - // Save values that needs to be kept for next time pwi = wi; pxi = xi; @@ -219,8 +273,3 @@ ao_plugin_data.data=pl_resample.data; return 1; } - - - - -