[Python-checkins] r43153 - in python/trunk: Doc/lib/libaudioop.tex Lib/test/test_audioop.py Misc/NEWS Modules/audioop.c

anthony.baxter python-checkins at python.org
Mon Mar 20 06:22:00 CET 2006


Author: anthony.baxter
Date: Mon Mar 20 06:21:58 2006
New Revision: 43153

Modified:
   python/trunk/Doc/lib/libaudioop.tex
   python/trunk/Lib/test/test_audioop.py
   python/trunk/Misc/NEWS
   python/trunk/Modules/audioop.c
Log:
SF [ 1231053 ] audioop - alaw encoding/decoding added, code updated
 This patch adds a-LAW encoding to audioop and replaces the old
u-LAW encoding/decoding code with the current code from sox.

Possible issues: the code from sox uses int16_t.

Code by Lars Immisch



Modified: python/trunk/Doc/lib/libaudioop.tex
==============================================================================
--- python/trunk/Doc/lib/libaudioop.tex	(original)
+++ python/trunk/Doc/lib/libaudioop.tex	Mon Mar 20 06:21:58 2006
@@ -12,9 +12,10 @@
 modules.  All scalar items are integers, unless specified otherwise.
 
 % This para is mostly here to provide an excuse for the index entries...
-This module provides support for u-LAW and Intel/DVI ADPCM encodings.
+This module provides support for a-LAW, u-LAW and Intel/DVI ADPCM encodings.
 \index{Intel/DVI ADPCM}
 \index{ADPCM, Intel/DVI}
+\index{a-LAW}
 \index{u-LAW}
 
 A few of the more complicated operations only take 16-bit samples,
@@ -42,6 +43,13 @@
 has the width specified in \var{width}.
 \end{funcdesc}
 
+\begin{funcdesc}{alaw2lin}{fragment, width}
+Convert sound fragments in a-LAW encoding to linearly encoded sound
+fragments.  a-LAW encoding always uses 8 bits samples, so \var{width}
+refers only to the sample width of the output fragment here.
+\versionadded{2.5}
+\end{funcdesc}
+
 \begin{funcdesc}{avg}{fragment, width}
 Return the average over all samples in the fragment.
 \end{funcdesc}
@@ -98,10 +106,6 @@
 Return the value of sample \var{index} from the fragment.
 \end{funcdesc}
 
-\begin{funcdesc}{lin2lin}{fragment, width, newwidth}
-Convert samples between 1-, 2- and 4-byte formats.
-\end{funcdesc}
-
 \begin{funcdesc}{lin2adpcm}{fragment, width, state}
 Convert samples to 4 bit Intel/DVI ADPCM encoding.  ADPCM coding is an
 adaptive coding scheme, whereby each 4 bit number is the difference
@@ -117,6 +121,18 @@
 packed 2 4-bit values per byte.
 \end{funcdesc}
 
+\begin{funcdesc}{lin2alaw}{fragment, width}
+Convert samples in the audio fragment to a-LAW encoding and return
+this as a Python string.  a-LAW is an audio encoding format whereby
+you get a dynamic range of about 13 bits using only 8 bit samples.  It
+is used by the Sun audio hardware, among others.
+\versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{lin2lin}{fragment, width, newwidth}
+Convert samples between 1-, 2- and 4-byte formats.
+\end{funcdesc}
+
 \begin{funcdesc}{lin2ulaw}{fragment, width}
 Convert samples in the audio fragment to u-LAW encoding and return
 this as a Python string.  u-LAW is an audio encoding format whereby

Modified: python/trunk/Lib/test/test_audioop.py
==============================================================================
--- python/trunk/Lib/test/test_audioop.py	(original)
+++ python/trunk/Lib/test/test_audioop.py	Mon Mar 20 06:21:58 2006
@@ -136,12 +136,30 @@
         return 0
     return 1
 
+def testlin2alaw(data):
+    if verbose:
+        print 'lin2alaw'
+    if audioop.lin2alaw(data[0], 1) != '\xd5\xc5\xf5' or \
+              audioop.lin2alaw(data[1], 2) != '\xd5\xd5\xd5' or \
+              audioop.lin2alaw(data[2], 4) != '\xd5\xd5\xd5':
+        return 0
+    return 1
+
+def testalaw2lin(data):
+    if verbose:
+        print 'alaw2lin'
+    # Cursory
+    d = audioop.lin2alaw(data[0], 1)
+    if audioop.alaw2lin(d, 1) != data[0]:
+        return 0
+    return 1
+
 def testlin2ulaw(data):
     if verbose:
         print 'lin2ulaw'
-    if audioop.lin2ulaw(data[0], 1) != '\377\347\333' or \
-              audioop.lin2ulaw(data[1], 2) != '\377\377\377' or \
-              audioop.lin2ulaw(data[2], 4) != '\377\377\377':
+    if audioop.lin2ulaw(data[0], 1) != '\xff\xe7\xdb' or \
+              audioop.lin2ulaw(data[1], 2) != '\xff\xff\xff' or \
+              audioop.lin2ulaw(data[2], 4) != '\xff\xff\xff':
         return 0
     return 1
 

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Mon Mar 20 06:21:58 2006
@@ -295,6 +295,9 @@
 Extension Modules
 -----------------
 
+- Patch #1231053: The audioop module now supports encoding/decoding of alaw.
+  In addition, the existing ulaw code was updated.
+
 - RFE #567972: Socket objects' family, type and proto properties are
   now exposed via new get...() methods.
 

Modified: python/trunk/Modules/audioop.c
==============================================================================
--- python/trunk/Modules/audioop.c	(original)
+++ python/trunk/Modules/audioop.c	Mon Mar 20 06:21:58 2006
@@ -22,103 +22,247 @@
 #endif
 #endif
 
-/* Code shamelessly stolen from sox,
+/* Code shamelessly stolen from sox, 12.17.7, g711.c
 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
 
-#define MINLIN -32768
-#define MAXLIN 32767
-#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
-                        else if ( x > MAXLIN ) x = MAXLIN; \
-                      } while ( 0 )
+/* From g711.c:
+ *
+ * December 30, 1994:
+ * Functions linear2alaw, linear2ulaw have been updated to correctly
+ * convert unquantized 16 bit values.
+ * Tables for direct u- to A-law and A- to u-law conversions have been
+ * corrected.
+ * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
+ * bli at cpk.auc.dk
+ *
+ */
+#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+#define	SIGN_BIT	(0x80)		/* Sign bit for a A-law byte. */
+#define	QUANT_MASK	(0xf)		/* Quantization field mask. */
+#define	SEG_SHIFT	(4)		/* Left shift for segment number. */
+#define	SEG_MASK	(0x70)		/* Segment field mask. */
+
+static int16_t seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
+							  0x1FF, 0x3FF, 0x7FF, 0xFFF};
+static int16_t seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
+							  0x3FF, 0x7FF, 0xFFF, 0x1FFF};
+
+static int16_t search(int16_t val, int16_t *table, int size)
+{
+	int i;
 
-static unsigned char st_linear_to_ulaw(int sample);
+	for (i = 0; i < size; i++) {
+		if (val <= *table++)
+			return (i);
+	}
+	return (size);
+}
+#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
+#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
+
+int16_t _st_ulaw2linear16[256] = {
+    -32124,  -31100,  -30076,  -29052,  -28028,  -27004,  -25980,
+    -24956,  -23932,  -22908,  -21884,  -20860,  -19836,  -18812,
+    -17788,  -16764,  -15996,  -15484,  -14972,  -14460,  -13948,
+    -13436,  -12924,  -12412,  -11900,  -11388,  -10876,  -10364,
+     -9852,   -9340,   -8828,   -8316,   -7932,   -7676,   -7420,
+     -7164,   -6908,   -6652,   -6396,   -6140,   -5884,   -5628,
+     -5372,   -5116,   -4860,   -4604,   -4348,   -4092,   -3900,
+     -3772,   -3644,   -3516,   -3388,   -3260,   -3132,   -3004,
+     -2876,   -2748,   -2620,   -2492,   -2364,   -2236,   -2108,
+     -1980,   -1884,   -1820,   -1756,   -1692,   -1628,   -1564,
+     -1500,   -1436,   -1372,   -1308,   -1244,   -1180,   -1116,
+     -1052,    -988,    -924,    -876,    -844,    -812,    -780,
+      -748,    -716,    -684,    -652,    -620,    -588,    -556,
+      -524,    -492,    -460,    -428,    -396,    -372,    -356,
+      -340,    -324,    -308,    -292,    -276,    -260,    -244,
+      -228,    -212,    -196,    -180,    -164,    -148,    -132,
+      -120,    -112,    -104,     -96,     -88,     -80,     -72,
+       -64,     -56,     -48,     -40,     -32,     -24,     -16,
+        -8,       0,   32124,   31100,   30076,   29052,   28028,
+     27004,   25980,   24956,   23932,   22908,   21884,   20860,
+     19836,   18812,   17788,   16764,   15996,   15484,   14972,
+     14460,   13948,   13436,   12924,   12412,   11900,   11388,
+     10876,   10364,    9852,    9340,    8828,    8316,    7932,
+      7676,    7420,    7164,    6908,    6652,    6396,    6140,
+      5884,    5628,    5372,    5116,    4860,    4604,    4348,
+      4092,    3900,    3772,    3644,    3516,    3388,    3260,
+      3132,    3004,    2876,    2748,    2620,    2492,    2364,
+      2236,    2108,    1980,    1884,    1820,    1756,    1692,
+      1628,    1564,    1500,    1436,    1372,    1308,    1244,
+      1180,    1116,    1052,     988,     924,     876,     844,
+       812,     780,     748,     716,     684,     652,     620,
+       588,     556,     524,     492,     460,     428,     396,
+       372,     356,     340,     324,     308,     292,     276,
+       260,     244,     228,     212,     196,     180,     164,
+       148,     132,     120,     112,     104,      96,      88,
+        80,      72,      64,      56,      48,      40,      32,
+        24,      16,       8,       0
+};
 
 /*
-** This macro converts from ulaw to 16 bit linear, faster.
-**
-** Jef Poskanzer
-** 23 October 1989
-**
-** Input: 8 bit ulaw sample
-** Output: signed 16 bit linear sample
-*/
-#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
+ * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
+ * stored in a unsigned char.  This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 14-bits.
+ *
+ * In order to simplify the encoding process, the original linear magnitude
+ * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ * (33 - 8191). The result can be seen in the following encoding table:
+ *
+ *	Biased Linear Input Code	Compressed Code
+ *	------------------------	---------------
+ *	00000001wxyza			000wxyz
+ *	0000001wxyzab			001wxyz
+ *	000001wxyzabc			010wxyz
+ *	00001wxyzabcd			011wxyz
+ *	0001wxyzabcde			100wxyz
+ *	001wxyzabcdef			101wxyz
+ *	01wxyzabcdefg			110wxyz
+ *	1wxyzabcdefgh			111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz.  * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char st_14linear2ulaw(
+	int16_t		pcm_val)	/* 2's complement (14-bit range) */
+{
+	int16_t		mask;
+	int16_t		seg;
+	unsigned char	uval;
+
+	/* The original sox code does this in the calling function, not here */
+	pcm_val = pcm_val >> 2;
+
+	/* u-law inverts all bits */
+	/* Get the sign and the magnitude of the value. */
+	if (pcm_val < 0) {
+		pcm_val = -pcm_val;
+		mask = 0x7F;
+	} else {
+		mask = 0xFF;
+	}
+        if ( pcm_val > CLIP ) pcm_val = CLIP;		/* clip the magnitude */
+	pcm_val += (BIAS >> 2);
+
+	/* Convert the scaled magnitude to segment number. */
+	seg = search(pcm_val, seg_uend, 8);
+
+	/*
+	 * Combine the sign, segment, quantization bits;
+	 * and complement the code word.
+	 */
+	if (seg >= 8)		/* out of range, return maximum value. */
+		return (unsigned char) (0x7F ^ mask);
+	else {
+		uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
+		return (uval ^ mask);
+	}
 
-static int ulaw_table[256] = {
-	-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
-	-23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
-	-15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
-	-11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
-	-7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
-	-5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
-	-3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
-	-2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
-	-1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
-	-1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
-	-876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
-	-620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
-	-372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
-	-244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
-	-120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
-	-56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
-	32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
-	23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
-	15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
-	11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
-	7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
-	5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
-	3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
-	2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
-	1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
-	1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
-	876,    844,    812,    780,    748,    716,    684,    652,
-	620,    588,    556,    524,    492,    460,    428,    396,
-	372,    356,    340,    324,    308,    292,    276,    260,
-	244,    228,    212,    196,    180,    164,    148,    132,
-	120,    112,    104,     96,     88,     80,     72,     64,
-	56,     48,     40,     32,     24,     16,      8,      0 };
+}
 
-/* #define ZEROTRAP */   /* turn on the trap as per the MIL-STD */
-#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
-#define CLIP 32635
+int16_t _st_alaw2linear16[256] = {
+     -5504,   -5248,   -6016,   -5760,   -4480,   -4224,   -4992,
+     -4736,   -7552,   -7296,   -8064,   -7808,   -6528,   -6272,
+     -7040,   -6784,   -2752,   -2624,   -3008,   -2880,   -2240,
+     -2112,   -2496,   -2368,   -3776,   -3648,   -4032,   -3904,
+     -3264,   -3136,   -3520,   -3392,  -22016,  -20992,  -24064,
+    -23040,  -17920,  -16896,  -19968,  -18944,  -30208,  -29184,
+    -32256,  -31232,  -26112,  -25088,  -28160,  -27136,  -11008,
+    -10496,  -12032,  -11520,   -8960,   -8448,   -9984,   -9472,
+    -15104,  -14592,  -16128,  -15616,  -13056,  -12544,  -14080,
+    -13568,    -344,    -328,    -376,    -360,    -280,    -264,
+      -312,    -296,    -472,    -456,    -504,    -488,    -408,
+      -392,    -440,    -424,     -88,     -72,    -120,    -104,
+       -24,      -8,     -56,     -40,    -216,    -200,    -248,
+      -232,    -152,    -136,    -184,    -168,   -1376,   -1312,
+     -1504,   -1440,   -1120,   -1056,   -1248,   -1184,   -1888,
+     -1824,   -2016,   -1952,   -1632,   -1568,   -1760,   -1696,
+      -688,    -656,    -752,    -720,    -560,    -528,    -624,
+      -592,    -944,    -912,   -1008,    -976,    -816,    -784,
+      -880,    -848,    5504,    5248,    6016,    5760,    4480,
+      4224,    4992,    4736,    7552,    7296,    8064,    7808,
+      6528,    6272,    7040,    6784,    2752,    2624,    3008,
+      2880,    2240,    2112,    2496,    2368,    3776,    3648,
+      4032,    3904,    3264,    3136,    3520,    3392,   22016,
+     20992,   24064,   23040,   17920,   16896,   19968,   18944,
+     30208,   29184,   32256,   31232,   26112,   25088,   28160,
+     27136,   11008,   10496,   12032,   11520,    8960,    8448,
+      9984,    9472,   15104,   14592,   16128,   15616,   13056,
+     12544,   14080,   13568,     344,     328,     376,     360,
+       280,     264,     312,     296,     472,     456,     504,
+       488,     408,     392,     440,     424,      88,      72,
+       120,     104,      24,       8,      56,      40,     216,
+       200,     248,     232,     152,     136,     184,     168,
+      1376,    1312,    1504,    1440,    1120,    1056,    1248,
+      1184,    1888,    1824,    2016,    1952,    1632,    1568,
+      1760,    1696,     688,     656,     752,     720,     560,
+       528,     624,     592,     944,     912,    1008,     976,
+       816,     784,     880,     848
+};
 
-static unsigned char
-st_linear_to_ulaw(int sample)
-{
-	static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
-				   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-				   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-				   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
-	int sign, exponent, mantissa;
-	unsigned char ulawbyte;
-
-	/* Get the sample into sign-magnitude. */
-	sign = (sample >> 8) & 0x80;		/* set aside the sign */
-	if ( sign != 0 ) sample = -sample;	/* get magnitude */
-	if ( sample > CLIP ) sample = CLIP;	/* clip the magnitude */
-
-	/* Convert from 16 bit linear to ulaw. */
-	sample = sample + BIAS;
-	exponent = exp_lut[( sample >> 7 ) & 0xFF];
-	mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
-	ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
-#ifdef ZEROTRAP
-	if ( ulawbyte == 0 ) ulawbyte = 0x02;	/* optional CCITT trap */
-#endif
+/*
+ * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
+ * stored in a unsigned char.  This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 13-bits.
+ *
+ *		Linear Input Code	Compressed Code
+ *	------------------------	---------------
+ *	0000000wxyza			000wxyz
+ *	0000001wxyza			001wxyz
+ *	000001wxyzab			010wxyz
+ *	00001wxyzabc			011wxyz
+ *	0001wxyzabcd			100wxyz
+ *	001wxyzabcde			101wxyz
+ *	01wxyzabcdef			110wxyz
+ *	1wxyzabcdefg			111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char st_linear2alaw(
+	int16_t		pcm_val)	/* 2's complement (13-bit range) */
+{
+	int16_t		mask;
+	short		seg;
+	unsigned char	aval;
+
+	/* The original sox code does this in the calling function, not here */
+	pcm_val = pcm_val >> 3;
+
+	/* A-law using even bit inversion */
+	if (pcm_val >= 0) {
+		mask = 0xD5;		/* sign (7th) bit = 1 */
+	} else {
+		mask = 0x55;		/* sign bit = 0 */
+		pcm_val = -pcm_val - 1;
+	}
+
+	/* Convert the scaled magnitude to segment number. */
+	seg = search(pcm_val, seg_aend, 8);
 
-	return ulawbyte;
+	/* Combine the sign, segment, and quantization bits. */
+
+	if (seg >= 8)		/* out of range, return maximum value. */
+		return (unsigned char) (0x7F ^ mask);
+	else {
+		aval = (unsigned char) seg << SEG_SHIFT;
+		if (seg < 2)
+			aval |= (pcm_val >> 1) & QUANT_MASK;
+		else
+			aval |= (pcm_val >> seg) & QUANT_MASK;
+		return (aval ^ mask);
+	}
 }
 /* End of code taken from sox */
 
@@ -1107,7 +1251,7 @@
 		else if ( size == 2 ) val = (int)*SHORTP(cp, i);
 		else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
 
-		*ncp++ = st_linear_to_ulaw(val);
+		*ncp++ = st_14linear2ulaw(val);
 	}
 	return rv;
 }
@@ -1138,7 +1282,75 @@
     
 	for ( i=0; i < len*size; i += size ) {
 		cval = *cp++;
-		val = st_ulaw_to_linear(cval);
+		val = st_ulaw2linear16(cval);
+	
+		if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val >> 8);
+		else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
+		else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
+	}
+	return rv;
+}
+
+static PyObject *
+audioop_lin2alaw(PyObject *self, PyObject *args)
+{
+	signed char *cp;
+	unsigned char *ncp;
+	int len, size, val = 0;
+	PyObject *rv;
+	int i;
+
+	if ( !PyArg_Parse(args, "(s#i)",
+			  &cp, &len, &size) )
+		return 0;
+
+	if ( size != 1 && size != 2 && size != 4) {
+		PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, len/size);
+	if ( rv == 0 )
+		return 0;
+	ncp = (unsigned char *)PyString_AsString(rv);
+    
+	for ( i=0; i < len; i += size ) {
+		if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
+		else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+		else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+		*ncp++ = st_linear2alaw(val);
+	}
+	return rv;
+}
+
+static PyObject *
+audioop_alaw2lin(PyObject *self, PyObject *args)
+{
+	unsigned char *cp;
+	unsigned char cval;
+	signed char *ncp;
+	int len, size, val;
+	PyObject *rv;
+	int i;
+
+	if ( !PyArg_Parse(args, "(s#i)",
+			  &cp, &len, &size) )
+		return 0;
+
+	if ( size != 1 && size != 2 && size != 4) {
+		PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+		return 0;
+	}
+    
+	rv = PyString_FromStringAndSize(NULL, len*size);
+	if ( rv == 0 )
+		return 0;
+	ncp = (signed char *)PyString_AsString(rv);
+    
+	for ( i=0; i < len*size; i += size ) {
+		cval = *cp++;
+		val = st_alaw2linear16(cval);
 	
 		if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val >> 8);
 		else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
@@ -1362,6 +1574,8 @@
 	{ "bias", audioop_bias, METH_OLDARGS },
 	{ "ulaw2lin", audioop_ulaw2lin, METH_OLDARGS },
 	{ "lin2ulaw", audioop_lin2ulaw, METH_OLDARGS },
+	{ "alaw2lin", audioop_alaw2lin, METH_OLDARGS },
+	{ "lin2alaw", audioop_lin2alaw, METH_OLDARGS },
 	{ "lin2lin", audioop_lin2lin, METH_OLDARGS },
 	{ "adpcm2lin", audioop_adpcm2lin, METH_OLDARGS },
 	{ "lin2adpcm", audioop_lin2adpcm, METH_OLDARGS },


More information about the Python-checkins mailing list