166 #include "rateconv.h" 
  180 #define MAXLENGTH   0x400        
  183 #define OUTBUFFSIZE     (2*MAXLENGTH)    
  184 #define INBUFFSIZE  (4*MAXLENGTH)    
  185 #define sqr(a)  ((a)*(a)) 
  188 #define M_PI 3.14159265358979 
  194 #ifdef  STEREO_DEFAULT 
  195 static  int g_monoflag = 0;
 
  197 static  int g_monoflag = -1;
 
  203 static double   g_ampli = 0.8;          
 
  227 static double sinc(
double x)
 
  229     return(fabs(x) < 1E-50 ? 1.0 : sin(fmod(x,2*M_PI))/x);
 
  236 static double interpol_func(
double t,
double fgk,
double fgg)
 
  238     return (2*fgk*sinc(M_PI*2*fgk*t)*exp(-M_PI*sqr(2*fgg*t)));
 
  245 static float coefficient(
int i,
int q,
int firlen,
double fgk,
double fgg,
 
  246              double fsi,
int up,
int down,
double amp)
 
  251     d = interpol_func((fmod(q*down/(
double)up,1.) + (firlen-1)/2. - i) / fsi,
 
  261 static void transfer_int(
float *s,
float *d,
int n)
 
  263     memmove(d,s,
sizeof(
float)*n);
 
  269 static void zerofill(
float *s,
int n)
 
  271     memset(s,0,n*(
sizeof(
float)));
 
  278 void fir_mono(
float *inp,
float *coep,
int firlen,
float *outp)
 
  280     float akku = 0, *endp;
 
  281     int n1 = (firlen / 8) * 8, n0 = firlen % 8;
 
  284     while (coep != endp) {
 
  285     akku += *inp++ * *coep++;
 
  286     akku += *inp++ * *coep++;
 
  287     akku += *inp++ * *coep++;
 
  288     akku += *inp++ * *coep++;
 
  289     akku += *inp++ * *coep++;
 
  290     akku += *inp++ * *coep++;
 
  291     akku += *inp++ * *coep++;
 
  292     akku += *inp++ * *coep++;
 
  296     while (coep != endp) {
 
  297     akku += *inp++ * *coep++;
 
  303 static void fir_stereo(
float *inp,
float *coep,
int firlen,
float *out1p,
float *out2p)
 
  305     float akku1 = 0, akku2 = 0, *endp;
 
  306     int n1 = (firlen / 8) * 8, n0 = firlen % 8;
 
  309     while (coep != endp) {
 
  310     akku1 += *inp++ * *coep;
 
  311     akku2 += *inp++ * *coep++;
 
  312     akku1 += *inp++ * *coep;
 
  313     akku2 += *inp++ * *coep++;
 
  314     akku1 += *inp++ * *coep;
 
  315     akku2 += *inp++ * *coep++;
 
  316     akku1 += *inp++ * *coep;
 
  317     akku2 += *inp++ * *coep++;
 
  318     akku1 += *inp++ * *coep;
 
  319     akku2 += *inp++ * *coep++;
 
  320     akku1 += *inp++ * *coep;
 
  321     akku2 += *inp++ * *coep++;
 
  322     akku1 += *inp++ * *coep;
 
  323     akku2 += *inp++ * *coep++;
 
  324     akku1 += *inp++ * *coep;
 
  325     akku2 += *inp++ * *coep++;
 
  329     while (coep != endp) {
 
  330     akku1 += *inp++ * *coep;
 
  331     akku2 += *inp++ * *coep++;
 
  348 static int inbaseidx = 0, inoffset = 0, cycctr = 0, outidx = 0;
 
  350 static int filtering_on_buffers
 
  351     (
float *inp,
int insize,
float *outp, 
int outsize, 
 
  352      float *coep,
int firlen,
int up,
int down,
int monoflag)
 
  357         inoffset = (cycctr * down)/up;
 
  358         if ((inbaseidx + inoffset + firlen) > insize) {
 
  359         inbaseidx -= insize - firlen + 1;
 
  362         fir_mono(inp + inoffset + inbaseidx,
 
  363              coep + cycctr * firlen,
 
  364              firlen, outp + outidx++);
 
  368         if (!(outidx %= outsize))
 
  380         inoffset = 2*((cycctr * down)/up);
 
  381         if ((inbaseidx + inoffset + 2*firlen) > insize) {
 
  382         inbaseidx -= insize - 2*firlen + 2;
 
  391         fir_stereo(inp + inoffset + inbaseidx,
 
  392                coep + cycctr * firlen, firlen,
 
  393                outp + outidx, outp + outidx+1);
 
  399         if (!(outidx %= outsize))
 
  408 static void make_coe(
void)
 
  412     for (i = 0; i < g_firlen; i++) {
 
  413         for (q = 0; q < g_up; q++) {
 
  414         g_coep[q * g_firlen + i] = coefficient(i, q, g_firlen,
 
  415             g_fgk, g_fgg, g_fsi, g_up, g_down, g_ampli);
 
  425 static WORD *inbuff = NULL;
 
  428 static WORD *outbuff = NULL;
 
  432 static int ioerr(
void)
 
  438 static int gcd(
int x, 
int y)
 
  442     if ((x < 1) || (y < 1))
 
  445     for (a=x,b=y; b != 0; )
 
  454 static int find_ratios(
int in_samp_freq,
int out_samp_freq,
int *up,
int *down)
 
  459     d = gcd(in_samp_freq,out_samp_freq);
 
  460     if (d == -1) 
return -1;
 
  461     *down = in_samp_freq / d;
 
  462     *up = out_samp_freq / d;
 
  464     if ((*up > 1024) || (*down > 1024))
 
  470 static int intimport(
float *buff, 
int n)
 
  475     if ((inpos+n) >= inmax)
 
  479     for (i=0;i < end; i++)
 
  480     buff[i] = inbuff[inpos++];
 
  485 static int intexport(
float *buff, 
int n)
 
  490     if ((outpos+n) >= outmax)
 
  491     end = outmax - inpos;
 
  494     for (i=0;i < end; i++)
 
  495     outbuff[outpos++] = (
short)buff[i];
 
  500 static int init_globs(WORD *in,
int insize, WORD **out, 
int *outsize,
 
  501                int in_samp_freq, 
int out_samp_freq)
 
  505     if (find_ratios(in_samp_freq,out_samp_freq,&g_up,&g_down) == -1)
 
  512     g_firlen = (int)(162 * (
float)g_up/(float)g_down);
 
  516     g_fgg = (float)g_up/(
float)g_down * 0.0116;
 
  517     g_fgk = (float)g_up/(
float)g_down * 0.461;
 
  518     g_firlen = (int)(162 * (
float)g_down/(float)g_up);
 
  520     if (g_firlen < 1 || g_firlen > MAXLENGTH)
 
  523     g_coep = 
new float[g_firlen * g_up];
 
  528     new_size = (int)(((
float)out_samp_freq/(float)in_samp_freq)*
 
  530     *out = 
new WORD[new_size];
 
  550 int rateconv(
short *in,
int isize, 
short **out, 
int *osize,
 
  551          int in_samp_freq, 
int out_samp_freq)
 
  553     int insize = 0, outsize = 0, skirtlen;
 
  555     if (init_globs(in,isize,out,osize,in_samp_freq,out_samp_freq) == -1)
 
  559     skirtlen = (g_firlen - 1) * (g_monoflag ? 1 : 2);
 
  560     zerofill(g_sin, skirtlen);
 
  562     insize = intimport(g_sin + skirtlen, INBUFFSIZE - skirtlen);
 
  563     if (insize < 0 || insize > INBUFFSIZE - skirtlen) 
 
  566         outsize = filtering_on_buffers(g_sin, skirtlen + insize,
 
  568                        g_coep, g_firlen, g_up, g_down,
 
  570         if (outsize != OUTBUFFSIZE) {
 
  571         transfer_int(g_sin + insize, g_sin, skirtlen);
 
  574         if (intexport(g_sout, outsize) != outsize) 
 
  577     } 
while (insize > 0);
 
  578     zerofill(g_sin + skirtlen, skirtlen);
 
  580     outsize = filtering_on_buffers(g_sin, skirtlen + skirtlen,
 
  582                        g_coep, g_firlen, g_up, g_down,
 
  584     if (intexport(g_sout, outsize) != outsize) 
 
  586     } 
while (outsize == OUTBUFFSIZE); 
 
  593     memmove(*out,*out+g_firlen/4,*osize*2);
 
  594     *osize -= g_firlen/4;