diff options
Diffstat (limited to 'third_party/resample/src/resamplesubs.c')
-rw-r--r-- | third_party/resample/src/resamplesubs.c | 520 |
1 files changed, 0 insertions, 520 deletions
diff --git a/third_party/resample/src/resamplesubs.c b/third_party/resample/src/resamplesubs.c deleted file mode 100644 index 920e56e6..00000000 --- a/third_party/resample/src/resamplesubs.c +++ /dev/null @@ -1,520 +0,0 @@ -/* resamplesubs.c - sampling rate conversion subroutines */ -// Altered version - -#include "resample.h" - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <string.h> - -#define IBUFFSIZE 4096 /* Input buffer size */ - -#include "smallfilter.h" -#include "largefilter.h" - -#include "filterkit.h" -#include "sndlibextra.h" - -#ifdef WITH_PJ -#include "resamplesubs.h" - -unsigned resample_LARGE_FILTER_NMULT = LARGE_FILTER_NMULT; -unsigned resample_LARGE_FILTER_NWING = LARGE_FILTER_NWING; -unsigned resample_LARGE_FILTER_SCALE = LARGE_FILTER_SCALE; -short* resample_LARGE_FILTER_IMP = LARGE_FILTER_IMP; -short* resample_LARGE_FILTER_IMPD = LARGE_FILTER_IMPD; - -unsigned resample_SMALL_FILTER_NMULT = SMALL_FILTER_NMULT; -unsigned resample_SMALL_FILTER_NWING = SMALL_FILTER_NWING; -unsigned resample_SMALL_FILTER_SCALE = SMALL_FILTER_SCALE; -short* resample_SMALL_FILTER_IMP = SMALL_FILTER_IMP; -short* resample_SMALL_FILTER_IMPD = SMALL_FILTER_IMPD; -#endif - - -/* CAUTION: Assumes we call this for only one resample job per program run! */ -/* return: 0 - notDone */ -/* >0 - index of last sample */ -static int -readData(int infd, /* input file descriptor */ - int inCount, /* _total_ number of frames in input file */ - HWORD *outPtr1, /* array receiving left chan samps */ - HWORD *outPtr2, /* array receiving right chan samps */ - int dataArraySize, /* size of these arrays */ - int nChans, - int Xoff) /* read into input array starting at this index */ -{ - int i, Nsamps, nret; - static unsigned int framecount; /* frames previously read */ - static mus_sample_t **ibufs = NULL; - - if (ibufs == NULL) { /* first time called, so allocate it */ - ibufs = sndlib_allocate_buffers(nChans, dataArraySize); - if (ibufs == NULL) { - fprintf(stderr, "readData: Can't allocate input buffers!\n"); - exit(1); - } - framecount = 0; /* init this too */ - } - - Nsamps = dataArraySize - Xoff; /* Calculate number of samples to get */ - outPtr1 += Xoff; /* Start at designated sample number */ - outPtr2 += Xoff; - - nret = mus_file_read(infd, 0, Nsamps - 1, nChans, ibufs); - if (nret < 0) { - fprintf(stderr, "readData: Can't read data!\n"); - exit(1); - } - - /* NB: sndlib pads ibufs with zeros if it reads past EOF. */ - if (nChans == 1) { - for (i = 0; i < Nsamps; i++) - *outPtr1++ = MUS_SAMPLE_TYPE_TO_HWORD(ibufs[0][i]); - } - else { - for (i = 0; i < Nsamps; i++) { - *outPtr1++ = MUS_SAMPLE_TYPE_TO_HWORD(ibufs[0][i]); - *outPtr2++ = MUS_SAMPLE_TYPE_TO_HWORD(ibufs[1][i]); - } - } - - framecount += Nsamps; - - if (framecount >= (unsigned)inCount) /* return index of last samp */ - return (((Nsamps - (framecount - inCount)) - 1) + Xoff); - else - return 0; -} - - -#ifdef DEBUG -static int pof = 0; /* positive overflow count */ -static int nof = 0; /* negative overflow count */ -#endif - -static INLINE HWORD WordToHword(WORD v, int scl) -{ - HWORD out; - WORD llsb = (1<<(scl-1)); - v += llsb; /* round */ - v >>= scl; - if (v>MAX_HWORD) { -#ifdef DEBUG - if (pof == 0) - fprintf(stderr, "*** resample: sound sample overflow\n"); - else if ((pof % 10000) == 0) - fprintf(stderr, "*** resample: another ten thousand overflows\n"); - pof++; -#endif - v = MAX_HWORD; - } else if (v < MIN_HWORD) { -#ifdef DEBUG - if (nof == 0) - fprintf(stderr, "*** resample: sound sample (-) overflow\n"); - else if ((nof % 1000) == 0) - fprintf(stderr, "*** resample: another thousand (-) overflows\n"); - nof++; -#endif - v = MIN_HWORD; - } - out = (HWORD) v; - return out; -} - -/* Sampling rate conversion using linear interpolation for maximum speed. - */ -STATIC int - SrcLinear(HWORD X[], HWORD Y[], double factor, UWORD *Time, UHWORD Nx) -{ - HWORD iconst; - HWORD *Xp, *Ystart; - WORD v,x1,x2; - - double dt; /* Step through input signal */ - UWORD dtb; /* Fixed-point version of Dt */ - UWORD endTime; /* When Time reaches EndTime, return to user */ - - dt = 1.0/factor; /* Output sampling period */ - dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */ - - Ystart = Y; - endTime = *Time + (1<<Np)*(WORD)Nx; - while (*Time < endTime) - { - iconst = (*Time) & Pmask; - Xp = &X[(*Time)>>Np]; /* Ptr to current input sample */ - x1 = *Xp++; - x2 = *Xp; - x1 *= ((1<<Np)-iconst); - x2 *= iconst; - v = x1 + x2; - *Y++ = WordToHword(v,Np); /* Deposit output */ - *Time += dtb; /* Move to next sample by time increment */ - } - return (Y - Ystart); /* Return number of output samples */ -} - -/* Sampling rate up-conversion only subroutine; - * Slightly faster than down-conversion; - */ -STATIC int SrcUp(HWORD X[], HWORD Y[], double factor, UWORD *Time, - UHWORD Nx, UHWORD Nwing, UHWORD LpScl, - HWORD Imp[], HWORD ImpD[], BOOL Interp) -{ - HWORD *Xp, *Ystart; - WORD v; - - double dt; /* Step through input signal */ - UWORD dtb; /* Fixed-point version of Dt */ - UWORD endTime; /* When Time reaches EndTime, return to user */ - - dt = 1.0/factor; /* Output sampling period */ - dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */ - - Ystart = Y; - endTime = *Time + (1<<Np)*(WORD)Nx; - while (*Time < endTime) - { - Xp = &X[*Time>>Np]; /* Ptr to current input sample */ - /* Perform left-wing inner product */ - v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask),-1); - /* Perform right-wing inner product */ - v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1, - /* previous (triggers warning): (HWORD)((-*Time)&Pmask),1); */ - (HWORD)((((*Time)^Pmask)+1)&Pmask),1); - v >>= Nhg; /* Make guard bits */ - v *= LpScl; /* Normalize for unity filter gain */ - *Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */ - *Time += dtb; /* Move to next sample by time increment */ - } - return (Y - Ystart); /* Return the number of output samples */ -} - - -/* Sampling rate conversion subroutine */ - -STATIC int SrcUD(HWORD X[], HWORD Y[], double factor, UWORD *Time, - UHWORD Nx, UHWORD Nwing, UHWORD LpScl, - HWORD Imp[], HWORD ImpD[], BOOL Interp) -{ - HWORD *Xp, *Ystart; - WORD v; - - double dh; /* Step through filter impulse response */ - double dt; /* Step through input signal */ - UWORD endTime; /* When Time reaches EndTime, return to user */ - UWORD dhb, dtb; /* Fixed-point versions of Dh,Dt */ - - dt = 1.0/factor; /* Output sampling period */ - dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */ - - dh = MIN(Npc, factor*Npc); /* Filter sampling period */ - dhb = dh*(1<<Na) + 0.5; /* Fixed-point representation */ - - Ystart = Y; - endTime = *Time + (1<<Np)*(WORD)Nx; - while (*Time < endTime) - { - Xp = &X[*Time>>Np]; /* Ptr to current input sample */ - v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask), - -1, dhb); /* Perform left-wing inner product */ - v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, - /* previous (triggers warning): (HWORD)((-*Time)&Pmask), */ - (HWORD)((((*Time)^Pmask)+1)&Pmask), - 1, dhb); /* Perform right-wing inner product */ - v >>= Nhg; /* Make guard bits */ - v *= LpScl; /* Normalize for unity filter gain */ - *Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */ - *Time += dtb; /* Move to next sample by time increment */ - } - return (Y - Ystart); /* Return the number of output samples */ -} - -#ifndef WITH_PJ -static int err_ret(char *s) -{ - fprintf(stderr,"resample: %s \n\n",s); /* Display error message */ - return -1; -} - -static int resampleFast( /* number of output samples returned */ - double factor, /* factor = Sndout/Sndin */ - int infd, /* input and output file descriptors */ - int outfd, - int inCount, /* number of input samples to convert */ - int outCount, /* number of output samples to compute */ - int nChans) /* number of sound channels (1 or 2) */ -{ - UWORD Time, Time2; /* Current time/pos in input sample */ - UHWORD Xp, Ncreep, Xoff, Xread; - int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor+2.0); - HWORD X1[IBUFFSIZE], Y1[2]; /* I/O buffers */ - HWORD X2[IBUFFSIZE], Y2[OBUFFSIZE]; /* I/O buffers */ - UHWORD Nout, Nx; - int i, Ycount, last; - - mus_sample_t **obufs = sndlib_allocate_buffers(nChans, OBUFFSIZE); - if (obufs == NULL) - return err_ret("Can't allocate output buffers"); - - Xoff = 10; - - Nx = IBUFFSIZE - 2*Xoff; /* # of samples to process each iteration */ - last = 0; /* Have not read last input sample yet */ - Ycount = 0; /* Current sample and length of output file */ - - Xp = Xoff; /* Current "now"-sample pointer for input */ - Xread = Xoff; /* Position in input array to read into */ - Time = (Xoff<<Np); /* Current-time pointer for converter */ - - for (i=0; i<Xoff; X1[i++]=0); /* Need Xoff zeros at begining of sample */ - for (i=0; i<Xoff; X2[i++]=0); /* Need Xoff zeros at begining of sample */ - - do { - if (!last) /* If haven't read last sample yet */ - { - last = readData(infd, inCount, X1, X2, IBUFFSIZE, - nChans, (int)Xread); - if (last && (last-Xoff<Nx)) { /* If last sample has been read... */ - Nx = last-Xoff; /* ...calc last sample affected by filter */ - if (Nx <= 0) - break; - } - } - - /* Resample stuff in input buffer */ - Time2 = Time; - Nout=SrcLinear(X1,Y1,factor,&Time,Nx); - if (nChans==2) - Nout=SrcLinear(X2,Y2,factor,&Time2,Nx); - - Time -= (Nx<<Np); /* Move converter Nx samples back in time */ - Xp += Nx; /* Advance by number of samples processed */ - Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */ - if (Ncreep) { - Time -= (Ncreep<<Np); /* Remove time accumulation */ - Xp += Ncreep; /* and add it to read pointer */ - } - for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */ - X1[i] = X1[i+Xp-Xoff]; /* that must be re-used */ - if (nChans==2) - X2[i] = X2[i+Xp-Xoff]; /* that must be re-used */ - } - if (last) { /* If near end of sample... */ - last -= Xp; /* ...keep track were it ends */ - if (!last) /* Lengthen input by 1 sample if... */ - last++; /* ...needed to keep flag TRUE */ - } - Xread = i; /* Pos in input buff to read new data into */ - Xp = Xoff; - - Ycount += Nout; - if (Ycount>outCount) { - Nout -= (Ycount-outCount); - Ycount = outCount; - } - - if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */ - return err_ret("Output array overflow"); - - if (nChans==1) { - for (i = 0; i < Nout; i++) - obufs[0][i] = HWORD_TO_MUS_SAMPLE_TYPE(Y1[i]); - } else { - for (i = 0; i < Nout; i++) { - obufs[0][i] = HWORD_TO_MUS_SAMPLE_TYPE(Y1[i]); - obufs[1][i] = HWORD_TO_MUS_SAMPLE_TYPE(Y2[i]); - } - } - /* NB: errors reported within sndlib */ - mus_file_write(outfd, 0, Nout - 1, nChans, obufs); - - printf("."); fflush(stdout); - - } while (Ycount<outCount); /* Continue until done */ - - return(Ycount); /* Return # of samples in output file */ -} - - -static int resampleWithFilter( /* number of output samples returned */ - double factor, /* factor = outSampleRate/inSampleRate */ - int infd, /* input and output file descriptors */ - int outfd, - int inCount, /* number of input samples to convert */ - int outCount, /* number of output samples to compute */ - int nChans, /* number of sound channels (1 or 2) */ - BOOL interpFilt, /* TRUE means interpolate filter coeffs */ - HWORD Imp[], HWORD ImpD[], - UHWORD LpScl, UHWORD Nmult, UHWORD Nwing) -{ - UWORD Time, Time2; /* Current time/pos in input sample */ - UHWORD Xp, Ncreep, Xoff, Xread; - int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor+2.0); - HWORD X1[IBUFFSIZE], Y1[OBUFFSIZE]; /* I/O buffers */ - HWORD X2[IBUFFSIZE], Y2[OBUFFSIZE]; /* I/O buffers */ - UHWORD Nout, Nx; - int i, Ycount, last; - - mus_sample_t **obufs = sndlib_allocate_buffers(nChans, OBUFFSIZE); - if (obufs == NULL) - return err_ret("Can't allocate output buffers"); - - /* Account for increased filter gain when using factors less than 1 */ - if (factor < 1) - LpScl = LpScl*factor + 0.5; - - /* Calc reach of LP filter wing & give some creeping room */ - Xoff = ((Nmult+1)/2.0) * MAX(1.0,1.0/factor) + 10; - - if (IBUFFSIZE < 2*Xoff) /* Check input buffer size */ - return err_ret("IBUFFSIZE (or factor) is too small"); - - Nx = IBUFFSIZE - 2*Xoff; /* # of samples to process each iteration */ - - last = 0; /* Have not read last input sample yet */ - Ycount = 0; /* Current sample and length of output file */ - Xp = Xoff; /* Current "now"-sample pointer for input */ - Xread = Xoff; /* Position in input array to read into */ - Time = (Xoff<<Np); /* Current-time pointer for converter */ - - for (i=0; i<Xoff; X1[i++]=0); /* Need Xoff zeros at begining of sample */ - for (i=0; i<Xoff; X2[i++]=0); /* Need Xoff zeros at begining of sample */ - - do { - if (!last) /* If haven't read last sample yet */ - { - last = readData(infd, inCount, X1, X2, IBUFFSIZE, - nChans, (int)Xread); - if (last && (last-Xoff<Nx)) { /* If last sample has been read... */ - Nx = last-Xoff; /* ...calc last sample affected by filter */ - if (Nx <= 0) - break; - } - } - /* Resample stuff in input buffer */ - Time2 = Time; - if (factor >= 1) { /* SrcUp() is faster if we can use it */ - Nout=SrcUp(X1,Y1,factor,&Time,Nx,Nwing,LpScl,Imp,ImpD,interpFilt); - if (nChans==2) - Nout=SrcUp(X2,Y2,factor,&Time2,Nx,Nwing,LpScl,Imp,ImpD, - interpFilt); - } - else { - Nout=SrcUD(X1,Y1,factor,&Time,Nx,Nwing,LpScl,Imp,ImpD,interpFilt); - if (nChans==2) - Nout=SrcUD(X2,Y2,factor,&Time2,Nx,Nwing,LpScl,Imp,ImpD, - interpFilt); - } - - Time -= (Nx<<Np); /* Move converter Nx samples back in time */ - Xp += Nx; /* Advance by number of samples processed */ - Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */ - if (Ncreep) { - Time -= (Ncreep<<Np); /* Remove time accumulation */ - Xp += Ncreep; /* and add it to read pointer */ - } - for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */ - X1[i] = X1[i+Xp-Xoff]; /* that must be re-used */ - if (nChans==2) - X2[i] = X2[i+Xp-Xoff]; /* that must be re-used */ - } - if (last) { /* If near end of sample... */ - last -= Xp; /* ...keep track were it ends */ - if (!last) /* Lengthen input by 1 sample if... */ - last++; /* ...needed to keep flag TRUE */ - } - Xread = i; /* Pos in input buff to read new data into */ - Xp = Xoff; - - Ycount += Nout; - if (Ycount>outCount) { - Nout -= (Ycount-outCount); - Ycount = outCount; - } - - if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */ - return err_ret("Output array overflow"); - - if (nChans==1) { - for (i = 0; i < Nout; i++) - obufs[0][i] = HWORD_TO_MUS_SAMPLE_TYPE(Y1[i]); - } else { - for (i = 0; i < Nout; i++) { - obufs[0][i] = HWORD_TO_MUS_SAMPLE_TYPE(Y1[i]); - obufs[1][i] = HWORD_TO_MUS_SAMPLE_TYPE(Y2[i]); - } - } - /* NB: errors reported within sndlib */ - mus_file_write(outfd, 0, Nout - 1, nChans, obufs); - - printf("."); fflush(stdout); - - } while (Ycount<outCount); /* Continue until done */ - - return(Ycount); /* Return # of samples in output file */ -} - - -int resample( /* number of output samples returned */ - double factor, /* factor = Sndout/Sndin */ - int infd, /* input and output file descriptors */ - int outfd, - int inCount, /* number of input samples to convert */ - int outCount, /* number of output samples to compute */ - int nChans, /* number of sound channels (1 or 2) */ - BOOL interpFilt, /* TRUE means interpolate filter coeffs */ - int fastMode, /* 0 = highest quality, slowest speed */ - BOOL largeFilter, /* TRUE means use 65-tap FIR filter */ - char *filterFile) /* NULL for internal filter, else filename */ -{ - UHWORD LpScl; /* Unity-gain scale factor */ - UHWORD Nwing; /* Filter table size */ - UHWORD Nmult; /* Filter length for up-conversions */ - HWORD *Imp=0; /* Filter coefficients */ - HWORD *ImpD=0; /* ImpD[n] = Imp[n+1]-Imp[n] */ - - if (fastMode) - return resampleFast(factor,infd,outfd,inCount,outCount,nChans); - -#ifdef DEBUG - /* Check for illegal constants */ - if (Np >= 16) - return err_ret("Error: Np>=16"); - if (Nb+Nhg+NLpScl >= 32) - return err_ret("Error: Nb+Nhg+NLpScl>=32"); - if (Nh+Nb > 32) - return err_ret("Error: Nh+Nb>32"); -#endif - - /* Set defaults */ - - if (filterFile != NULL && *filterFile != '\0') { - if (readFilter(filterFile, &Imp, &ImpD, &LpScl, &Nmult, &Nwing)) - return err_ret("could not find filter file, " - "or syntax error in contents of filter file"); - } else if (largeFilter) { - Nmult = LARGE_FILTER_NMULT; - Imp = LARGE_FILTER_IMP; /* Impulse response */ - ImpD = LARGE_FILTER_IMPD; /* Impulse response deltas */ - LpScl = LARGE_FILTER_SCALE; /* Unity-gain scale factor */ - Nwing = LARGE_FILTER_NWING; /* Filter table length */ - } else { - Nmult = SMALL_FILTER_NMULT; - Imp = SMALL_FILTER_IMP; /* Impulse response */ - ImpD = SMALL_FILTER_IMPD; /* Impulse response deltas */ - LpScl = SMALL_FILTER_SCALE; /* Unity-gain scale factor */ - Nwing = SMALL_FILTER_NWING; /* Filter table length */ - } -#if DEBUG - fprintf(stderr,"Attenuating resampler scale factor by 0.95 " - "to reduce probability of clipping\n"); -#endif - LpScl *= 0.95; - return resampleWithFilter(factor,infd,outfd,inCount,outCount,nChans, - interpFilt, Imp, ImpD, LpScl, Nmult, Nwing); -} -#endif /* WITH_PJ */ - |