📄 hermite.c
字号:
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)
*/
int
RAGetDelayHermite(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
*/
int
RAResampleMonoHermite(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
*/
int
RAResampleStereoHermite(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 + -