📄 hermite.c
字号:
if (s->nchans == 2 && outsamps & 0x01) return -1; outframes = (UINT)(s->nchans == 2 ? outsamps >> 1 : outsamps); inframes = 0; /* fractional part */ f = s->step_f; for (i = 0; i < 4; i++) { inframes += outframes * (f & 0xff); /* add 24x8 partial product */ inframes = (inframes + 0xff) >> 8; /* shift, rounding up */ f >>= 8; } /* integer part */ inframes += outframes * s->step_i; return (int)(inframes * s->nchans); /* equivalent method using __int64 * * step64 = ((__int64)s->step_i << 32) + (__int64)s->step_f; * inframes = ( (__int64)outframes * step64); * inframes += (__int64)(0x00000000ffffffff); COMMENT: (add 1.0 - 2^-32 to 32.32 number) * return (int)((inframes >> 32) * s->nchans); */ /* equivalent method using double-precision floats * * double step; * outframes = (s->nchans == 2 ? outsamps >> 1 : outsamps); * step = s->step_i + (s->step_f / 4294967296.0); * inframes = (int) ceil((double)outframes * step); * return (inframes * s->nchans); */ /* equivalent method using an empty (null) resample * * outframes = (s->nchans == 2 ? outsamps >> 1 : outsamps); * for (i = f = currOut = 0; currOut < outframes; currOut++) { * f += s->step_f; * i += s->step_i + (f < s->step_f); COMMENT: add with carry * } * if (f) COMMENT: ceiling (if any fractional part, round up) * i++; * return (int)(i * s->nchans); */}/* Get number of frames of delay in the Hermite resampler * * Parameters * ---------- * void *inst instance pointer * * return value frames of delay * * Notes * ----- * - always two frames of delay (2 samples per channel) */intRAGetDelayHermite(void *inst){ return 2;}/* Cubic Hermite interpolation - one channel * * Parameters * ---------- * void *inbuf pointer to buffer of input data (16-bit PCM) * int insamps number of samples in inbuf * cvtFunctionType cvt conversion function pointer, ignored * short *outbuf output buffer, must be large enough to hold RAGetMaxOutputHermite(insamps) samples * void *inst instance pointer * * return value number of output samples generated and placed in outbuf, -1 if error * * Notes * ----- * - no restrictions on number of insamps * - inbuf MUST contain 16-bit PCM data, the cvt function is ignored */intRAResampleMonoHermite(void *inbuf, int insamps, tConverter *pCvt, short *outbuf, int outstride, void *inst){ STATE *s = (STATE *)inst; UINT f, step_i, step_f; int outsamps, i, acc0; int x0, x1, x2, x3, frac; short *inptr; /* restore state */ i = s->time_i; f = s->time_f; step_i = s->step_i; step_f = s->step_f; outsamps = 0; inptr = (short *)inbuf; if (s->nchans != 1 || outstride != 1) return -1; /* mono */ while (i < insamps) { if (i < 3) { x3 = (i < 3 ? s->hist[i+0] : inptr[i-3]) << 12; x2 = (i < 2 ? s->hist[i+1] : inptr[i-2]) << 12; x1 = (i < 1 ? s->hist[i+2] : inptr[i-1]) << 12; } else { x3 = inptr[i-3] << 12; x2 = inptr[i-2] << 12; x1 = inptr[i-1] << 12; } x0 = inptr[i] << 12; frac = f >> 1; /* 4-tap Hermite, using Farrow structure */ acc0 = (3 * (x2 - x1) + x0 - x3) >> 1; acc0 = MulShift31(acc0, frac); acc0 += 2 * x1 + x3 - ((5 * x2 + x0) >> 1); acc0 = MulShift31(acc0, frac); acc0 += (x1 - x3) >> 1; acc0 = MulShift31(acc0, frac); acc0 += x2; f += step_f; i += step_i + (f < step_f); /* add with carry */ acc0 = (acc0 + (1<<11)) >> 12; if (acc0 > +32767) acc0 = +32767; if (acc0 < -32768) acc0 = -32768; outbuf[outsamps++] = (short)acc0; } /* save delay samples for next time (hist[0] = oldest, hist[2] = newest) */ s->hist[0] = (insamps < 3 ? s->hist[insamps+0] : inptr[insamps-3]); s->hist[1] = (insamps < 2 ? s->hist[insamps+1] : inptr[insamps-2]); s->hist[2] = (insamps < 1 ? s->hist[insamps+2] : inptr[insamps-1]); /* save state */ s->time_f = f; s->time_i = i - insamps; return outsamps;}/* Cubic Hermite interpolation - two channels * * Parameters * ---------- * void *inbuf pointer to buffer of input data (16-bit PCM, interleaved LRLRLR...) * int insamps number of samples in inbuf * cvtFunctionType cvt conversion function pointer, ignored * short *outbuf output buffer, must be large enough to hold RAGetMaxOutputHermite(insamps) samples * void *inst instance pointer * * return value number of output samples generated and placed in outbuf, -1 if error * * Notes * ----- * - no restrictions on number of insamps * - inbuf MUST contain 16-bit PCM data, the cvt function is ignored * - insamps must be even, function will exit with error if not */intRAResampleStereoHermite(void *inbuf, int insamps, tConverter *pCvt, short *outbuf, int outstride, void *inst){ STATE *s = (STATE *)inst; UINT f, step_i, step_f; int outsamps, i, acc0, acc1, j; int x0, x1, x2, x3, frac; short *inptr; /* restore state */ i = s->time_i; f = s->time_f; step_i = s->step_i; step_f = s->step_f; outsamps = 0; inptr = (short *)inbuf; /* fail if odd number of input samples */ if (s->nchans != 2 || insamps & 0x01 || outstride != 2) return -1; /* stereo - assume insamps is even */ insamps /= 2; /* number of stereo frames - consume samples two at a time */ while (i < insamps) { frac = f >> 1; j = 2*i; /* left */ if (i < 3) { x3 = (i < 3 ? s->hist[j+0] : inptr[j-6]) << 12; x2 = (i < 2 ? s->hist[j+2] : inptr[j-4]) << 12; x1 = (i < 1 ? s->hist[j+4] : inptr[j-2]) << 12; } else { x3 = inptr[j-6] << 12; x2 = inptr[j-4] << 12; x1 = inptr[j-2] << 12; } x0 = inptr[j] << 12; /* 4-tap Hermite, using Farrow structure */ acc0 = (3 * (x2 - x1) + x0 - x3) >> 1; acc0 = MulShift31(acc0, frac); acc0 += 2 * x1 + x3 - ((5 * x2 + x0) >> 1); acc0 = MulShift31(acc0, frac); acc0 += (x1 - x3) >> 1; acc0 = MulShift31(acc0, frac); acc0 += x2; /* right */ if (i < 3) { x3 = (i < 3 ? s->hist[j+1] : inptr[j-5]) << 12; x2 = (i < 2 ? s->hist[j+3] : inptr[j-3]) << 12; x1 = (i < 1 ? s->hist[j+5] : inptr[j-1]) << 12; } else { x3 = inptr[j-5] << 12; x2 = inptr[j-3] << 12; x1 = inptr[j-1] << 12; } x0 = inptr[j+1] << 12; /* 4-tap Hermite, using Farrow structure */ acc1 = (3 * (x2 - x1) + x0 - x3) >> 1; acc1 = MulShift31(acc1, frac); acc1 += 2 * x1 + x3 - ((5 * x2 + x0) >> 1); acc1 = MulShift31(acc1, frac); acc1 += (x1 - x3) >> 1; acc1 = MulShift31(acc1, frac); acc1 += x2; f += step_f; i += step_i + (f < step_f); /* add with carry */ acc0 = (acc0 + (1<<11)) >> 12; if (acc0 > +32767) acc0 = +32767; if (acc0 < -32768) acc0 = -32768; outbuf[outsamps++] = (short)acc0; acc1 = (acc1 + (1<<11)) >> 12; if (acc1 > +32767) acc1 = +32767; if (acc1 < -32768) acc1 = -32768; outbuf[outsamps++] = (short)acc1; } /* save delay samples for next time (hist[0] = oldest left, hist[1] = oldest right, ...) */ s->hist[0] = (insamps < 3 ? s->hist[2*(insamps+0) + 0] : inptr[2*(insamps-3) + 0]); s->hist[2] = (insamps < 2 ? s->hist[2*(insamps+1) + 0] : inptr[2*(insamps-2) + 0]); s->hist[4] = (insamps < 1 ? s->hist[2*(insamps+2) + 0] : inptr[2*(insamps-1) + 0]); s->hist[1] = (insamps < 3 ? s->hist[2*(insamps+0) + 1] : inptr[2*(insamps-3) + 1]); s->hist[3] = (insamps < 2 ? s->hist[2*(insamps+1) + 1] : inptr[2*(insamps-2) + 1]); s->hist[5] = (insamps < 1 ? s->hist[2*(insamps+2) + 1] : inptr[2*(insamps-1) + 1]); /* save state */ s->time_f = f; s->time_i = i - insamps; return outsamps;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -