📄 resamplesubs.c
字号:
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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -