home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / py2s152.zip / Modules / audioop.c < prev    next >
C/C++ Source or Header  |  1999-06-27  |  39KB  |  1,415 lines

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