Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const signed short iCoef[4][2] = {
- {0, 0},
- {240, 0},
- {488, -240},
- {460, -208}
- };
- const int f[5][2] = { { 0, 0 },
- { 60, 0 },
- { 115, -52 },
- { 98, -55 },
- { 122, -60 } };
- static double
- AdpcmMashS (int curc, /* current channel */
- int ch, /* total channels */
- signed short *v, /* values to use as starting 2 */
- signed short *vl, /* if set, factor final two samples against these and add to error */
- const signed short iCoef[2], /* lin predictor coeffs */
- signed short *ibuff, /* ibuff[] is interleaved input samples */
- int iopow, /* input/output step, REQUIRE 16 <= *st <= 0x7fff */
- unsigned char *obuff /* output buffer[blockAlign], or NULL for no output */
- )
- {
- signed short *ip, *itop;
- unsigned char *op;
- int ox = curc; /* */
- int d, v0, v1, step;
- double d2; /* long long is okay also, speed abt the same */
- ip = ibuff + curc; /* point ip to 1st input sample for this channel */
- itop = ibuff + (ch << 4) + curc;
- v0 = v[0];
- v1 = v[1];
- d2 = 0;
- step = 1 << iopow;
- op = obuff; /* output pointer (or NULL) */
- for (; ip < itop; ip += ch)
- {
- int vlin, d, dp, c;
- /* make linear prediction for next sample */
- /* vlin = (v0 * iCoef[0] + v1 * iCoef[1]) >> 8; */
- vlin = (v0 * iCoef[0]) >> 9;
- vlin += (v1 * iCoef[1]) >> 9;
- vlin <<= 1;
- d = *ip - vlin; /* difference between linear prediction and current sample */
- dp = d + (step << 3) + (step >> 1);
- c = 0;
- if (dp > 0)
- {
- c = dp / step;
- if (c > 15)
- c = 15;
- }
- c -= 8;
- dp = c * step; /* quantized estimate of samp - vlin */
- c &= 0x0f; /* mask to 4 bits */
- v1 = v0; /* shift history */
- v0 = vlin + dp;
- if (v0 < -0x10000) v0 = -0x10000;
- else if (v0 > 0xffff) v0 = 0xffff;
- v0 = (signed short) (v0 & ~1);
- d = *ip - v0;
- d2 += d * d; /* update square-error */
- if (op)
- { /* if we want output, put it in proper place */
- /* FIXME: does c<<0 work properly? */
- op[ox >> 1] |= (ox & 1) ? c : (c << 4);
- ox += ch;
- }
- }
- if (vl)
- {
- d = v0 - vl[0];
- d2 += d * d;
- d = v1 - vl[1];
- d2 += d * d;
- d2 /= 18.;
- }
- else
- d2 /= 16.; /* be sure it's non-negative */
- if (op)
- {
- /* when generating real output, we want to return these */
- v[0] = v0;
- v[1] = v1;
- }
- return sqrt (d2);
- }
- void
- AdpcmBlockMashI (int ch, /* number of channels */
- signed short *ip, /* ip[] is input samples */
- unsigned char *obuff, /* output buffer */
- signed short *v, /* input/output last samples */
- signed short *vl)
- {
- int s, smin;
- int k, kmin;
- int c;
- double dmin;
- for (s = ch; s < ch * 9; s++)
- obuff[s] = 0;
- for (c = 0; c < ch; c++)
- {
- dmin = 0.;
- kmin = 0;
- smin = 0;
- for (s = 0; s < 13; s++)
- {
- for (k = 0; k < 4; k++)
- {
- double d;
- d =
- AdpcmMashS (c, ch, &v[c << 1], vl ? &vl[c << 1] : 0, iCoef[k],
- ip, s, NULL);
- if ((!s && !k) || d < dmin)
- {
- kmin = k;
- dmin = d;
- smin = s;
- }
- }
- }
- obuff[c] = (smin << 4) | (kmin << 2);
- AdpcmMashS (c, ch, &v[c << 1], 0, iCoef[kmin], ip, smin, obuff + ch);
- }
- }
- static double
- AdpcmMashPS (int curc, /* current channel */
- int ch, /* total channels */
- signed short *v, /* values to use as starting 2 */
- signed short *vl, /* if set, factor final two samples against these and add to error */
- const signed int iCoef[2], /* lin predictor coeffs */
- signed short *ibuff, /* ibuff[] is interleaved input samples */
- int iopow, /* input/output step, REQUIRE 16 <= *st <= 0x7fff */
- unsigned char *obuff /* output buffer[blockAlign], or NULL for no output */
- )
- {
- signed short *ip, *itop;
- unsigned char *op;
- int ox = curc; /* */
- int d, v0, v1, step;
- double d2; /* long long is okay also, speed abt the same */
- ip = ibuff + curc; /* point ip to 1st input sample for this channel */
- itop = ibuff + (ch * 28) + curc;
- v0 = v[0];
- v1 = v[1];
- d2 = 0;
- step = 1 << (12 - iopow);
- op = obuff; /* output pointer (or NULL) */
- for (; ip < itop; ip += ch)
- {
- int vlin, d, dp, c;
- /* make linear prediction for next sample */
- vlin = (v0 * iCoef[0] + v1 * iCoef[1]) >> 6;
- d = *ip - vlin; /* difference between linear prediction and current sample */
- dp = d + (step << 3) + (step >> 1);
- c = 0;
- if (dp > 0)
- {
- c = dp / step;
- if (c > 15)
- c = 15;
- }
- c -= 8;
- dp = c * step; /* quantized estimate of samp - vlin */
- c &= 0x0f; /* mask to 4 bits */
- v1 = v0; /* shift history */
- v0 = vlin + dp;
- if (v0 < -0x8000) v0 = -0x8000;
- else if (v0 > 0x7fff) v0 = 0x7fff;
- d = *ip - v0;
- d2 += d * d; /* update square-error */
- if (op)
- { /* if we want output, put it in proper place */
- /* FIXME: does c<<0 work properly? */
- op[ox >> 1] |= (ox & 1) ? (c << 4) : c;
- ox += ch;
- }
- }
- if (vl)
- {
- d = v0 - vl[0];
- d2 += d * d;
- d = v1 - vl[1];
- d2 += d * d;
- d2 /= 30.;
- }
- else
- d2 /= 28.; /* be sure it's non-negative */
- if (op)
- {
- /* when generating real output, we want to return these */
- v[0] = v0;
- v[1] = v1;
- }
- return sqrt (d2);
- }
- void
- AdpcmBlockMashPI (int ch, /* number of channels */
- signed short *ip, /* ip[] is input samples */
- unsigned char *obuff, /* output buffer */
- signed short *v, /* input/output last samples */
- signed short *vl)
- {
- int s, smin;
- int k, kmin;
- int c;
- double dmin;
- for (s = 2; s < 16 * ch; s++)
- obuff[s] = 0;
- for (c = 0; c < ch; c++)
- {
- dmin = 0.;
- kmin = 0;
- smin = 0;
- for (s = 0; s < 13; s++)
- {
- for (k = 0; k < 5; k++)
- {
- double d;
- d =
- AdpcmMashPS (c, ch, &v[c << 1], vl ? &vl[c << 1] : 0, f[k],
- ip, s, NULL);
- if ((!s && !k) || d < dmin)
- {
- kmin = k;
- dmin = d;
- smin = s;
- }
- }
- }
- obuff[c*2] = (kmin << 4) | smin;
- obuff[(c*2)+1] = 0;
- AdpcmMashPS (c, ch, &v[c << 1], 0, f[kmin], ip, smin, obuff + ch*2);
- }
- }
- static double
- AdpcmMashXA (int unit, /* current channel */
- int ch, /* total channels */
- signed short *v, /* values to use as starting 2 */
- signed short *vl, /* if set, factor final two samples against these and add to error */
- const signed int iCoef[2], /* lin predictor coeffs */
- signed short *ibuff, /* ibuff[] is interleaved input samples */
- int iopow, /* input/output step, REQUIRE 16 <= *st <= 0x7fff */
- unsigned char *obuff /* output buffer[blockAlign], or NULL for no output */
- )
- {
- signed short *ip, *itop;
- unsigned char *op;
- int ox = unit; /* */
- int d, v0, v1, step;
- double d2; /* long long is okay also, speed abt the same */
- int curc = (unit & (ch-1)) + ((unit >> (ch-1)) * 28 * ch);
- ip = ibuff + curc; /* point ip to 1st input sample for this channel */
- itop = ibuff + (ch * 28) + curc;
- v0 = v[0];
- v1 = v[1];
- d2 = 0;
- step = 1 << (12 - iopow);
- op = obuff; /* output pointer (or NULL) */
- for (; ip < itop; ip += ch)
- {
- int vlin, d, dp, c;
- /* make linear prediction for next sample */
- vlin = (v0 * iCoef[0] + v1 * iCoef[1]) >> 6;
- d = *ip - vlin; /* difference between linear prediction and current sample */
- dp = d + (step << 3) + (step >> 1);
- c = 0;
- if (dp > 0)
- {
- c = dp / step;
- if (c > 15)
- c = 15;
- }
- c -= 8;
- dp = c * step; /* quantized estimate of samp - vlin */
- c &= 0x0f; /* mask to 4 bits */
- v1 = v0; /* shift history */
- v0 = vlin + dp;
- if (v0 < -0x8000) v0 = -0x8000;
- else if (v0 > 0x7fff) v0 = 0x7fff;
- d = *ip - v0;
- d2 += d * d; /* update square-error */
- if (op)
- { /* if we want output, put it in proper place */
- /* FIXME: does c<<0 work properly? */
- op[ox >> 1] |= (ox & 1) ? (c << 4) : c;
- ox += 8;
- }
- }
- if (vl)
- {
- d = v0 - vl[0];
- d2 += d * d;
- d = v1 - vl[1];
- d2 += d * d;
- d2 /= 30.;
- }
- else
- d2 /= 28.; /* be sure it's non-negative */
- if (op)
- {
- /* when generating real output, we want to return these */
- v[0] = v0;
- v[1] = v1;
- }
- return sqrt (d2);
- }
- void
- AdpcmBlockMashXA4I (int ch, /* number of channels */
- signed short *ip, /* ip[] is input samples */
- unsigned char *obuff, /* output buffer */
- signed short *v, /* input/output last samples */
- signed short *vl)
- {
- int s, smin;
- int k, kmin;
- int unit, c;
- double dmin;
- memset(obuff + 16, 0, 14 * 8);
- for (unit = 0; unit < 8; unit++)
- {
- c = unit & (ch-1);
- dmin = 0.;
- kmin = 0;
- smin = 0;
- for (s = 0; s < 13; s++)
- {
- for (k = 0; k < 4; k++)
- {
- double d;
- d =
- AdpcmMashXA (unit, ch, &v[c << 1], vl ? &vl[c << 1] : 0, f[k],
- ip, s, NULL);
- if ((!s && !k) || d < dmin)
- {
- kmin = k;
- dmin = d;
- smin = s;
- }
- }
- }
- obuff[4 + unit] = smin | (kmin << 4);
- AdpcmMashXA (unit, ch, &v[c << 1], 0, f[kmin], ip, smin, obuff + 16);
- }
- *(int*)obuff = ((int*)obuff)[1];
- ((int*)obuff)[3] = ((int*)obuff)[2];
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement