Advertisement
Guest User

Untitled

a guest
Feb 11th, 2012
402
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.05 KB | None | 0 0
  1. const signed short iCoef[4][2] = {
  2.   {0, 0},
  3.   {240, 0},
  4.   {488, -240},
  5.   {460, -208}
  6. };
  7.  
  8. const int f[5][2] = {   {    0,  0  },
  9.                         {   60,  0  },
  10.                         {  115, -52 },
  11.                         {   98, -55 },
  12.                         {  122, -60 } };
  13.  
  14. static double
  15. AdpcmMashS (int curc,       /* current channel */
  16.             int ch,     /* total channels */
  17.             signed short *v,        /* values to use as starting 2 */
  18.             signed short *vl,       /* if set, factor final two samples against these and add to error */
  19.             const signed short iCoef[2],    /* lin predictor coeffs */
  20.             signed short *ibuff,    /* ibuff[] is interleaved input samples */
  21.             int iopow,      /* input/output step, REQUIRE 16 <= *st <= 0x7fff */
  22.             unsigned char *obuff    /* output buffer[blockAlign], or NULL for no output  */
  23.             )
  24. {
  25.     signed short *ip, *itop;
  26.     unsigned char *op;
  27.     int ox = curc;      /*  */
  28.     int d, v0, v1, step;
  29.     double d2;          /* long long is okay also, speed abt the same */
  30.  
  31.     ip = ibuff + curc;      /* point ip to 1st input sample for this channel */
  32.     itop = ibuff + (ch << 4) + curc;
  33.     v0 = v[0];
  34.     v1 = v[1];
  35.     d2 = 0;
  36.  
  37.     step = 1 << iopow;
  38.  
  39.     op = obuff;         /* output pointer (or NULL) */
  40.     for (; ip < itop; ip += ch)
  41.     {
  42.         int vlin, d, dp, c;
  43.  
  44.         /* make linear prediction for next sample */
  45.         /*      vlin = (v0 * iCoef[0] + v1 * iCoef[1]) >> 8; */
  46.         vlin = (v0 * iCoef[0]) >> 9;
  47.         vlin += (v1 * iCoef[1]) >> 9;
  48.         vlin <<= 1;
  49.         d = *ip - vlin;     /* difference between linear prediction and current sample */
  50.         dp = d + (step << 3) + (step >> 1);
  51.         c = 0;
  52.         if (dp > 0)
  53.         {
  54.             c = dp / step;
  55.             if (c > 15)
  56.                 c = 15;
  57.         }
  58.         c -= 8;
  59.         dp = c * step;      /* quantized estimate of samp - vlin */
  60.         c &= 0x0f;      /* mask to 4 bits */
  61.  
  62.         v1 = v0;            /* shift history */
  63.         v0 = vlin + dp;
  64.         if (v0 < -0x10000) v0 = -0x10000;
  65.         else if (v0 > 0xffff) v0 = 0xffff;
  66.         v0 = (signed short) (v0 & ~1);
  67.  
  68.         d = *ip - v0;
  69.         d2 += d * d;        /* update square-error */
  70.  
  71.         if (op)
  72.         {           /* if we want output, put it in proper place */
  73.             /* FIXME: does c<<0 work properly? */
  74.             op[ox >> 1] |= (ox & 1) ? c : (c << 4);
  75.             ox += ch;
  76.         }
  77.     }
  78.     if (vl)
  79.     {
  80.         d = v0 - vl[0];
  81.         d2 += d * d;
  82.         d = v1 - vl[1];
  83.         d2 += d * d;
  84.         d2 /= 18.;
  85.     }
  86.     else
  87.         d2 /= 16.;          /* be sure it's non-negative */
  88.     if (op)
  89.     {
  90.         /* when generating real output, we want to return these */
  91.         v[0] = v0;
  92.         v[1] = v1;
  93.     }
  94.     return sqrt (d2);
  95. }
  96.  
  97. void
  98. AdpcmBlockMashI (int ch,    /* number of channels */
  99.                  signed short *ip,  /* ip[] is input samples */
  100.                  unsigned char *obuff,  /* output buffer */
  101.                  signed short *v,   /* input/output last samples */
  102.                  signed short *vl)
  103. {
  104.     int s, smin;
  105.     int k, kmin;
  106.     int c;
  107.     double dmin;
  108.  
  109.     for (s = ch; s < ch * 9; s++)
  110.         obuff[s] = 0;
  111.  
  112.     for (c = 0; c < ch; c++)
  113.     {
  114.         dmin = 0.;
  115.         kmin = 0;
  116.         smin = 0;
  117.         for (s = 0; s < 13; s++)
  118.         {
  119.             for (k = 0; k < 4; k++)
  120.             {
  121.                 double d;
  122.                 d =
  123.                     AdpcmMashS (c, ch, &v[c << 1], vl ? &vl[c << 1] : 0, iCoef[k],
  124.                     ip, s, NULL);
  125.  
  126.                 if ((!s && !k) || d < dmin)
  127.                 {
  128.                     kmin = k;
  129.                     dmin = d;
  130.                     smin = s;
  131.                 }
  132.             }
  133.         }
  134.         obuff[c] = (smin << 4) | (kmin << 2);
  135.  
  136.         AdpcmMashS (c, ch, &v[c << 1], 0, iCoef[kmin], ip, smin, obuff + ch);
  137.     }
  138. }
  139.  
  140. static double
  141. AdpcmMashPS (int curc,      /* current channel */
  142.             int ch,     /* total channels */
  143.             signed short *v,        /* values to use as starting 2 */
  144.             signed short *vl,       /* if set, factor final two samples against these and add to error */
  145.             const signed int iCoef[2],  /* lin predictor coeffs */
  146.             signed short *ibuff,    /* ibuff[] is interleaved input samples */
  147.             int iopow,      /* input/output step, REQUIRE 16 <= *st <= 0x7fff */
  148.             unsigned char *obuff    /* output buffer[blockAlign], or NULL for no output  */
  149.             )
  150. {
  151.     signed short *ip, *itop;
  152.     unsigned char *op;
  153.     int ox = curc;      /*  */
  154.     int d, v0, v1, step;
  155.     double d2;          /* long long is okay also, speed abt the same */
  156.  
  157.     ip = ibuff + curc;      /* point ip to 1st input sample for this channel */
  158.     itop = ibuff + (ch * 28) + curc;
  159.     v0 = v[0];
  160.     v1 = v[1];
  161.     d2 = 0;
  162.  
  163.     step = 1 << (12 - iopow);
  164.  
  165.     op = obuff;         /* output pointer (or NULL) */
  166.     for (; ip < itop; ip += ch)
  167.     {
  168.         int vlin, d, dp, c;
  169.  
  170.         /* make linear prediction for next sample */
  171.         vlin = (v0 * iCoef[0] + v1 * iCoef[1]) >> 6;
  172.         d = *ip - vlin;     /* difference between linear prediction and current sample */
  173.         dp = d + (step << 3) + (step >> 1);
  174.         c = 0;
  175.         if (dp > 0)
  176.         {
  177.             c = dp / step;
  178.             if (c > 15)
  179.                 c = 15;
  180.         }
  181.         c -= 8;
  182.         dp = c * step;      /* quantized estimate of samp - vlin */
  183.         c &= 0x0f;      /* mask to 4 bits */
  184.  
  185.         v1 = v0;            /* shift history */
  186.         v0 = vlin + dp;
  187.         if (v0 < -0x8000) v0 = -0x8000;
  188.         else if (v0 > 0x7fff) v0 = 0x7fff;
  189.  
  190.         d = *ip - v0;
  191.         d2 += d * d;        /* update square-error */
  192.  
  193.         if (op)
  194.         {           /* if we want output, put it in proper place */
  195.             /* FIXME: does c<<0 work properly? */
  196.             op[ox >> 1] |= (ox & 1) ? (c << 4) : c;
  197.             ox += ch;
  198.         }
  199.     }
  200.     if (vl)
  201.     {
  202.         d = v0 - vl[0];
  203.         d2 += d * d;
  204.         d = v1 - vl[1];
  205.         d2 += d * d;
  206.         d2 /= 30.;
  207.     }
  208.     else
  209.         d2 /= 28.;          /* be sure it's non-negative */
  210.     if (op)
  211.     {
  212.         /* when generating real output, we want to return these */
  213.         v[0] = v0;
  214.         v[1] = v1;
  215.     }
  216.     return sqrt (d2);
  217. }
  218.  
  219. void
  220. AdpcmBlockMashPI (int ch,   /* number of channels */
  221.                  signed short *ip,  /* ip[] is input samples */
  222.                  unsigned char *obuff,  /* output buffer */
  223.                  signed short *v,   /* input/output last samples */
  224.                  signed short *vl)
  225. {
  226.     int s, smin;
  227.     int k, kmin;
  228.     int c;
  229.     double dmin;
  230.  
  231.     for (s = 2; s < 16 * ch; s++)
  232.         obuff[s] = 0;
  233.  
  234.     for (c = 0; c < ch; c++)
  235.     {
  236.         dmin = 0.;
  237.         kmin = 0;
  238.         smin = 0;
  239.         for (s = 0; s < 13; s++)
  240.         {
  241.             for (k = 0; k < 5; k++)
  242.             {
  243.                 double d;
  244.                 d =
  245.                     AdpcmMashPS (c, ch, &v[c << 1], vl ? &vl[c << 1] : 0, f[k],
  246.                     ip, s, NULL);
  247.  
  248.                 if ((!s && !k) || d < dmin)
  249.                 {
  250.                     kmin = k;
  251.                     dmin = d;
  252.                     smin = s;
  253.                 }
  254.             }
  255.         }
  256.         obuff[c*2] = (kmin << 4) | smin;
  257.         obuff[(c*2)+1] = 0;
  258.  
  259.         AdpcmMashPS (c, ch, &v[c << 1], 0, f[kmin], ip, smin, obuff + ch*2);
  260.     }
  261. }
  262.  
  263. static double
  264. AdpcmMashXA (int unit,      /* current channel */
  265.             int ch,     /* total channels */
  266.             signed short *v,        /* values to use as starting 2 */
  267.             signed short *vl,       /* if set, factor final two samples against these and add to error */
  268.             const signed int iCoef[2],  /* lin predictor coeffs */
  269.             signed short *ibuff,    /* ibuff[] is interleaved input samples */
  270.             int iopow,      /* input/output step, REQUIRE 16 <= *st <= 0x7fff */
  271.             unsigned char *obuff    /* output buffer[blockAlign], or NULL for no output  */
  272.             )
  273. {
  274.     signed short *ip, *itop;
  275.     unsigned char *op;
  276.     int ox = unit;      /*  */
  277.     int d, v0, v1, step;
  278.     double d2;          /* long long is okay also, speed abt the same */
  279.  
  280.     int curc = (unit & (ch-1)) + ((unit >> (ch-1)) * 28 * ch);
  281.  
  282.     ip = ibuff + curc;      /* point ip to 1st input sample for this channel */
  283.     itop = ibuff + (ch * 28) + curc;
  284.     v0 = v[0];
  285.     v1 = v[1];
  286.     d2 = 0;
  287.  
  288.     step = 1 << (12 - iopow);
  289.  
  290.     op = obuff;         /* output pointer (or NULL) */
  291.     for (; ip < itop; ip += ch)
  292.     {
  293.         int vlin, d, dp, c;
  294.  
  295.         /* make linear prediction for next sample */
  296.         vlin = (v0 * iCoef[0] + v1 * iCoef[1]) >> 6;
  297.         d = *ip - vlin;     /* difference between linear prediction and current sample */
  298.         dp = d + (step << 3) + (step >> 1);
  299.         c = 0;
  300.         if (dp > 0)
  301.         {
  302.             c = dp / step;
  303.             if (c > 15)
  304.                 c = 15;
  305.         }
  306.         c -= 8;
  307.         dp = c * step;      /* quantized estimate of samp - vlin */
  308.         c &= 0x0f;      /* mask to 4 bits */
  309.  
  310.         v1 = v0;            /* shift history */
  311.         v0 = vlin + dp;
  312.         if (v0 < -0x8000) v0 = -0x8000;
  313.         else if (v0 > 0x7fff) v0 = 0x7fff;
  314.  
  315.         d = *ip - v0;
  316.         d2 += d * d;        /* update square-error */
  317.  
  318.         if (op)
  319.         {           /* if we want output, put it in proper place */
  320.             /* FIXME: does c<<0 work properly? */
  321.             op[ox >> 1] |= (ox & 1) ? (c << 4) : c;
  322.             ox += 8;
  323.         }
  324.     }
  325.     if (vl)
  326.     {
  327.         d = v0 - vl[0];
  328.         d2 += d * d;
  329.         d = v1 - vl[1];
  330.         d2 += d * d;
  331.         d2 /= 30.;
  332.     }
  333.     else
  334.         d2 /= 28.;          /* be sure it's non-negative */
  335.     if (op)
  336.     {
  337.         /* when generating real output, we want to return these */
  338.         v[0] = v0;
  339.         v[1] = v1;
  340.     }
  341.     return sqrt (d2);
  342. }
  343.  
  344. void
  345. AdpcmBlockMashXA4I (int ch, /* number of channels */
  346.                  signed short *ip,  /* ip[] is input samples */
  347.                  unsigned char *obuff,  /* output buffer */
  348.                  signed short *v,   /* input/output last samples */
  349.                  signed short *vl)
  350. {
  351.     int s, smin;
  352.     int k, kmin;
  353.     int unit, c;
  354.     double dmin;
  355.  
  356.     memset(obuff + 16, 0, 14 * 8);
  357.  
  358.     for (unit = 0; unit < 8; unit++)
  359.     {
  360.         c = unit & (ch-1);
  361.         dmin = 0.;
  362.         kmin = 0;
  363.         smin = 0;
  364.         for (s = 0; s < 13; s++)
  365.         {
  366.             for (k = 0; k < 4; k++)
  367.             {
  368.                 double d;
  369.                 d =
  370.                     AdpcmMashXA (unit, ch, &v[c << 1], vl ? &vl[c << 1] : 0, f[k],
  371.                     ip, s, NULL);
  372.  
  373.                 if ((!s && !k) || d < dmin)
  374.                 {
  375.                     kmin = k;
  376.                     dmin = d;
  377.                     smin = s;
  378.                 }
  379.             }
  380.         }
  381.         obuff[4 + unit] = smin | (kmin << 4);
  382.  
  383.         AdpcmMashXA (unit, ch, &v[c << 1], 0, f[kmin], ip, smin, obuff + 16);
  384.     }
  385.     *(int*)obuff = ((int*)obuff)[1];
  386.     ((int*)obuff)[3] = ((int*)obuff)[2];
  387. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement