📄 aflibconverter.cc
字号:
dt = 1.0/factor; /* Output sampling period */ dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */ dh = MIN(Npc, factor*Npc); /* Filter sampling period */ dhb = (unsigned int)(dh*(1<<Na) + 0.5); /* Fixed-point representation */ start_sample = (*Time)>>Np; Ystart = Y;// endTime = *Time + (1<<Np)*(int)Nx; /* * TODO * DAS: not sure why this was changed from *Time < endTime * update: *Time < endTime causes seg fault. Also adds a clicking sound. */ while (Y - Ystart != Nout)// while (*Time < endTime) { Xp = &X[*Time>>Np]; /* Ptr to current input sample */ v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask), -1, dhb); /* Perform left-wing inner product */ v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, (short)((((*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 */ } end_sample = (*Time)>>Np; Nx = end_sample - start_sample; return (Y - Ystart); /* Return the number of output samples */}intaflibConverter::resampleFast( /* number of output samples returned */ int& inCount, /* number of input samples to convert */ int outCount, /* number of output samples to compute */ short inArray[], /* input data */ short outArray[]) /* output data */{ unsigned int Time2; /* Current time/pos in input sample */#if 0 unsigned short Ncreep;#endif unsigned short Xp, Xoff, Xread; int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor); unsigned short Nout = 0, Nx, orig_Nx; unsigned short maxOutput; int total_inCount = 0; int c, i, Ycount, last; bool first_pass = TRUE; 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 */ if (_initial == TRUE) _Time = (Xoff<<Np); /* Current-time pointer for converter */ do { if (!last) /* If haven't read last sample yet */ { last = readData(inCount, inArray, _X, IBUFFSIZE, (int)Xread,first_pass); first_pass = FALSE; if (last && (last-Xoff<Nx)) { /* If last sample has been read... */ Nx = last-Xoff; /* ...calc last sample affected by filter */ if (Nx <= 0) break; } } if ((outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) ) maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor); else maxOutput = outCount-Ycount; for (c = 0; c < _nChans; c++) { orig_Nx = Nx; Time2 = _Time; /* Resample stuff in input buffer */ Nout=SrcLinear(_X[c],_Y[c],_factor,&Time2,orig_Nx,maxOutput); } Nx = orig_Nx; _Time = Time2; _Time -= (Nx<<Np); /* Move converter Nx samples back in time */ Xp += Nx; /* Advance by number of samples processed */#if 0 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 */ }#endif for (c = 0; c < _nChans; c++) { for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */ _X[c][i] = _X[c][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 = IBUFFSIZE - Nx; /* 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"); for (c = 0; c < _nChans; c++) for (i = 0; i < Nout; i++) outArray[c * outCount + i + Ycount - Nout] = _Y[c][i]; total_inCount += Nx; } while (Ycount < outCount); /* Continue until done */ inCount = total_inCount; return(Ycount); /* Return # of samples in output file */}intaflibConverter::resampleWithFilter( /* number of output samples returned */ int& inCount, /* number of input samples to convert */ int outCount, /* number of output samples to compute */ short inArray[], /* input data */ short outArray[], /* output data */ short Imp[], short ImpD[], unsigned short LpScl, unsigned short Nmult, unsigned short Nwing){ unsigned int Time2; /* Current time/pos in input sample */#if 0 unsigned short Ncreep;#endif unsigned short Xp, Xoff, Xread; int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor); unsigned short Nout = 0, Nx, orig_Nx; unsigned short maxOutput; int total_inCount = 0; int c, i, Ycount, last; bool first_pass = TRUE; /* Account for increased filter gain when using factors less than 1 */ if (_factor < 1) LpScl = (unsigned short)(LpScl*_factor + 0.5); /* Calc reach of LP filter wing & give some creeping room */ Xoff = (unsigned short)(((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 */ if (_initial == TRUE) _Time = (Xoff<<Np); /* Current-time pointer for converter */ do { if (!last) /* If haven't read last sample yet */ { last = readData(inCount, inArray, _X, IBUFFSIZE, (int)Xread,first_pass); first_pass = FALSE; if (last && (last-Xoff<Nx)) { /* If last sample has been read... */ Nx = last-Xoff; /* ...calc last sample affected by filter */ if (Nx <= 0) break; } } if ( (outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) ) maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor); else maxOutput = outCount-Ycount; for (c = 0; c < _nChans; c++) { orig_Nx = Nx; Time2 = _Time; /* Resample stuff in input buffer */ if (_factor >= 1) { /* SrcUp() is faster if we can use it */ Nout=SrcUp(_X[c],_Y[c],_factor, &Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt); } else { Nout=SrcUD(_X[c],_Y[c],_factor, &Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt); } } _Time = Time2; _Time -= (Nx<<Np); /* Move converter Nx samples back in time */ Xp += Nx; /* Advance by number of samples processed */#if 0 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 */ }#endif 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 */ } 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"); for (c = 0; c < _nChans; c++) { for (i = 0; i < Nout; i++) { outArray[c * outCount + i + Ycount - Nout] = _Y[c][i]; } } int act_incount = (int)Nx; for (c = 0; c < _nChans; c++) { for (i=0; i<IBUFFSIZE-act_incount+Xoff; i++) { /* Copy part of input signal */ _X[c][i] = _X[c][i+act_incount]; /* that must be re-used */ } } Xread = IBUFFSIZE - Nx; /* Pos in input buff to read new data into */ Xp = Xoff; total_inCount += Nx; } while (Ycount < outCount); /* Continue until done */ inCount = total_inCount; return(Ycount); /* Return # of samples in output file */}intaflibConverter::FilterUp( short Imp[], short ImpD[], unsigned short Nwing, bool Interp, short *Xp, short Ph, short Inc){ short *Hp, *Hdp = NULL, *End; short a = 0; int v, t; v=0; Hp = &Imp[Ph>>Na]; End = &Imp[Nwing]; if (Interp) { Hdp = &ImpD[Ph>>Na]; a = Ph & Amask; } if (Inc == 1) /* If doing right wing... */ { /* ...drop extra coeff, so when Ph is */ End--; /* 0.5, we don't do too many mult's */ if (Ph == 0) /* If the phase is zero... */ { /* ...then we've already skipped the */ Hp += Npc; /* first sample, so we must also */ Hdp += Npc; /* skip ahead in Imp[] and ImpD[] */ } } if (Interp) { while (Hp < End) { t = *Hp; /* Get filter coeff */ t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */ Hdp += Npc; /* Filter coeff differences step */ t *= *Xp; /* Mult coeff by input sample */ if (t & (1<<(Nhxn-1))) /* Round, if needed */ t += (1<<(Nhxn-1)); t >>= Nhxn; /* Leave some guard bits, but come back some */ v += t; /* The filter output */ Hp += Npc; /* Filter coeff step */ Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ } } else { while (Hp < End) { t = *Hp; /* Get filter coeff */ t *= *Xp; /* Mult coeff by input sample */ if (t & (1<<(Nhxn-1))) /* Round, if needed */ t += (1<<(Nhxn-1)); t >>= Nhxn; /* Leave some guard bits, but come back some */ v += t; /* The filter output */ Hp += Npc; /* Filter coeff step */ Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ } } return(v);}intaflibConverter::FilterUD( short Imp[], short ImpD[], unsigned short Nwing, bool Interp, short *Xp, short Ph, short Inc, unsigned short dhb){ short a; short *Hp, *Hdp, *End; int v, t; unsigned int Ho; v=0; Ho = (Ph*(unsigned int)dhb)>>Np; End = &Imp[Nwing]; if (Inc == 1) /* If doing right wing... */ { /* ...drop extra coeff, so when Ph is */ End--; /* 0.5, we don't do too many mult's */ if (Ph == 0) /* If the phase is zero... */ Ho += dhb; /* ...then we've already skipped the */ } /* first sample, so we must also */ /* skip ahead in Imp[] and ImpD[] */ if (Interp) { while ((Hp = &Imp[Ho>>Na]) < End) { t = *Hp; /* Get IR sample */ Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table*/ a = Ho & Amask; /* a is logically between 0 and 1 */ t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */ t *= *Xp; /* Mult coeff by input sample */ if (t & 1<<(Nhxn-1)) /* Round, if needed */ t += 1<<(Nhxn-1); t >>= Nhxn; /* Leave some guard bits, but come back some */ v += t; /* The filter output */ Ho += dhb; /* IR step */ Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ } } else { while ((Hp = &Imp[Ho>>Na]) < End) { t = *Hp; /* Get IR sample */ t *= *Xp; /* Mult coeff by input sample */ if (t & 1<<(Nhxn-1)) /* Round, if needed */ t += 1<<(Nhxn-1); t >>= Nhxn; /* Leave some guard bits, but come back some */ v += t; /* The filter output */ Ho += dhb; /* IR step */ Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ } } return(v);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -