📄 resamplesubs.c
字号:
/* 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"/* CAUTION: Assumes we call this for only one resample job per program run! *//* return: 0 - notDone *//* >0 - index of last sample */static intreadData(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 DEBUGstatic int pof = 0; /* positive overflow count */static int nof = 0; /* negative overflow count */#endifstatic 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 */}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[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"); 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -