home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / audioop.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  35.1 KB  |  1,341 lines

  1.  
  2. /* audioopmodule - Module to detect peak values in arrays */
  3.  
  4. #include "Python.h"
  5.  
  6. #if SIZEOF_INT == 4
  7. typedef int Py_Int32;
  8. typedef unsigned int Py_UInt32;
  9. #else
  10. #if SIZEOF_LONG == 4
  11. typedef long Py_Int32;
  12. typedef unsigned long Py_UInt32;
  13. #else
  14. #error "No 4-byte integral type"
  15. #endif
  16. #endif
  17.  
  18. #if defined(__CHAR_UNSIGNED__)
  19. #if defined(signed)
  20. /* This module currently does not work on systems where only unsigned
  21.    characters are available.  Take it out of Setup.  Sorry. */
  22. #endif
  23. #endif
  24.  
  25. /* Code shamelessly stolen from sox,
  26. ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
  27.  
  28. #define MINLIN -32768
  29. #define MAXLIN 32767
  30. #define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
  31.                         else if ( x > MAXLIN ) x = MAXLIN; \
  32.                       } while ( 0 )
  33.  
  34. static unsigned char st_linear_to_ulaw(int sample);
  35.  
  36. /*
  37. ** This macro converts from ulaw to 16 bit linear, faster.
  38. **
  39. ** Jef Poskanzer
  40. ** 23 October 1989
  41. **
  42. ** Input: 8 bit ulaw sample
  43. ** Output: signed 16 bit linear sample
  44. */
  45. #define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
  46.  
  47. static int ulaw_table[256] = {
  48.     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
  49.     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
  50.     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
  51.     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
  52.     -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
  53.     -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
  54.     -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
  55.     -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
  56.     -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
  57.     -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
  58.     -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
  59.     -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
  60.     -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
  61.     -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
  62.     -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
  63.     -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
  64.     32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
  65.     23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
  66.     15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
  67.     11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
  68.     7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
  69.     5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
  70.     3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
  71.     2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
  72.     1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
  73.     1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
  74.     876,    844,    812,    780,    748,    716,    684,    652,
  75.     620,    588,    556,    524,    492,    460,    428,    396,
  76.     372,    356,    340,    324,    308,    292,    276,    260,
  77.     244,    228,    212,    196,    180,    164,    148,    132,
  78.     120,    112,    104,     96,     88,     80,     72,     64,
  79.     56,     48,     40,     32,     24,     16,      8,      0 };
  80.  
  81. /* #define ZEROTRAP */   /* turn on the trap as per the MIL-STD */
  82. #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
  83. #define CLIP 32635
  84.  
  85. static unsigned char
  86. st_linear_to_ulaw(int sample)
  87. {
  88.     static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
  89.                    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  90.                    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  91.                    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  92.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  93.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  94.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  95.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  96.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  97.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  98.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  99.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  100.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  101.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  102.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  103.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
  104.     int sign, exponent, mantissa;
  105.     unsigned char ulawbyte;
  106.  
  107.     /* Get the sample into sign-magnitude. */
  108.     sign = (sample >> 8) & 0x80;        /* set aside the sign */
  109.     if ( sign != 0 ) sample = -sample;    /* get magnitude */
  110.     if ( sample > CLIP ) sample = CLIP;    /* clip the magnitude */
  111.  
  112.     /* Convert from 16 bit linear to ulaw. */
  113.     sample = sample + BIAS;
  114.     exponent = exp_lut[( sample >> 7 ) & 0xFF];
  115.     mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
  116.     ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
  117. #ifdef ZEROTRAP
  118.     if ( ulawbyte == 0 ) ulawbyte = 0x02;    /* optional CCITT trap */
  119. #endif
  120.  
  121.     return ulawbyte;
  122. }
  123. /* End of code taken from sox */
  124.  
  125. /* Intel ADPCM step variation table */
  126. static int indexTable[16] = {
  127.     -1, -1, -1, -1, 2, 4, 6, 8,
  128.     -1, -1, -1, -1, 2, 4, 6, 8,
  129. };
  130.  
  131. static int stepsizeTable[89] = {
  132.     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  133.     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  134.     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  135.     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  136.     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  137.     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  138.     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  139.     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  140.     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  141. };
  142.     
  143. #define CHARP(cp, i) ((signed char *)(cp+i))
  144. #define SHORTP(cp, i) ((short *)(cp+i))
  145. #define LONGP(cp, i) ((Py_Int32 *)(cp+i))
  146.  
  147.  
  148.  
  149. static PyObject *AudioopError;
  150.  
  151. static PyObject *
  152. audioop_getsample(PyObject *self, PyObject *args)
  153. {
  154.     signed char *cp;
  155.     int len, size, val = 0;
  156.     int i;
  157.  
  158.     if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
  159.         return 0;
  160.     if ( size != 1 && size != 2 && size != 4 ) {
  161.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  162.         return 0;
  163.     }
  164.     if ( i < 0 || i >= len/size ) {
  165.         PyErr_SetString(AudioopError, "Index out of range");
  166.         return 0;
  167.     }
  168.     if ( size == 1 )      val = (int)*CHARP(cp, i);
  169.     else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
  170.     else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
  171.     return PyInt_FromLong(val);
  172. }
  173.  
  174. static PyObject *
  175. audioop_max(PyObject *self, PyObject *args)
  176. {
  177.     signed char *cp;
  178.     int len, size, val = 0;
  179.     int i;
  180.     int max = 0;
  181.  
  182.     if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
  183.         return 0;
  184.     if ( size != 1 && size != 2 && size != 4 ) {
  185.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  186.         return 0;
  187.     }
  188.     for ( i=0; i<len; i+= size) {
  189.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  190.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  191.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  192.         if ( val < 0 ) val = (-val);
  193.         if ( val > max ) max = val;
  194.     }
  195.     return PyInt_FromLong(max);
  196. }
  197.  
  198. static PyObject *
  199. audioop_minmax(PyObject *self, PyObject *args)
  200. {
  201.     signed char *cp;
  202.     int len, size, val = 0;
  203.     int i;
  204.     int min = 0x7fffffff, max = -0x7fffffff;
  205.  
  206.     if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
  207.         return NULL;
  208.     if (size != 1 && size != 2 && size != 4) {
  209.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  210.         return NULL;
  211.     }
  212.     for (i = 0; i < len; i += size) {
  213.         if (size == 1) val = (int) *CHARP(cp, i);
  214.         else if (size == 2) val = (int) *SHORTP(cp, i);
  215.         else if (size == 4) val = (int) *LONGP(cp, i);
  216.         if (val > max) max = val;
  217.         if (val < min) min = val;
  218.     }
  219.     return Py_BuildValue("(ii)", min, max);
  220. }
  221.  
  222. static PyObject *
  223. audioop_avg(PyObject *self, PyObject *args)
  224. {
  225.     signed char *cp;
  226.     int len, size, val = 0;
  227.     int i;
  228.     double avg = 0.0;
  229.  
  230.     if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
  231.         return 0;
  232.     if ( size != 1 && size != 2 && size != 4 ) {
  233.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  234.         return 0;
  235.     }
  236.     for ( i=0; i<len; i+= size) {
  237.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  238.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  239.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  240.         avg += val;
  241.     }
  242.     if ( len == 0 )
  243.         val = 0;
  244.     else
  245.         val = (int)(avg / (double)(len/size));
  246.     return PyInt_FromLong(val);
  247. }
  248.  
  249. static PyObject *
  250. audioop_rms(PyObject *self, PyObject *args)
  251. {
  252.     signed char *cp;
  253.     int len, size, val = 0;
  254.     int i;
  255.     double sum_squares = 0.0;
  256.  
  257.     if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
  258.         return 0;
  259.     if ( size != 1 && size != 2 && size != 4 ) {
  260.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  261.         return 0;
  262.     }
  263.     for ( i=0; i<len; i+= size) {
  264.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  265.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  266.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  267.         sum_squares += (double)val*(double)val;
  268.     }
  269.     if ( len == 0 )
  270.         val = 0;
  271.     else
  272.         val = (int)sqrt(sum_squares / (double)(len/size));
  273.     return PyInt_FromLong(val);
  274. }
  275.  
  276. static double _sum2(short *a, short *b, int len)
  277. {
  278.     int i;
  279.     double sum = 0.0;
  280.  
  281.     for( i=0; i<len; i++) {
  282.         sum = sum + (double)a[i]*(double)b[i];
  283.     }
  284.     return sum;
  285. }
  286.  
  287. /*
  288. ** Findfit tries to locate a sample within another sample. Its main use
  289. ** is in echo-cancellation (to find the feedback of the output signal in
  290. ** the input signal).
  291. ** The method used is as follows:
  292. **
  293. ** let R be the reference signal (length n) and A the input signal (length N)
  294. ** with N > n, and let all sums be over i from 0 to n-1.
  295. **
  296. ** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
  297. ** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
  298. ** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
  299. **
  300. ** Next, we compute the relative distance between the original signal and
  301. ** the modified signal and minimize that over j:
  302. ** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 )  =>
  303. ** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
  304. **
  305. ** In the code variables correspond as follows:
  306. ** cp1        A
  307. ** cp2        R
  308. ** len1        N
  309. ** len2        n
  310. ** aj_m1    A[j-1]
  311. ** aj_lm1    A[j+n-1]
  312. ** sum_ri_2    sum(R[i]^2)
  313. ** sum_aij_2    sum(A[i+j]^2)
  314. ** sum_aij_ri    sum(A[i+j]R[i])
  315. **
  316. ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
  317. ** is completely recalculated each step.
  318. */
  319. static PyObject *
  320. audioop_findfit(PyObject *self, PyObject *args)
  321. {
  322.     short *cp1, *cp2;
  323.     int len1, len2;
  324.     int j, best_j;
  325.     double aj_m1, aj_lm1;
  326.     double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
  327.  
  328.     if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
  329.         return 0;
  330.     if ( len1 & 1 || len2 & 1 ) {
  331.         PyErr_SetString(AudioopError, "Strings should be even-sized");
  332.         return 0;
  333.     }
  334.     len1 >>= 1;
  335.     len2 >>= 1;
  336.     
  337.     if ( len1 < len2 ) {
  338.         PyErr_SetString(AudioopError, "First sample should be longer");
  339.         return 0;
  340.     }
  341.     sum_ri_2 = _sum2(cp2, cp2, len2);
  342.     sum_aij_2 = _sum2(cp1, cp1, len2);
  343.     sum_aij_ri = _sum2(cp1, cp2, len2);
  344.  
  345.     result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
  346.  
  347.     best_result = result;
  348.     best_j = 0;
  349.     j = 0;
  350.  
  351.     for ( j=1; j<=len1-len2; j++) {
  352.         aj_m1 = (double)cp1[j-1];
  353.         aj_lm1 = (double)cp1[j+len2-1];
  354.  
  355.         sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
  356.         sum_aij_ri = _sum2(cp1+j, cp2, len2);
  357.  
  358.         result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
  359.             / sum_aij_2;
  360.  
  361.         if ( result < best_result ) {
  362.             best_result = result;
  363.             best_j = j;
  364.         }
  365.     
  366.     }
  367.  
  368.     factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
  369.     
  370.     return Py_BuildValue("(if)", best_j, factor);
  371. }
  372.  
  373. /*
  374. ** findfactor finds a factor f so that the energy in A-fB is minimal.
  375. ** See the comment for findfit for details.
  376. */
  377. static PyObject *
  378. audioop_findfactor(PyObject *self, PyObject *args)
  379. {
  380.     short *cp1, *cp2;
  381.     int len1, len2;
  382.     double sum_ri_2, sum_aij_ri, result;
  383.  
  384.     if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
  385.         return 0;
  386.     if ( len1 & 1 || len2 & 1 ) {
  387.         PyErr_SetString(AudioopError, "Strings should be even-sized");
  388.         return 0;
  389.     }
  390.     if ( len1 != len2 ) {
  391.         PyErr_SetString(AudioopError, "Samples should be same size");
  392.         return 0;
  393.     }
  394.     len2 >>= 1;
  395.     sum_ri_2 = _sum2(cp2, cp2, len2);
  396.     sum_aij_ri = _sum2(cp1, cp2, len2);
  397.  
  398.     result = sum_aij_ri / sum_ri_2;
  399.  
  400.     return PyFloat_FromDouble(result);
  401. }
  402.  
  403. /*
  404. ** findmax returns the index of the n-sized segment of the input sample
  405. ** that contains the most energy.
  406. */
  407. static PyObject *
  408. audioop_findmax(PyObject *self, PyObject *args)
  409. {
  410.     short *cp1;
  411.     int len1, len2;
  412.     int j, best_j;
  413.     double aj_m1, aj_lm1;
  414.     double result, best_result;
  415.  
  416.     if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
  417.         return 0;
  418.     if ( len1 & 1 ) {
  419.         PyErr_SetString(AudioopError, "Strings should be even-sized");
  420.         return 0;
  421.     }
  422.     len1 >>= 1;
  423.     
  424.     if ( len1 < len2 ) {
  425.         PyErr_SetString(AudioopError, "Input sample should be longer");
  426.         return 0;
  427.     }
  428.  
  429.     result = _sum2(cp1, cp1, len2);
  430.  
  431.     best_result = result;
  432.     best_j = 0;
  433.     j = 0;
  434.  
  435.     for ( j=1; j<=len1-len2; j++) {
  436.         aj_m1 = (double)cp1[j-1];
  437.         aj_lm1 = (double)cp1[j+len2-1];
  438.  
  439.         result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
  440.  
  441.         if ( result > best_result ) {
  442.             best_result = result;
  443.             best_j = j;
  444.         }
  445.     
  446.     }
  447.  
  448.     return PyInt_FromLong(best_j);
  449. }
  450.  
  451. static PyObject *
  452. audioop_avgpp(PyObject *self, PyObject *args)
  453. {
  454.     signed char *cp;
  455.     int len, size, val = 0, prevval = 0, prevextremevalid = 0,
  456.         prevextreme = 0;
  457.     int i;
  458.     double avg = 0.0;
  459.     int diff, prevdiff, extremediff, nextreme = 0;
  460.  
  461.     if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
  462.         return 0;
  463.     if ( size != 1 && size != 2 && size != 4 ) {
  464.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  465.         return 0;
  466.     }
  467.     /* Compute first delta value ahead. Also automatically makes us
  468.     ** skip the first extreme value
  469.     */
  470.     if ( size == 1 )      prevval = (int)*CHARP(cp, 0);
  471.     else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
  472.     else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
  473.     if ( size == 1 )      val = (int)*CHARP(cp, size);
  474.     else if ( size == 2 ) val = (int)*SHORTP(cp, size);
  475.     else if ( size == 4 ) val = (int)*LONGP(cp, size);
  476.     prevdiff = val - prevval;
  477.     
  478.     for ( i=size; i<len; i+= size) {
  479.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  480.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  481.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  482.         diff = val - prevval;
  483.         if ( diff*prevdiff < 0 ) {
  484.             /* Derivative changed sign. Compute difference to last
  485.             ** extreme value and remember.
  486.             */
  487.             if ( prevextremevalid ) {
  488.                 extremediff = prevval - prevextreme;
  489.                 if ( extremediff < 0 )
  490.                     extremediff = -extremediff;
  491.                 avg += extremediff;
  492.                 nextreme++;
  493.             }
  494.             prevextremevalid = 1;
  495.             prevextreme = prevval;
  496.         }
  497.         prevval = val;
  498.         if ( diff != 0 )
  499.             prevdiff = diff;    
  500.     }
  501.     if ( nextreme == 0 )
  502.         val = 0;
  503.     else
  504.         val = (int)(avg / (double)nextreme);
  505.     return PyInt_FromLong(val);
  506. }
  507.  
  508. static PyObject *
  509. audioop_maxpp(PyObject *self, PyObject *args)
  510. {
  511.     signed char *cp;
  512.     int len, size, val = 0, prevval = 0, prevextremevalid = 0,
  513.         prevextreme = 0;
  514.     int i;
  515.     int max = 0;
  516.     int diff, prevdiff, extremediff;
  517.  
  518.     if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
  519.         return 0;
  520.     if ( size != 1 && size != 2 && size != 4 ) {
  521.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  522.         return 0;
  523.     }
  524.     /* Compute first delta value ahead. Also automatically makes us
  525.     ** skip the first extreme value
  526.     */
  527.     if ( size == 1 )      prevval = (int)*CHARP(cp, 0);
  528.     else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
  529.     else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
  530.     if ( size == 1 )      val = (int)*CHARP(cp, size);
  531.     else if ( size == 2 ) val = (int)*SHORTP(cp, size);
  532.     else if ( size == 4 ) val = (int)*LONGP(cp, size);
  533.     prevdiff = val - prevval;
  534.  
  535.     for ( i=size; i<len; i+= size) {
  536.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  537.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  538.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  539.         diff = val - prevval;
  540.         if ( diff*prevdiff < 0 ) {
  541.             /* Derivative changed sign. Compute difference to
  542.             ** last extreme value and remember.
  543.             */
  544.             if ( prevextremevalid ) {
  545.                 extremediff = prevval - prevextreme;
  546.                 if ( extremediff < 0 )
  547.                     extremediff = -extremediff;
  548.                 if ( extremediff > max )
  549.                     max = extremediff;
  550.             }
  551.             prevextremevalid = 1;
  552.             prevextreme = prevval;
  553.         }
  554.         prevval = val;
  555.         if ( diff != 0 )
  556.             prevdiff = diff;
  557.     }
  558.     return PyInt_FromLong(max);
  559. }
  560.  
  561. static PyObject *
  562. audioop_cross(PyObject *self, PyObject *args)
  563. {
  564.     signed char *cp;
  565.     int len, size, val = 0;
  566.     int i;
  567.     int prevval, ncross;
  568.  
  569.     if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
  570.         return 0;
  571.     if ( size != 1 && size != 2 && size != 4 ) {
  572.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  573.         return 0;
  574.     }
  575.     ncross = -1;
  576.     prevval = 17; /* Anything <> 0,1 */
  577.     for ( i=0; i<len; i+= size) {
  578.         if ( size == 1 )      val = ((int)*CHARP(cp, i)) >> 7;
  579.         else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
  580.         else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
  581.         val = val & 1;
  582.         if ( val != prevval ) ncross++;
  583.         prevval = val;
  584.     }
  585.     return PyInt_FromLong(ncross);
  586. }
  587.  
  588. static PyObject *
  589. audioop_mul(PyObject *self, PyObject *args)
  590. {
  591.     signed char *cp, *ncp;
  592.     int len, size, val = 0;
  593.     double factor, fval, maxval;
  594.     PyObject *rv;
  595.     int i;
  596.  
  597.     if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
  598.         return 0;
  599.     
  600.     if ( size == 1 ) maxval = (double) 0x7f;
  601.     else if ( size == 2 ) maxval = (double) 0x7fff;
  602.     else if ( size == 4 ) maxval = (double) 0x7fffffff;
  603.     else {
  604.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  605.         return 0;
  606.     }
  607.     
  608.     rv = PyString_FromStringAndSize(NULL, len);
  609.     if ( rv == 0 )
  610.         return 0;
  611.     ncp = (signed char *)PyString_AsString(rv);
  612.     
  613.     
  614.     for ( i=0; i < len; i += size ) {
  615.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  616.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  617.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  618.         fval = (double)val*factor;
  619.         if ( fval > maxval ) fval = maxval;
  620.         else if ( fval < -maxval ) fval = -maxval;
  621.         val = (int)fval;
  622.         if ( size == 1 )      *CHARP(ncp, i) = (signed char)val;
  623.         else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
  624.         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
  625.     }
  626.     return rv;
  627. }
  628.  
  629. static PyObject *
  630. audioop_tomono(PyObject *self, PyObject *args)
  631. {
  632.     signed char *cp, *ncp;
  633.     int len, size, val1 = 0, val2 = 0;
  634.     double fac1, fac2, fval, maxval;
  635.     PyObject *rv;
  636.     int i;
  637.  
  638.     if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
  639.         return 0;
  640.     
  641.     if ( size == 1 ) maxval = (double) 0x7f;
  642.     else if ( size == 2 ) maxval = (double) 0x7fff;
  643.     else if ( size == 4 ) maxval = (double) 0x7fffffff;
  644.     else {
  645.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  646.         return 0;
  647.     }
  648.     
  649.     rv = PyString_FromStringAndSize(NULL, len/2);
  650.     if ( rv == 0 )
  651.         return 0;
  652.     ncp = (signed char *)PyString_AsString(rv);
  653.     
  654.     
  655.     for ( i=0; i < len; i += size*2 ) {
  656.         if ( size == 1 )      val1 = (int)*CHARP(cp, i);
  657.         else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
  658.         else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
  659.         if ( size == 1 )      val2 = (int)*CHARP(cp, i+1);
  660.         else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
  661.         else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
  662.         fval = (double)val1*fac1 + (double)val2*fac2;
  663.         if ( fval > maxval ) fval = maxval;
  664.         else if ( fval < -maxval ) fval = -maxval;
  665.         val1 = (int)fval;
  666.         if ( size == 1 )      *CHARP(ncp, i/2) = (signed char)val1;
  667.         else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
  668.         else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
  669.     }
  670.     return rv;
  671. }
  672.  
  673. static PyObject *
  674. audioop_tostereo(PyObject *self, PyObject *args)
  675. {
  676.     signed char *cp, *ncp;
  677.     int len, size, val1, val2, val = 0;
  678.     double fac1, fac2, fval, maxval;
  679.     PyObject *rv;
  680.     int i;
  681.  
  682.     if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
  683.         return 0;
  684.     
  685.     if ( size == 1 ) maxval = (double) 0x7f;
  686.     else if ( size == 2 ) maxval = (double) 0x7fff;
  687.     else if ( size == 4 ) maxval = (double) 0x7fffffff;
  688.     else {
  689.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  690.         return 0;
  691.     }
  692.     
  693.     rv = PyString_FromStringAndSize(NULL, len*2);
  694.     if ( rv == 0 )
  695.         return 0;
  696.     ncp = (signed char *)PyString_AsString(rv);
  697.     
  698.     
  699.     for ( i=0; i < len; i += size ) {
  700.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  701.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  702.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  703.  
  704.         fval = (double)val*fac1;
  705.         if ( fval > maxval ) fval = maxval;
  706.         else if ( fval < -maxval ) fval = -maxval;
  707.         val1 = (int)fval;
  708.  
  709.         fval = (double)val*fac2;
  710.         if ( fval > maxval ) fval = maxval;
  711.         else if ( fval < -maxval ) fval = -maxval;
  712.         val2 = (int)fval;
  713.  
  714.         if ( size == 1 )      *CHARP(ncp, i*2) = (signed char)val1;
  715.         else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
  716.         else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
  717.  
  718.         if ( size == 1 )      *CHARP(ncp, i*2+1) = (signed char)val2;
  719.         else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
  720.         else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
  721.     }
  722.     return rv;
  723. }
  724.  
  725. static PyObject *
  726. audioop_add(PyObject *self, PyObject *args)
  727. {
  728.     signed char *cp1, *cp2, *ncp;
  729.     int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
  730.     PyObject *rv;
  731.     int i;
  732.  
  733.     if ( !PyArg_Parse(args, "(s#s#i)",
  734.               &cp1, &len1, &cp2, &len2, &size ) )
  735.         return 0;
  736.  
  737.     if ( len1 != len2 ) {
  738.         PyErr_SetString(AudioopError, "Lengths should be the same");
  739.         return 0;
  740.     }
  741.     
  742.     if ( size == 1 ) maxval = 0x7f;
  743.     else if ( size == 2 ) maxval = 0x7fff;
  744.     else if ( size == 4 ) maxval = 0x7fffffff;
  745.     else {
  746.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  747.         return 0;
  748.     }
  749.  
  750.     rv = PyString_FromStringAndSize(NULL, len1);
  751.     if ( rv == 0 )
  752.         return 0;
  753.     ncp = (signed char *)PyString_AsString(rv);
  754.  
  755.     for ( i=0; i < len1; i += size ) {
  756.         if ( size == 1 )      val1 = (int)*CHARP(cp1, i);
  757.         else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
  758.         else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
  759.     
  760.         if ( size == 1 )      val2 = (int)*CHARP(cp2, i);
  761.         else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
  762.         else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
  763.  
  764.         newval = val1 + val2;
  765.         /* truncate in case of overflow */
  766.         if (newval > maxval) newval = maxval;
  767.         else if (newval < -maxval) newval = -maxval;
  768.         else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
  769.             newval = val1 > 0 ? maxval : - maxval;
  770.  
  771.         if ( size == 1 )      *CHARP(ncp, i) = (signed char)newval;
  772.         else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
  773.         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
  774.     }
  775.     return rv;
  776. }
  777.  
  778. static PyObject *
  779. audioop_bias(PyObject *self, PyObject *args)
  780. {
  781.     signed char *cp, *ncp;
  782.     int len, size, val = 0;
  783.     PyObject *rv;
  784.     int i;
  785.     int bias;
  786.  
  787.     if ( !PyArg_Parse(args, "(s#ii)",
  788.               &cp, &len, &size , &bias) )
  789.         return 0;
  790.  
  791.     if ( size != 1 && size != 2 && size != 4) {
  792.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  793.         return 0;
  794.     }
  795.     
  796.     rv = PyString_FromStringAndSize(NULL, len);
  797.     if ( rv == 0 )
  798.         return 0;
  799.     ncp = (signed char *)PyString_AsString(rv);
  800.     
  801.     
  802.     for ( i=0; i < len; i += size ) {
  803.         if ( size == 1 )      val = (int)*CHARP(cp, i);
  804.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  805.         else if ( size == 4 ) val = (int)*LONGP(cp, i);
  806.     
  807.         if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val+bias);
  808.         else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
  809.         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
  810.     }
  811.     return rv;
  812. }
  813.  
  814. static PyObject *
  815. audioop_reverse(PyObject *self, PyObject *args)
  816. {
  817.     signed char *cp;
  818.     unsigned char *ncp;
  819.     int len, size, val = 0;
  820.     PyObject *rv;
  821.     int i, j;
  822.  
  823.     if ( !PyArg_Parse(args, "(s#i)",
  824.               &cp, &len, &size) )
  825.         return 0;
  826.  
  827.     if ( size != 1 && size != 2 && size != 4 ) {
  828.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  829.         return 0;
  830.     }
  831.     
  832.     rv = PyString_FromStringAndSize(NULL, len);
  833.     if ( rv == 0 )
  834.         return 0;
  835.     ncp = (unsigned char *)PyString_AsString(rv);
  836.     
  837.     for ( i=0; i < len; i += size ) {
  838.         if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
  839.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  840.         else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
  841.  
  842.         j = len - i - size;
  843.     
  844.         if ( size == 1 )      *CHARP(ncp, j) = (signed char)(val >> 8);
  845.         else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
  846.         else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
  847.     }
  848.     return rv;
  849. }
  850.  
  851. static PyObject *
  852. audioop_lin2lin(PyObject *self, PyObject *args)
  853. {
  854.     signed char *cp;
  855.     unsigned char *ncp;
  856.     int len, size, size2, val = 0;
  857.     PyObject *rv;
  858.     int i, j;
  859.  
  860.     if ( !PyArg_Parse(args, "(s#ii)",
  861.               &cp, &len, &size, &size2) )
  862.         return 0;
  863.  
  864.     if ( (size != 1 && size != 2 && size != 4) ||
  865.          (size2 != 1 && size2 != 2 && size2 != 4)) {
  866.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  867.         return 0;
  868.     }
  869.     
  870.     rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
  871.     if ( rv == 0 )
  872.         return 0;
  873.     ncp = (unsigned char *)PyString_AsString(rv);
  874.     
  875.     for ( i=0, j=0; i < len; i += size, j += size2 ) {
  876.         if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
  877.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  878.         else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
  879.  
  880.         if ( size2 == 1 )  *CHARP(ncp, j) = (signed char)(val >> 8);
  881.         else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
  882.         else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
  883.     }
  884.     return rv;
  885. }
  886.  
  887. static int
  888. gcd(int a, int b)
  889. {
  890.     while (b > 0) {
  891.         int tmp = a % b;
  892.         a = b;
  893.         b = tmp;
  894.     }
  895.     return a;
  896. }
  897.  
  898. static PyObject *
  899. audioop_ratecv(PyObject *self, PyObject *args)
  900. {
  901.     char *cp, *ncp;
  902.     int len, size, nchannels, inrate, outrate, weightA, weightB;
  903.     int chan, d, *prev_i, *cur_i, cur_o;
  904.     PyObject *state, *samps, *str, *rv = NULL;
  905.  
  906.     weightA = 1;
  907.     weightB = 0;
  908.     if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
  909.                   &inrate, &outrate, &state, &weightA, &weightB))
  910.         return NULL;
  911.     if (size != 1 && size != 2 && size != 4) {
  912.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  913.         return NULL;
  914.     }
  915.     if (nchannels < 1) {
  916.         PyErr_SetString(AudioopError, "# of channels should be >= 1");
  917.         return NULL;
  918.     }
  919.     if (weightA < 1 || weightB < 0) {
  920.         PyErr_SetString(AudioopError,
  921.             "weightA should be >= 1, weightB should be >= 0");
  922.         return NULL;
  923.     }
  924.     if (len % (size * nchannels) != 0) {
  925.         PyErr_SetString(AudioopError, "not a whole number of frames");
  926.         return NULL;
  927.     }
  928.     if (inrate <= 0 || outrate <= 0) {
  929.         PyErr_SetString(AudioopError, "sampling rate not > 0");
  930.         return NULL;
  931.     }
  932.     /* divide inrate and outrate by their greatest common divisor */
  933.     d = gcd(inrate, outrate);
  934.     inrate /= d;
  935.     outrate /= d;
  936.  
  937.     prev_i = (int *) malloc(nchannels * sizeof(int));
  938.     cur_i = (int *) malloc(nchannels * sizeof(int));
  939.     len /= size * nchannels;    /* # of frames */
  940.     if (prev_i == NULL || cur_i == NULL) {
  941.         (void) PyErr_NoMemory();
  942.         goto exit;
  943.     }
  944.  
  945.     if (state == Py_None) {
  946.         d = -outrate;
  947.         for (chan = 0; chan < nchannels; chan++)
  948.             prev_i[chan] = cur_i[chan] = 0;
  949.     } else {
  950.         if (!PyArg_ParseTuple(state,
  951.                 "iO!;audioop.ratecv: illegal state argument",
  952.                 &d, &PyTuple_Type, &samps))
  953.             goto exit;
  954.         if (PyTuple_Size(samps) != nchannels) {
  955.             PyErr_SetString(AudioopError,
  956.                     "illegal state argument");
  957.             goto exit;
  958.         }
  959.         for (chan = 0; chan < nchannels; chan++) {
  960.             if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
  961.                           "ii:ratecv",&prev_i[chan],&cur_i[chan]))
  962.                 goto exit;
  963.         }
  964.     }
  965.     str = PyString_FromStringAndSize(
  966.           NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
  967.     if (str == NULL)
  968.         goto exit;
  969.     ncp = PyString_AsString(str);
  970.  
  971.     for (;;) {
  972.         while (d < 0) {
  973.             if (len == 0) {
  974.                 samps = PyTuple_New(nchannels);
  975.                 for (chan = 0; chan < nchannels; chan++)
  976.                     PyTuple_SetItem(samps, chan,
  977.                         Py_BuildValue("(ii)",
  978.                                   prev_i[chan],
  979.                                   cur_i[chan]));
  980.                 if (PyErr_Occurred())
  981.                     goto exit;
  982.                 len = ncp - PyString_AsString(str);
  983.                 if (len == 0) {
  984.                     /*don't want to resize to zero length*/
  985.                     rv = PyString_FromStringAndSize("", 0);
  986.                     Py_DECREF(str);
  987.                     str = rv;
  988.                 } else if (_PyString_Resize(&str, len) < 0)
  989.                     goto exit;
  990.                 rv = Py_BuildValue("(O(iO))", str, d, samps);
  991.                 Py_DECREF(samps);
  992.                 Py_DECREF(str);
  993.                 goto exit; /* return rv */
  994.             }
  995.             for (chan = 0; chan < nchannels; chan++) {
  996.                 prev_i[chan] = cur_i[chan];
  997.                 if (size == 1)
  998.                     cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
  999.                 else if (size == 2)
  1000.                     cur_i[chan] = (int)*SHORTP(cp, 0);
  1001.                 else if (size == 4)
  1002.                     cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
  1003.                 cp += size;
  1004.                 /* implements a simple digital filter */
  1005.                 cur_i[chan] =
  1006.                     (weightA * cur_i[chan] +
  1007.                      weightB * prev_i[chan]) /
  1008.                     (weightA + weightB);
  1009.             }
  1010.             len--;
  1011.             d += outrate;
  1012.         }
  1013.         while (d >= 0) {
  1014.             for (chan = 0; chan < nchannels; chan++) {
  1015.                 cur_o = (prev_i[chan] * d +
  1016.                      cur_i[chan] * (outrate - d)) /
  1017.                     outrate;
  1018.                 if (size == 1)
  1019.                     *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
  1020.                 else if (size == 2)
  1021.                     *SHORTP(ncp, 0) = (short)(cur_o);
  1022.                 else if (size == 4)
  1023.                     *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
  1024.                 ncp += size;
  1025.             }
  1026.             d -= inrate;
  1027.         }
  1028.     }
  1029.   exit:
  1030.     if (prev_i != NULL)
  1031.         free(prev_i);
  1032.     if (cur_i != NULL)
  1033.         free(cur_i);
  1034.     return rv;
  1035. }
  1036.  
  1037. static PyObject *
  1038. audioop_lin2ulaw(PyObject *self, PyObject *args)
  1039. {
  1040.     signed char *cp;
  1041.     unsigned char *ncp;
  1042.     int len, size, val = 0;
  1043.     PyObject *rv;
  1044.     int i;
  1045.  
  1046.     if ( !PyArg_Parse(args, "(s#i)",
  1047.               &cp, &len, &size) )
  1048.         return 0;
  1049.  
  1050.     if ( size != 1 && size != 2 && size != 4) {
  1051.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  1052.         return 0;
  1053.     }
  1054.     
  1055.     rv = PyString_FromStringAndSize(NULL, len/size);
  1056.     if ( rv == 0 )
  1057.         return 0;
  1058.     ncp = (unsigned char *)PyString_AsString(rv);
  1059.     
  1060.     for ( i=0; i < len; i += size ) {
  1061.         if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
  1062.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  1063.         else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
  1064.  
  1065.         *ncp++ = st_linear_to_ulaw(val);
  1066.     }
  1067.     return rv;
  1068. }
  1069.  
  1070. static PyObject *
  1071. audioop_ulaw2lin(PyObject *self, PyObject *args)
  1072. {
  1073.     unsigned char *cp;
  1074.     unsigned char cval;
  1075.     signed char *ncp;
  1076.     int len, size, val;
  1077.     PyObject *rv;
  1078.     int i;
  1079.  
  1080.     if ( !PyArg_Parse(args, "(s#i)",
  1081.               &cp, &len, &size) )
  1082.         return 0;
  1083.  
  1084.     if ( size != 1 && size != 2 && size != 4) {
  1085.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  1086.         return 0;
  1087.     }
  1088.     
  1089.     rv = PyString_FromStringAndSize(NULL, len*size);
  1090.     if ( rv == 0 )
  1091.         return 0;
  1092.     ncp = (signed char *)PyString_AsString(rv);
  1093.     
  1094.     for ( i=0; i < len*size; i += size ) {
  1095.         cval = *cp++;
  1096.         val = st_ulaw_to_linear(cval);
  1097.     
  1098.         if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val >> 8);
  1099.         else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
  1100.         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
  1101.     }
  1102.     return rv;
  1103. }
  1104.  
  1105. static PyObject *
  1106. audioop_lin2adpcm(PyObject *self, PyObject *args)
  1107. {
  1108.     signed char *cp;
  1109.     signed char *ncp;
  1110.     int len, size, val = 0, step, valpred, delta,
  1111.         index, sign, vpdiff, diff;
  1112.     PyObject *rv, *state, *str;
  1113.     int i, outputbuffer = 0, bufferstep;
  1114.  
  1115.     if ( !PyArg_Parse(args, "(s#iO)",
  1116.               &cp, &len, &size, &state) )
  1117.         return 0;
  1118.     
  1119.  
  1120.     if ( size != 1 && size != 2 && size != 4) {
  1121.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  1122.         return 0;
  1123.     }
  1124.     
  1125.     str = PyString_FromStringAndSize(NULL, len/(size*2));
  1126.     if ( str == 0 )
  1127.         return 0;
  1128.     ncp = (signed char *)PyString_AsString(str);
  1129.  
  1130.     /* Decode state, should have (value, step) */
  1131.     if ( state == Py_None ) {
  1132.         /* First time, it seems. Set defaults */
  1133.         valpred = 0;
  1134.         step = 7;
  1135.         index = 0;
  1136.     } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
  1137.         return 0;
  1138.  
  1139.     step = stepsizeTable[index];
  1140.     bufferstep = 1;
  1141.  
  1142.     for ( i=0; i < len; i += size ) {
  1143.         if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
  1144.         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
  1145.         else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
  1146.  
  1147.         /* Step 1 - compute difference with previous value */
  1148.         diff = val - valpred;
  1149.         sign = (diff < 0) ? 8 : 0;
  1150.         if ( sign ) diff = (-diff);
  1151.  
  1152.         /* Step 2 - Divide and clamp */
  1153.         /* Note:
  1154.         ** This code *approximately* computes:
  1155.         **    delta = diff*4/step;
  1156.         **    vpdiff = (delta+0.5)*step/4;
  1157.         ** but in shift step bits are dropped. The net result of this
  1158.         ** is that even if you have fast mul/div hardware you cannot
  1159.         ** put it to good use since the fixup would be too expensive.
  1160.         */
  1161.         delta = 0;
  1162.         vpdiff = (step >> 3);
  1163.     
  1164.         if ( diff >= step ) {
  1165.             delta = 4;
  1166.             diff -= step;
  1167.             vpdiff += step;
  1168.         }
  1169.         step >>= 1;
  1170.         if ( diff >= step  ) {
  1171.             delta |= 2;
  1172.             diff -= step;
  1173.             vpdiff += step;
  1174.         }
  1175.         step >>= 1;
  1176.         if ( diff >= step ) {
  1177.             delta |= 1;
  1178.             vpdiff += step;
  1179.         }
  1180.  
  1181.         /* Step 3 - Update previous value */
  1182.         if ( sign )
  1183.             valpred -= vpdiff;
  1184.         else
  1185.             valpred += vpdiff;
  1186.  
  1187.         /* Step 4 - Clamp previous value to 16 bits */
  1188.         if ( valpred > 32767 )
  1189.             valpred = 32767;
  1190.         else if ( valpred < -32768 )
  1191.             valpred = -32768;
  1192.  
  1193.         /* Step 5 - Assemble value, update index and step values */
  1194.         delta |= sign;
  1195.     
  1196.         index += indexTable[delta];
  1197.         if ( index < 0 ) index = 0;
  1198.         if ( index > 88 ) index = 88;
  1199.         step = stepsizeTable[index];
  1200.  
  1201.         /* Step 6 - Output value */
  1202.         if ( bufferstep ) {
  1203.             outputbuffer = (delta << 4) & 0xf0;
  1204.         } else {
  1205.             *ncp++ = (delta & 0x0f) | outputbuffer;
  1206.         }
  1207.         bufferstep = !bufferstep;
  1208.     }
  1209.     rv = Py_BuildValue("(O(ii))", str, valpred, index);
  1210.     Py_DECREF(str);
  1211.     return rv;
  1212. }
  1213.  
  1214. static PyObject *
  1215. audioop_adpcm2lin(PyObject *self, PyObject *args)
  1216. {
  1217.     signed char *cp;
  1218.     signed char *ncp;
  1219.     int len, size, valpred, step, delta, index, sign, vpdiff;
  1220.     PyObject *rv, *str, *state;
  1221.     int i, inputbuffer = 0, bufferstep;
  1222.  
  1223.     if ( !PyArg_Parse(args, "(s#iO)",
  1224.               &cp, &len, &size, &state) )
  1225.         return 0;
  1226.  
  1227.     if ( size != 1 && size != 2 && size != 4) {
  1228.         PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
  1229.         return 0;
  1230.     }
  1231.     
  1232.     /* Decode state, should have (value, step) */
  1233.     if ( state == Py_None ) {
  1234.         /* First time, it seems. Set defaults */
  1235.         valpred = 0;
  1236.         step = 7;
  1237.         index = 0;
  1238.     } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
  1239.         return 0;
  1240.     
  1241.     str = PyString_FromStringAndSize(NULL, len*size*2);
  1242.     if ( str == 0 )
  1243.         return 0;
  1244.     ncp = (signed char *)PyString_AsString(str);
  1245.  
  1246.     step = stepsizeTable[index];
  1247.     bufferstep = 0;
  1248.     
  1249.     for ( i=0; i < len*size*2; i += size ) {
  1250.         /* Step 1 - get the delta value and compute next index */
  1251.         if ( bufferstep ) {
  1252.             delta = inputbuffer & 0xf;
  1253.         } else {
  1254.             inputbuffer = *cp++;
  1255.             delta = (inputbuffer >> 4) & 0xf;
  1256.         }
  1257.  
  1258.         bufferstep = !bufferstep;
  1259.  
  1260.         /* Step 2 - Find new index value (for later) */
  1261.         index += indexTable[delta];
  1262.         if ( index < 0 ) index = 0;
  1263.         if ( index > 88 ) index = 88;
  1264.  
  1265.         /* Step 3 - Separate sign and magnitude */
  1266.         sign = delta & 8;
  1267.         delta = delta & 7;
  1268.  
  1269.         /* Step 4 - Compute difference and new predicted value */
  1270.         /*
  1271.         ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
  1272.         ** in adpcm_coder.
  1273.         */
  1274.         vpdiff = step >> 3;
  1275.         if ( delta & 4 ) vpdiff += step;
  1276.         if ( delta & 2 ) vpdiff += step>>1;
  1277.         if ( delta & 1 ) vpdiff += step>>2;
  1278.  
  1279.         if ( sign )
  1280.             valpred -= vpdiff;
  1281.         else
  1282.             valpred += vpdiff;
  1283.  
  1284.         /* Step 5 - clamp output value */
  1285.         if ( valpred > 32767 )
  1286.             valpred = 32767;
  1287.         else if ( valpred < -32768 )
  1288.             valpred = -32768;
  1289.  
  1290.         /* Step 6 - Update step value */
  1291.         step = stepsizeTable[index];
  1292.  
  1293.         /* Step 6 - Output value */
  1294.         if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
  1295.         else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
  1296.         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
  1297.     }
  1298.  
  1299.     rv = Py_BuildValue("(O(ii))", str, valpred, index);
  1300.     Py_DECREF(str);
  1301.     return rv;
  1302. }
  1303.  
  1304. static PyMethodDef audioop_methods[] = {
  1305.     { "max", audioop_max },
  1306.     { "minmax", audioop_minmax },
  1307.     { "avg", audioop_avg },
  1308.     { "maxpp", audioop_maxpp },
  1309.     { "avgpp", audioop_avgpp },
  1310.     { "rms", audioop_rms },
  1311.     { "findfit", audioop_findfit },
  1312.     { "findmax", audioop_findmax },
  1313.     { "findfactor", audioop_findfactor },
  1314.     { "cross", audioop_cross },
  1315.     { "mul", audioop_mul },
  1316.     { "add", audioop_add },
  1317.     { "bias", audioop_bias },
  1318.     { "ulaw2lin", audioop_ulaw2lin },
  1319.     { "lin2ulaw", audioop_lin2ulaw },
  1320.     { "lin2lin", audioop_lin2lin },
  1321.     { "adpcm2lin", audioop_adpcm2lin },
  1322.     { "lin2adpcm", audioop_lin2adpcm },
  1323.     { "tomono", audioop_tomono },
  1324.     { "tostereo", audioop_tostereo },
  1325.     { "getsample", audioop_getsample },
  1326.     { "reverse", audioop_reverse },
  1327.     { "ratecv", audioop_ratecv, 1 },
  1328.     { 0,          0 }
  1329. };
  1330.  
  1331. DL_EXPORT(void)
  1332. initaudioop(void)
  1333. {
  1334.     PyObject *m, *d;
  1335.     m = Py_InitModule("audioop", audioop_methods);
  1336.     d = PyModule_GetDict(m);
  1337.     AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
  1338.     if (AudioopError != NULL)
  1339.          PyDict_SetItemString(d,"error",AudioopError);
  1340. }
  1341.