Branch data Line data Source code
1 : : /* The audioop module uses the code base in g777.c file of the Sox project.
2 : : * Source: https://web.archive.org/web/19970716121258/http://www.spies.com/Sox/Archive/soxgamma.tar.gz
3 : : * Programming the AdLib/Sound Blaster
4 : : * FM Music Chips
5 : : * Version 2.0 (24 Feb 1992)
6 : : *
7 : : * Copyright (c) 1991, 1992 by Jeffrey S. Lee
8 : : *
9 : : * jlee@smylex.uucp
10 : : *
11 : : *
12 : : *
13 : : * Warranty and Copyright Policy
14 : : *
15 : : * This document is provided on an "as-is" basis, and its author makes
16 : : * no warranty or representation, express or implied, with respect to
17 : : * its quality performance or fitness for a particular purpose. In no
18 : : * event will the author of this document be liable for direct, indirect,
19 : : * special, incidental, or consequential damages arising out of the use
20 : : * or inability to use the information contained within. Use of this
21 : : * document is at your own risk.
22 : : *
23 : : * This file may be used and copied freely so long as the applicable
24 : : * copyright notices are retained, and no modifications are made to the
25 : : * text of the document. No money shall be charged for its distribution
26 : : * beyond reasonable shipping, handling and duplication costs, nor shall
27 : : * proprietary changes be made to this document so that it cannot be
28 : : * distributed freely. This document may not be included in published
29 : : * material or commercial packages without the written consent of its
30 : : * author. */
31 : :
32 : : /* audioopmodule - Module to detect peak values in arrays */
33 : :
34 : : #define PY_SSIZE_T_CLEAN
35 : :
36 : : #include "Python.h"
37 : :
38 : : static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
39 : : /* -1 trick is needed on Windows to support -0x80000000 without a warning */
40 : : static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
41 : : static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
42 : :
43 : : static int
44 : 0 : fbound(double val, double minval, double maxval)
45 : : {
46 [ # # ]: 0 : if (val > maxval) {
47 : 0 : val = maxval;
48 : : }
49 [ # # ]: 0 : else if (val < minval + 1.0) {
50 : 0 : val = minval;
51 : : }
52 : :
53 : : /* Round towards minus infinity (-inf) */
54 : 0 : val = floor(val);
55 : :
56 : : /* Cast double to integer: round towards zero */
57 : 0 : return (int)val;
58 : : }
59 : :
60 : :
61 : : #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
62 : : #define CLIP 32635
63 : : #define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
64 : : #define QUANT_MASK (0xf) /* Quantization field mask. */
65 : : #define SEG_SHIFT (4) /* Left shift for segment number. */
66 : : #define SEG_MASK (0x70) /* Segment field mask. */
67 : :
68 : : static const int16_t seg_aend[8] = {
69 : : 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
70 : : };
71 : : static const int16_t seg_uend[8] = {
72 : : 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF
73 : : };
74 : :
75 : : static int16_t
76 : 0 : search(int16_t val, const int16_t *table, int size)
77 : : {
78 : : assert(0 <= size);
79 : : assert(size < INT16_MAX);
80 : : int i;
81 : :
82 [ # # ]: 0 : for (i = 0; i < size; i++) {
83 [ # # ]: 0 : if (val <= *table++)
84 : 0 : return (i);
85 : : }
86 : 0 : return (size);
87 : : }
88 : : #define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
89 : : #define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
90 : :
91 : : static const int16_t _st_ulaw2linear16[256] = {
92 : : -32124, -31100, -30076, -29052, -28028, -27004, -25980,
93 : : -24956, -23932, -22908, -21884, -20860, -19836, -18812,
94 : : -17788, -16764, -15996, -15484, -14972, -14460, -13948,
95 : : -13436, -12924, -12412, -11900, -11388, -10876, -10364,
96 : : -9852, -9340, -8828, -8316, -7932, -7676, -7420,
97 : : -7164, -6908, -6652, -6396, -6140, -5884, -5628,
98 : : -5372, -5116, -4860, -4604, -4348, -4092, -3900,
99 : : -3772, -3644, -3516, -3388, -3260, -3132, -3004,
100 : : -2876, -2748, -2620, -2492, -2364, -2236, -2108,
101 : : -1980, -1884, -1820, -1756, -1692, -1628, -1564,
102 : : -1500, -1436, -1372, -1308, -1244, -1180, -1116,
103 : : -1052, -988, -924, -876, -844, -812, -780,
104 : : -748, -716, -684, -652, -620, -588, -556,
105 : : -524, -492, -460, -428, -396, -372, -356,
106 : : -340, -324, -308, -292, -276, -260, -244,
107 : : -228, -212, -196, -180, -164, -148, -132,
108 : : -120, -112, -104, -96, -88, -80, -72,
109 : : -64, -56, -48, -40, -32, -24, -16,
110 : : -8, 0, 32124, 31100, 30076, 29052, 28028,
111 : : 27004, 25980, 24956, 23932, 22908, 21884, 20860,
112 : : 19836, 18812, 17788, 16764, 15996, 15484, 14972,
113 : : 14460, 13948, 13436, 12924, 12412, 11900, 11388,
114 : : 10876, 10364, 9852, 9340, 8828, 8316, 7932,
115 : : 7676, 7420, 7164, 6908, 6652, 6396, 6140,
116 : : 5884, 5628, 5372, 5116, 4860, 4604, 4348,
117 : : 4092, 3900, 3772, 3644, 3516, 3388, 3260,
118 : : 3132, 3004, 2876, 2748, 2620, 2492, 2364,
119 : : 2236, 2108, 1980, 1884, 1820, 1756, 1692,
120 : : 1628, 1564, 1500, 1436, 1372, 1308, 1244,
121 : : 1180, 1116, 1052, 988, 924, 876, 844,
122 : : 812, 780, 748, 716, 684, 652, 620,
123 : : 588, 556, 524, 492, 460, 428, 396,
124 : : 372, 356, 340, 324, 308, 292, 276,
125 : : 260, 244, 228, 212, 196, 180, 164,
126 : : 148, 132, 120, 112, 104, 96, 88,
127 : : 80, 72, 64, 56, 48, 40, 32,
128 : : 24, 16, 8, 0
129 : : };
130 : :
131 : : /*
132 : : * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
133 : : * stored in an unsigned char. This function should only be called with
134 : : * the data shifted such that it only contains information in the lower
135 : : * 14-bits.
136 : : *
137 : : * In order to simplify the encoding process, the original linear magnitude
138 : : * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
139 : : * (33 - 8191). The result can be seen in the following encoding table:
140 : : *
141 : : * Biased Linear Input Code Compressed Code
142 : : * ------------------------ ---------------
143 : : * 00000001wxyza 000wxyz
144 : : * 0000001wxyzab 001wxyz
145 : : * 000001wxyzabc 010wxyz
146 : : * 00001wxyzabcd 011wxyz
147 : : * 0001wxyzabcde 100wxyz
148 : : * 001wxyzabcdef 101wxyz
149 : : * 01wxyzabcdefg 110wxyz
150 : : * 1wxyzabcdefgh 111wxyz
151 : : *
152 : : * Each biased linear code has a leading 1 which identifies the segment
153 : : * number. The value of the segment number is equal to 7 minus the number
154 : : * of leading 0's. The quantization interval is directly available as the
155 : : * four bits wxyz. * The trailing bits (a - h) are ignored.
156 : : *
157 : : * Ordinarily the complement of the resulting code word is used for
158 : : * transmission, and so the code word is complemented before it is returned.
159 : : *
160 : : * For further information see John C. Bellamy's Digital Telephony, 1982,
161 : : * John Wiley & Sons, pps 98-111 and 472-476.
162 : : */
163 : : static unsigned char
164 : 0 : st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */
165 : : {
166 : : int16_t mask;
167 : : int16_t seg;
168 : : unsigned char uval;
169 : :
170 : : /* u-law inverts all bits */
171 : : /* Get the sign and the magnitude of the value. */
172 [ # # ]: 0 : if (pcm_val < 0) {
173 : 0 : pcm_val = -pcm_val;
174 : 0 : mask = 0x7F;
175 : : } else {
176 : 0 : mask = 0xFF;
177 : : }
178 [ # # ]: 0 : if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
179 : 0 : pcm_val += (BIAS >> 2);
180 : :
181 : : /* Convert the scaled magnitude to segment number. */
182 : 0 : seg = search(pcm_val, seg_uend, 8);
183 : :
184 : : /*
185 : : * Combine the sign, segment, quantization bits;
186 : : * and complement the code word.
187 : : */
188 [ # # ]: 0 : if (seg >= 8) /* out of range, return maximum value. */
189 : 0 : return (unsigned char) (0x7F ^ mask);
190 : : else {
191 : : assert(seg >= 0);
192 : 0 : uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
193 : 0 : return (uval ^ mask);
194 : : }
195 : :
196 : : }
197 : :
198 : : static const int16_t _st_alaw2linear16[256] = {
199 : : -5504, -5248, -6016, -5760, -4480, -4224, -4992,
200 : : -4736, -7552, -7296, -8064, -7808, -6528, -6272,
201 : : -7040, -6784, -2752, -2624, -3008, -2880, -2240,
202 : : -2112, -2496, -2368, -3776, -3648, -4032, -3904,
203 : : -3264, -3136, -3520, -3392, -22016, -20992, -24064,
204 : : -23040, -17920, -16896, -19968, -18944, -30208, -29184,
205 : : -32256, -31232, -26112, -25088, -28160, -27136, -11008,
206 : : -10496, -12032, -11520, -8960, -8448, -9984, -9472,
207 : : -15104, -14592, -16128, -15616, -13056, -12544, -14080,
208 : : -13568, -344, -328, -376, -360, -280, -264,
209 : : -312, -296, -472, -456, -504, -488, -408,
210 : : -392, -440, -424, -88, -72, -120, -104,
211 : : -24, -8, -56, -40, -216, -200, -248,
212 : : -232, -152, -136, -184, -168, -1376, -1312,
213 : : -1504, -1440, -1120, -1056, -1248, -1184, -1888,
214 : : -1824, -2016, -1952, -1632, -1568, -1760, -1696,
215 : : -688, -656, -752, -720, -560, -528, -624,
216 : : -592, -944, -912, -1008, -976, -816, -784,
217 : : -880, -848, 5504, 5248, 6016, 5760, 4480,
218 : : 4224, 4992, 4736, 7552, 7296, 8064, 7808,
219 : : 6528, 6272, 7040, 6784, 2752, 2624, 3008,
220 : : 2880, 2240, 2112, 2496, 2368, 3776, 3648,
221 : : 4032, 3904, 3264, 3136, 3520, 3392, 22016,
222 : : 20992, 24064, 23040, 17920, 16896, 19968, 18944,
223 : : 30208, 29184, 32256, 31232, 26112, 25088, 28160,
224 : : 27136, 11008, 10496, 12032, 11520, 8960, 8448,
225 : : 9984, 9472, 15104, 14592, 16128, 15616, 13056,
226 : : 12544, 14080, 13568, 344, 328, 376, 360,
227 : : 280, 264, 312, 296, 472, 456, 504,
228 : : 488, 408, 392, 440, 424, 88, 72,
229 : : 120, 104, 24, 8, 56, 40, 216,
230 : : 200, 248, 232, 152, 136, 184, 168,
231 : : 1376, 1312, 1504, 1440, 1120, 1056, 1248,
232 : : 1184, 1888, 1824, 2016, 1952, 1632, 1568,
233 : : 1760, 1696, 688, 656, 752, 720, 560,
234 : : 528, 624, 592, 944, 912, 1008, 976,
235 : : 816, 784, 880, 848
236 : : };
237 : :
238 : : /*
239 : : * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
240 : : * stored in an unsigned char. This function should only be called with
241 : : * the data shifted such that it only contains information in the lower
242 : : * 13-bits.
243 : : *
244 : : * Linear Input Code Compressed Code
245 : : * ------------------------ ---------------
246 : : * 0000000wxyza 000wxyz
247 : : * 0000001wxyza 001wxyz
248 : : * 000001wxyzab 010wxyz
249 : : * 00001wxyzabc 011wxyz
250 : : * 0001wxyzabcd 100wxyz
251 : : * 001wxyzabcde 101wxyz
252 : : * 01wxyzabcdef 110wxyz
253 : : * 1wxyzabcdefg 111wxyz
254 : : *
255 : : * For further information see John C. Bellamy's Digital Telephony, 1982,
256 : : * John Wiley & Sons, pps 98-111 and 472-476.
257 : : */
258 : : static unsigned char
259 : 0 : st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */
260 : : {
261 : : int16_t mask;
262 : : int16_t seg;
263 : : unsigned char aval;
264 : :
265 : : /* A-law using even bit inversion */
266 [ # # ]: 0 : if (pcm_val >= 0) {
267 : 0 : mask = 0xD5; /* sign (7th) bit = 1 */
268 : : } else {
269 : 0 : mask = 0x55; /* sign bit = 0 */
270 : 0 : pcm_val = -pcm_val - 1;
271 : : }
272 : :
273 : : /* Convert the scaled magnitude to segment number. */
274 : 0 : seg = search(pcm_val, seg_aend, 8);
275 : :
276 : : /* Combine the sign, segment, and quantization bits. */
277 : :
278 [ # # ]: 0 : if (seg >= 8) /* out of range, return maximum value. */
279 : 0 : return (unsigned char) (0x7F ^ mask);
280 : : else {
281 : 0 : aval = (unsigned char) seg << SEG_SHIFT;
282 [ # # ]: 0 : if (seg < 2)
283 : 0 : aval |= (pcm_val >> 1) & QUANT_MASK;
284 : : else
285 : 0 : aval |= (pcm_val >> seg) & QUANT_MASK;
286 : 0 : return (aval ^ mask);
287 : : }
288 : : }
289 : : /* End of code taken from sox */
290 : :
291 : : /* Intel ADPCM step variation table */
292 : : static const int indexTable[16] = {
293 : : -1, -1, -1, -1, 2, 4, 6, 8,
294 : : -1, -1, -1, -1, 2, 4, 6, 8,
295 : : };
296 : :
297 : : static const int stepsizeTable[89] = {
298 : : 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
299 : : 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
300 : : 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
301 : : 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
302 : : 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
303 : : 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
304 : : 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
305 : : 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
306 : : 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
307 : : };
308 : :
309 : : #define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
310 : : #define SETINTX(T, cp, i, val) do { \
311 : : *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
312 : : } while (0)
313 : :
314 : :
315 : : #define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
316 : : #define GETINT16(cp, i) GETINTX(int16_t, (cp), (i))
317 : : #define GETINT32(cp, i) GETINTX(int32_t, (cp), (i))
318 : :
319 : : #ifdef WORDS_BIGENDIAN
320 : : #define GETINT24(cp, i) ( \
321 : : ((unsigned char *)(cp) + (i))[2] + \
322 : : (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \
323 : : (((signed char *)(cp) + (i))[0] * (1 << 16)) )
324 : : #else
325 : : #define GETINT24(cp, i) ( \
326 : : ((unsigned char *)(cp) + (i))[0] + \
327 : : (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \
328 : : (((signed char *)(cp) + (i))[2] * (1 << 16)) )
329 : : #endif
330 : :
331 : :
332 : : #define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
333 : : #define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val))
334 : : #define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val))
335 : :
336 : : #ifdef WORDS_BIGENDIAN
337 : : #define SETINT24(cp, i, val) do { \
338 : : ((unsigned char *)(cp) + (i))[2] = (int)(val); \
339 : : ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
340 : : ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
341 : : } while (0)
342 : : #else
343 : : #define SETINT24(cp, i, val) do { \
344 : : ((unsigned char *)(cp) + (i))[0] = (int)(val); \
345 : : ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
346 : : ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
347 : : } while (0)
348 : : #endif
349 : :
350 : :
351 : : #define GETRAWSAMPLE(size, cp, i) ( \
352 : : (size == 1) ? (int)GETINT8((cp), (i)) : \
353 : : (size == 2) ? (int)GETINT16((cp), (i)) : \
354 : : (size == 3) ? (int)GETINT24((cp), (i)) : \
355 : : (int)GETINT32((cp), (i)))
356 : :
357 : : #define SETRAWSAMPLE(size, cp, i, val) do { \
358 : : if (size == 1) \
359 : : SETINT8((cp), (i), (val)); \
360 : : else if (size == 2) \
361 : : SETINT16((cp), (i), (val)); \
362 : : else if (size == 3) \
363 : : SETINT24((cp), (i), (val)); \
364 : : else \
365 : : SETINT32((cp), (i), (val)); \
366 : : } while(0)
367 : :
368 : :
369 : : #define GETSAMPLE32(size, cp, i) ( \
370 : : (size == 1) ? (int)GETINT8((cp), (i)) * (1 << 24) : \
371 : : (size == 2) ? (int)GETINT16((cp), (i)) * (1 << 16) : \
372 : : (size == 3) ? (int)GETINT24((cp), (i)) * (1 << 8) : \
373 : : (int)GETINT32((cp), (i)))
374 : :
375 : : #define SETSAMPLE32(size, cp, i, val) do { \
376 : : if (size == 1) \
377 : : SETINT8((cp), (i), (val) >> 24); \
378 : : else if (size == 2) \
379 : : SETINT16((cp), (i), (val) >> 16); \
380 : : else if (size == 3) \
381 : : SETINT24((cp), (i), (val) >> 8); \
382 : : else \
383 : : SETINT32((cp), (i), (val)); \
384 : : } while(0)
385 : :
386 : : static PyModuleDef audioopmodule;
387 : :
388 : : typedef struct {
389 : : PyObject *AudioopError;
390 : : } audioop_state;
391 : :
392 : : static inline audioop_state *
393 : 9 : get_audioop_state(PyObject *module)
394 : : {
395 : 9 : void *state = PyModule_GetState(module);
396 : : assert(state != NULL);
397 : 9 : return (audioop_state *)state;
398 : : }
399 : :
400 : : static int
401 : 0 : audioop_check_size(PyObject *module, int size)
402 : : {
403 [ # # # # ]: 0 : if (size < 1 || size > 4) {
404 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
405 : : "Size should be 1, 2, 3 or 4");
406 : 0 : return 0;
407 : : }
408 : : else
409 : 0 : return 1;
410 : : }
411 : :
412 : : static int
413 : 0 : audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
414 : : {
415 [ # # ]: 0 : if (!audioop_check_size(module, size))
416 : 0 : return 0;
417 [ # # ]: 0 : if (len % size != 0) {
418 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
419 : : "not a whole number of frames");
420 : 0 : return 0;
421 : : }
422 : 0 : return 1;
423 : : }
424 : :
425 : : /*[clinic input]
426 : : module audioop
427 : : [clinic start generated code]*/
428 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
429 : :
430 : : /*[clinic input]
431 : : audioop.getsample
432 : :
433 : : fragment: Py_buffer
434 : : width: int
435 : : index: Py_ssize_t
436 : : /
437 : :
438 : : Return the value of sample index from the fragment.
439 : : [clinic start generated code]*/
440 : :
441 : : static PyObject *
442 : 0 : audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
443 : : Py_ssize_t index)
444 : : /*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
445 : : {
446 : : int val;
447 : :
448 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
449 : 0 : return NULL;
450 [ # # # # ]: 0 : if (index < 0 || index >= fragment->len/width) {
451 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
452 : : "Index out of range");
453 : 0 : return NULL;
454 : : }
455 [ # # # # : 0 : val = GETRAWSAMPLE(width, fragment->buf, index*width);
# # ]
456 : 0 : return PyLong_FromLong(val);
457 : : }
458 : :
459 : : /*[clinic input]
460 : : audioop.max
461 : :
462 : : fragment: Py_buffer
463 : : width: int
464 : : /
465 : :
466 : : Return the maximum of the absolute value of all samples in a fragment.
467 : : [clinic start generated code]*/
468 : :
469 : : static PyObject *
470 : 0 : audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
471 : : /*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/
472 : : {
473 : : Py_ssize_t i;
474 : 0 : unsigned int absval, max = 0;
475 : :
476 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
477 : 0 : return NULL;
478 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
479 [ # # # # : 0 : int val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
480 : : /* Cast to unsigned before negating. Unsigned overflow is well-
481 : : defined, but signed overflow is not. */
482 [ # # ]: 0 : if (val < 0) absval = (unsigned int)-(int64_t)val;
483 : 0 : else absval = val;
484 [ # # ]: 0 : if (absval > max) max = absval;
485 : : }
486 : 0 : return PyLong_FromUnsignedLong(max);
487 : : }
488 : :
489 : : /*[clinic input]
490 : : audioop.minmax
491 : :
492 : : fragment: Py_buffer
493 : : width: int
494 : : /
495 : :
496 : : Return the minimum and maximum values of all samples in the sound fragment.
497 : : [clinic start generated code]*/
498 : :
499 : : static PyObject *
500 : 0 : audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
501 : : /*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/
502 : : {
503 : : Py_ssize_t i;
504 : : /* -1 trick below is needed on Windows to support -0x80000000 without
505 : : a warning */
506 : 0 : int min = 0x7fffffff, max = -0x7FFFFFFF-1;
507 : :
508 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
509 : 0 : return NULL;
510 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
511 [ # # # # : 0 : int val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
512 [ # # ]: 0 : if (val > max) max = val;
513 [ # # ]: 0 : if (val < min) min = val;
514 : : }
515 : 0 : return Py_BuildValue("(ii)", min, max);
516 : : }
517 : :
518 : : /*[clinic input]
519 : : audioop.avg
520 : :
521 : : fragment: Py_buffer
522 : : width: int
523 : : /
524 : :
525 : : Return the average over all samples in the fragment.
526 : : [clinic start generated code]*/
527 : :
528 : : static PyObject *
529 : 0 : audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
530 : : /*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/
531 : : {
532 : : Py_ssize_t i;
533 : : int avg;
534 : 0 : double sum = 0.0;
535 : :
536 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
537 : 0 : return NULL;
538 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width)
539 [ # # # # : 0 : sum += GETRAWSAMPLE(width, fragment->buf, i);
# # ]
540 [ # # ]: 0 : if (fragment->len == 0)
541 : 0 : avg = 0;
542 : : else
543 : 0 : avg = (int)floor(sum / (double)(fragment->len/width));
544 : 0 : return PyLong_FromLong(avg);
545 : : }
546 : :
547 : : /*[clinic input]
548 : : audioop.rms
549 : :
550 : : fragment: Py_buffer
551 : : width: int
552 : : /
553 : :
554 : : Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
555 : : [clinic start generated code]*/
556 : :
557 : : static PyObject *
558 : 0 : audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
559 : : /*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/
560 : : {
561 : : Py_ssize_t i;
562 : : unsigned int res;
563 : 0 : double sum_squares = 0.0;
564 : :
565 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
566 : 0 : return NULL;
567 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
568 [ # # # # : 0 : double val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
569 : 0 : sum_squares += val*val;
570 : : }
571 [ # # ]: 0 : if (fragment->len == 0)
572 : 0 : res = 0;
573 : : else
574 : 0 : res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
575 : 0 : return PyLong_FromUnsignedLong(res);
576 : : }
577 : :
578 : 0 : static double _sum2(const int16_t *a, const int16_t *b, Py_ssize_t len)
579 : : {
580 : : Py_ssize_t i;
581 : 0 : double sum = 0.0;
582 : :
583 [ # # ]: 0 : for( i=0; i<len; i++) {
584 : 0 : sum = sum + (double)a[i]*(double)b[i];
585 : : }
586 : 0 : return sum;
587 : : }
588 : :
589 : : /*
590 : : ** Findfit tries to locate a sample within another sample. Its main use
591 : : ** is in echo-cancellation (to find the feedback of the output signal in
592 : : ** the input signal).
593 : : ** The method used is as follows:
594 : : **
595 : : ** let R be the reference signal (length n) and A the input signal (length N)
596 : : ** with N > n, and let all sums be over i from 0 to n-1.
597 : : **
598 : : ** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
599 : : ** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
600 : : ** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
601 : : **
602 : : ** Next, we compute the relative distance between the original signal and
603 : : ** the modified signal and minimize that over j:
604 : : ** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
605 : : ** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
606 : : **
607 : : ** In the code variables correspond as follows:
608 : : ** cp1 A
609 : : ** cp2 R
610 : : ** len1 N
611 : : ** len2 n
612 : : ** aj_m1 A[j-1]
613 : : ** aj_lm1 A[j+n-1]
614 : : ** sum_ri_2 sum(R[i]^2)
615 : : ** sum_aij_2 sum(A[i+j]^2)
616 : : ** sum_aij_ri sum(A[i+j]R[i])
617 : : **
618 : : ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
619 : : ** is completely recalculated each step.
620 : : */
621 : : /*[clinic input]
622 : : audioop.findfit
623 : :
624 : : fragment: Py_buffer
625 : : reference: Py_buffer
626 : : /
627 : :
628 : : Try to match reference as well as possible to a portion of fragment.
629 : : [clinic start generated code]*/
630 : :
631 : : static PyObject *
632 : 0 : audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
633 : : Py_buffer *reference)
634 : : /*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/
635 : : {
636 : : const int16_t *cp1, *cp2;
637 : : Py_ssize_t len1, len2;
638 : : Py_ssize_t j, best_j;
639 : : double aj_m1, aj_lm1;
640 : : double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
641 : :
642 [ # # # # ]: 0 : if (fragment->len & 1 || reference->len & 1) {
643 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
644 : : "Strings should be even-sized");
645 : 0 : return NULL;
646 : : }
647 : 0 : cp1 = (const int16_t *)fragment->buf;
648 : 0 : len1 = fragment->len >> 1;
649 : 0 : cp2 = (const int16_t *)reference->buf;
650 : 0 : len2 = reference->len >> 1;
651 : :
652 [ # # ]: 0 : if (len1 < len2) {
653 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
654 : : "First sample should be longer");
655 : 0 : return NULL;
656 : : }
657 : 0 : sum_ri_2 = _sum2(cp2, cp2, len2);
658 : 0 : sum_aij_2 = _sum2(cp1, cp1, len2);
659 : 0 : sum_aij_ri = _sum2(cp1, cp2, len2);
660 : :
661 : 0 : result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
662 : :
663 : 0 : best_result = result;
664 : 0 : best_j = 0;
665 : :
666 [ # # ]: 0 : for ( j=1; j<=len1-len2; j++) {
667 : 0 : aj_m1 = (double)cp1[j-1];
668 : 0 : aj_lm1 = (double)cp1[j+len2-1];
669 : :
670 : 0 : sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
671 : 0 : sum_aij_ri = _sum2(cp1+j, cp2, len2);
672 : :
673 : 0 : result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
674 : : / sum_aij_2;
675 : :
676 [ # # ]: 0 : if ( result < best_result ) {
677 : 0 : best_result = result;
678 : 0 : best_j = j;
679 : : }
680 : :
681 : : }
682 : :
683 : 0 : factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
684 : :
685 : 0 : return Py_BuildValue("(nf)", best_j, factor);
686 : : }
687 : :
688 : : /*
689 : : ** findfactor finds a factor f so that the energy in A-fB is minimal.
690 : : ** See the comment for findfit for details.
691 : : */
692 : : /*[clinic input]
693 : : audioop.findfactor
694 : :
695 : : fragment: Py_buffer
696 : : reference: Py_buffer
697 : : /
698 : :
699 : : Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
700 : : [clinic start generated code]*/
701 : :
702 : : static PyObject *
703 : 0 : audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
704 : : Py_buffer *reference)
705 : : /*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/
706 : : {
707 : : const int16_t *cp1, *cp2;
708 : : Py_ssize_t len;
709 : : double sum_ri_2, sum_aij_ri, result;
710 : :
711 [ # # # # ]: 0 : if (fragment->len & 1 || reference->len & 1) {
712 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
713 : : "Strings should be even-sized");
714 : 0 : return NULL;
715 : : }
716 [ # # ]: 0 : if (fragment->len != reference->len) {
717 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
718 : : "Samples should be same size");
719 : 0 : return NULL;
720 : : }
721 : 0 : cp1 = (const int16_t *)fragment->buf;
722 : 0 : cp2 = (const int16_t *)reference->buf;
723 : 0 : len = fragment->len >> 1;
724 : 0 : sum_ri_2 = _sum2(cp2, cp2, len);
725 : 0 : sum_aij_ri = _sum2(cp1, cp2, len);
726 : :
727 : 0 : result = sum_aij_ri / sum_ri_2;
728 : :
729 : 0 : return PyFloat_FromDouble(result);
730 : : }
731 : :
732 : : /*
733 : : ** findmax returns the index of the n-sized segment of the input sample
734 : : ** that contains the most energy.
735 : : */
736 : : /*[clinic input]
737 : : audioop.findmax
738 : :
739 : : fragment: Py_buffer
740 : : length: Py_ssize_t
741 : : /
742 : :
743 : : Search fragment for a slice of specified number of samples with maximum energy.
744 : : [clinic start generated code]*/
745 : :
746 : : static PyObject *
747 : 0 : audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
748 : : Py_ssize_t length)
749 : : /*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/
750 : : {
751 : : const int16_t *cp1;
752 : : Py_ssize_t len1;
753 : : Py_ssize_t j, best_j;
754 : : double aj_m1, aj_lm1;
755 : : double result, best_result;
756 : :
757 [ # # ]: 0 : if (fragment->len & 1) {
758 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
759 : : "Strings should be even-sized");
760 : 0 : return NULL;
761 : : }
762 : 0 : cp1 = (const int16_t *)fragment->buf;
763 : 0 : len1 = fragment->len >> 1;
764 : :
765 [ # # # # ]: 0 : if (length < 0 || len1 < length) {
766 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
767 : : "Input sample should be longer");
768 : 0 : return NULL;
769 : : }
770 : :
771 : 0 : result = _sum2(cp1, cp1, length);
772 : :
773 : 0 : best_result = result;
774 : 0 : best_j = 0;
775 : :
776 [ # # ]: 0 : for ( j=1; j<=len1-length; j++) {
777 : 0 : aj_m1 = (double)cp1[j-1];
778 : 0 : aj_lm1 = (double)cp1[j+length-1];
779 : :
780 : 0 : result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
781 : :
782 [ # # ]: 0 : if ( result > best_result ) {
783 : 0 : best_result = result;
784 : 0 : best_j = j;
785 : : }
786 : :
787 : : }
788 : :
789 : 0 : return PyLong_FromSsize_t(best_j);
790 : : }
791 : :
792 : : /*[clinic input]
793 : : audioop.avgpp
794 : :
795 : : fragment: Py_buffer
796 : : width: int
797 : : /
798 : :
799 : : Return the average peak-peak value over all samples in the fragment.
800 : : [clinic start generated code]*/
801 : :
802 : : static PyObject *
803 : 0 : audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
804 : : /*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/
805 : : {
806 : : Py_ssize_t i;
807 : 0 : int prevval, prevextremevalid = 0, prevextreme = 0;
808 : 0 : double sum = 0.0;
809 : : unsigned int avg;
810 : 0 : int diff, prevdiff, nextreme = 0;
811 : :
812 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
813 : 0 : return NULL;
814 [ # # ]: 0 : if (fragment->len <= width)
815 : 0 : return PyLong_FromLong(0);
816 [ # # # # : 0 : prevval = GETRAWSAMPLE(width, fragment->buf, 0);
# # ]
817 : 0 : prevdiff = 17; /* Anything != 0, 1 */
818 [ # # ]: 0 : for (i = width; i < fragment->len; i += width) {
819 [ # # # # : 0 : int val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
820 [ # # ]: 0 : if (val != prevval) {
821 : 0 : diff = val < prevval;
822 [ # # ]: 0 : if (prevdiff == !diff) {
823 : : /* Derivative changed sign. Compute difference to last
824 : : ** extreme value and remember.
825 : : */
826 [ # # ]: 0 : if (prevextremevalid) {
827 [ # # ]: 0 : if (prevval < prevextreme)
828 : 0 : sum += (double)((unsigned int)prevextreme -
829 : 0 : (unsigned int)prevval);
830 : : else
831 : 0 : sum += (double)((unsigned int)prevval -
832 : 0 : (unsigned int)prevextreme);
833 : 0 : nextreme++;
834 : : }
835 : 0 : prevextremevalid = 1;
836 : 0 : prevextreme = prevval;
837 : : }
838 : 0 : prevval = val;
839 : 0 : prevdiff = diff;
840 : : }
841 : : }
842 [ # # ]: 0 : if ( nextreme == 0 )
843 : 0 : avg = 0;
844 : : else
845 : 0 : avg = (unsigned int)(sum / (double)nextreme);
846 : 0 : return PyLong_FromUnsignedLong(avg);
847 : : }
848 : :
849 : : /*[clinic input]
850 : : audioop.maxpp
851 : :
852 : : fragment: Py_buffer
853 : : width: int
854 : : /
855 : :
856 : : Return the maximum peak-peak value in the sound fragment.
857 : : [clinic start generated code]*/
858 : :
859 : : static PyObject *
860 : 0 : audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
861 : : /*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/
862 : : {
863 : : Py_ssize_t i;
864 : 0 : int prevval, prevextremevalid = 0, prevextreme = 0;
865 : 0 : unsigned int max = 0, extremediff;
866 : : int diff, prevdiff;
867 : :
868 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
869 : 0 : return NULL;
870 [ # # ]: 0 : if (fragment->len <= width)
871 : 0 : return PyLong_FromLong(0);
872 [ # # # # : 0 : prevval = GETRAWSAMPLE(width, fragment->buf, 0);
# # ]
873 : 0 : prevdiff = 17; /* Anything != 0, 1 */
874 [ # # ]: 0 : for (i = width; i < fragment->len; i += width) {
875 [ # # # # : 0 : int val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
876 [ # # ]: 0 : if (val != prevval) {
877 : 0 : diff = val < prevval;
878 [ # # ]: 0 : if (prevdiff == !diff) {
879 : : /* Derivative changed sign. Compute difference to
880 : : ** last extreme value and remember.
881 : : */
882 [ # # ]: 0 : if (prevextremevalid) {
883 [ # # ]: 0 : if (prevval < prevextreme)
884 : 0 : extremediff = (unsigned int)prevextreme -
885 : 0 : (unsigned int)prevval;
886 : : else
887 : 0 : extremediff = (unsigned int)prevval -
888 : 0 : (unsigned int)prevextreme;
889 [ # # ]: 0 : if ( extremediff > max )
890 : 0 : max = extremediff;
891 : : }
892 : 0 : prevextremevalid = 1;
893 : 0 : prevextreme = prevval;
894 : : }
895 : 0 : prevval = val;
896 : 0 : prevdiff = diff;
897 : : }
898 : : }
899 : 0 : return PyLong_FromUnsignedLong(max);
900 : : }
901 : :
902 : : /*[clinic input]
903 : : audioop.cross
904 : :
905 : : fragment: Py_buffer
906 : : width: int
907 : : /
908 : :
909 : : Return the number of zero crossings in the fragment passed as an argument.
910 : : [clinic start generated code]*/
911 : :
912 : : static PyObject *
913 : 0 : audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
914 : : /*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/
915 : : {
916 : : Py_ssize_t i;
917 : : int prevval;
918 : : Py_ssize_t ncross;
919 : :
920 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
921 : 0 : return NULL;
922 : 0 : ncross = -1;
923 : 0 : prevval = 17; /* Anything <> 0,1 */
924 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
925 [ # # # # : 0 : int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
# # ]
926 [ # # ]: 0 : if (val != prevval) ncross++;
927 : 0 : prevval = val;
928 : : }
929 : 0 : return PyLong_FromSsize_t(ncross);
930 : : }
931 : :
932 : : /*[clinic input]
933 : : audioop.mul
934 : :
935 : : fragment: Py_buffer
936 : : width: int
937 : : factor: double
938 : : /
939 : :
940 : : Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
941 : : [clinic start generated code]*/
942 : :
943 : : static PyObject *
944 : 0 : audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
945 : : double factor)
946 : : /*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/
947 : : {
948 : : signed char *ncp;
949 : : Py_ssize_t i;
950 : : double maxval, minval;
951 : : PyObject *rv;
952 : :
953 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
954 : 0 : return NULL;
955 : :
956 : 0 : maxval = (double) maxvals[width];
957 : 0 : minval = (double) minvals[width];
958 : :
959 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len);
960 [ # # ]: 0 : if (rv == NULL)
961 : 0 : return NULL;
962 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
963 : :
964 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
965 [ # # # # : 0 : double val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
966 : 0 : int ival = fbound(val * factor, minval, maxval);
967 [ # # # # : 0 : SETRAWSAMPLE(width, ncp, i, ival);
# # ]
968 : : }
969 : 0 : return rv;
970 : : }
971 : :
972 : : /*[clinic input]
973 : : audioop.tomono
974 : :
975 : : fragment: Py_buffer
976 : : width: int
977 : : lfactor: double
978 : : rfactor: double
979 : : /
980 : :
981 : : Convert a stereo fragment to a mono fragment.
982 : : [clinic start generated code]*/
983 : :
984 : : static PyObject *
985 : 0 : audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
986 : : double lfactor, double rfactor)
987 : : /*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/
988 : : {
989 : : signed char *cp, *ncp;
990 : : Py_ssize_t len, i;
991 : : double maxval, minval;
992 : : PyObject *rv;
993 : :
994 : 0 : cp = fragment->buf;
995 : 0 : len = fragment->len;
996 [ # # ]: 0 : if (!audioop_check_parameters(module, len, width))
997 : 0 : return NULL;
998 [ # # ]: 0 : if (((len / width) & 1) != 0) {
999 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1000 : : "not a whole number of frames");
1001 : 0 : return NULL;
1002 : : }
1003 : :
1004 : 0 : maxval = (double) maxvals[width];
1005 : 0 : minval = (double) minvals[width];
1006 : :
1007 : 0 : rv = PyBytes_FromStringAndSize(NULL, len/2);
1008 [ # # ]: 0 : if (rv == NULL)
1009 : 0 : return NULL;
1010 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
1011 : :
1012 [ # # ]: 0 : for (i = 0; i < len; i += width*2) {
1013 [ # # # # : 0 : double val1 = GETRAWSAMPLE(width, cp, i);
# # ]
1014 [ # # # # : 0 : double val2 = GETRAWSAMPLE(width, cp, i + width);
# # ]
1015 : 0 : double val = val1 * lfactor + val2 * rfactor;
1016 : 0 : int ival = fbound(val, minval, maxval);
1017 [ # # # # : 0 : SETRAWSAMPLE(width, ncp, i/2, ival);
# # ]
1018 : : }
1019 : 0 : return rv;
1020 : : }
1021 : :
1022 : : /*[clinic input]
1023 : : audioop.tostereo
1024 : :
1025 : : fragment: Py_buffer
1026 : : width: int
1027 : : lfactor: double
1028 : : rfactor: double
1029 : : /
1030 : :
1031 : : Generate a stereo fragment from a mono fragment.
1032 : : [clinic start generated code]*/
1033 : :
1034 : : static PyObject *
1035 : 0 : audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
1036 : : double lfactor, double rfactor)
1037 : : /*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/
1038 : : {
1039 : : signed char *ncp;
1040 : : Py_ssize_t i;
1041 : : double maxval, minval;
1042 : : PyObject *rv;
1043 : :
1044 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1045 : 0 : return NULL;
1046 : :
1047 : 0 : maxval = (double) maxvals[width];
1048 : 0 : minval = (double) minvals[width];
1049 : :
1050 [ # # ]: 0 : if (fragment->len > PY_SSIZE_T_MAX/2) {
1051 : 0 : PyErr_SetString(PyExc_MemoryError,
1052 : : "not enough memory for output buffer");
1053 : 0 : return NULL;
1054 : : }
1055 : :
1056 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
1057 [ # # ]: 0 : if (rv == NULL)
1058 : 0 : return NULL;
1059 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
1060 : :
1061 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1062 [ # # # # : 0 : double val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
1063 : 0 : int val1 = fbound(val * lfactor, minval, maxval);
1064 : 0 : int val2 = fbound(val * rfactor, minval, maxval);
1065 [ # # # # : 0 : SETRAWSAMPLE(width, ncp, i*2, val1);
# # ]
1066 [ # # # # : 0 : SETRAWSAMPLE(width, ncp, i*2 + width, val2);
# # ]
1067 : : }
1068 : 0 : return rv;
1069 : : }
1070 : :
1071 : : /*[clinic input]
1072 : : audioop.add
1073 : :
1074 : : fragment1: Py_buffer
1075 : : fragment2: Py_buffer
1076 : : width: int
1077 : : /
1078 : :
1079 : : Return a fragment which is the addition of the two samples passed as parameters.
1080 : : [clinic start generated code]*/
1081 : :
1082 : : static PyObject *
1083 : 0 : audioop_add_impl(PyObject *module, Py_buffer *fragment1,
1084 : : Py_buffer *fragment2, int width)
1085 : : /*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/
1086 : : {
1087 : : signed char *ncp;
1088 : : Py_ssize_t i;
1089 : : int minval, maxval, newval;
1090 : : PyObject *rv;
1091 : :
1092 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment1->len, width))
1093 : 0 : return NULL;
1094 [ # # ]: 0 : if (fragment1->len != fragment2->len) {
1095 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1096 : : "Lengths should be the same");
1097 : 0 : return NULL;
1098 : : }
1099 : :
1100 : 0 : maxval = maxvals[width];
1101 : 0 : minval = minvals[width];
1102 : :
1103 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
1104 [ # # ]: 0 : if (rv == NULL)
1105 : 0 : return NULL;
1106 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
1107 : :
1108 [ # # ]: 0 : for (i = 0; i < fragment1->len; i += width) {
1109 [ # # # # : 0 : int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
# # ]
1110 [ # # # # : 0 : int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
# # ]
1111 : :
1112 [ # # ]: 0 : if (width < 4) {
1113 : 0 : newval = val1 + val2;
1114 : : /* truncate in case of overflow */
1115 [ # # ]: 0 : if (newval > maxval)
1116 : 0 : newval = maxval;
1117 [ # # ]: 0 : else if (newval < minval)
1118 : 0 : newval = minval;
1119 : : }
1120 : : else {
1121 : 0 : double fval = (double)val1 + (double)val2;
1122 : : /* truncate in case of overflow */
1123 : 0 : newval = fbound(fval, minval, maxval);
1124 : : }
1125 : :
1126 [ # # # # : 0 : SETRAWSAMPLE(width, ncp, i, newval);
# # ]
1127 : : }
1128 : 0 : return rv;
1129 : : }
1130 : :
1131 : : /*[clinic input]
1132 : : audioop.bias
1133 : :
1134 : : fragment: Py_buffer
1135 : : width: int
1136 : : bias: int
1137 : : /
1138 : :
1139 : : Return a fragment that is the original fragment with a bias added to each sample.
1140 : : [clinic start generated code]*/
1141 : :
1142 : : static PyObject *
1143 : 0 : audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
1144 : : /*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/
1145 : : {
1146 : : signed char *ncp;
1147 : : Py_ssize_t i;
1148 : 0 : unsigned int val = 0, mask;
1149 : : PyObject *rv;
1150 : :
1151 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1152 : 0 : return NULL;
1153 : :
1154 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len);
1155 [ # # ]: 0 : if (rv == NULL)
1156 : 0 : return NULL;
1157 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
1158 : :
1159 : 0 : mask = masks[width];
1160 : :
1161 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1162 [ # # ]: 0 : if (width == 1)
1163 : 0 : val = GETINTX(unsigned char, fragment->buf, i);
1164 [ # # ]: 0 : else if (width == 2)
1165 : 0 : val = GETINTX(uint16_t, fragment->buf, i);
1166 [ # # ]: 0 : else if (width == 3)
1167 : 0 : val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
1168 : : else {
1169 : : assert(width == 4);
1170 : 0 : val = GETINTX(uint32_t, fragment->buf, i);
1171 : : }
1172 : :
1173 : 0 : val += (unsigned int)bias;
1174 : : /* wrap around in case of overflow */
1175 : 0 : val &= mask;
1176 : :
1177 [ # # ]: 0 : if (width == 1)
1178 : 0 : SETINTX(unsigned char, ncp, i, val);
1179 [ # # ]: 0 : else if (width == 2)
1180 : 0 : SETINTX(uint16_t, ncp, i, val);
1181 [ # # ]: 0 : else if (width == 3)
1182 : 0 : SETINT24(ncp, i, (int)val);
1183 : : else {
1184 : : assert(width == 4);
1185 : 0 : SETINTX(uint32_t, ncp, i, val);
1186 : : }
1187 : : }
1188 : 0 : return rv;
1189 : : }
1190 : :
1191 : : /*[clinic input]
1192 : : audioop.reverse
1193 : :
1194 : : fragment: Py_buffer
1195 : : width: int
1196 : : /
1197 : :
1198 : : Reverse the samples in a fragment and returns the modified fragment.
1199 : : [clinic start generated code]*/
1200 : :
1201 : : static PyObject *
1202 : 0 : audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
1203 : : /*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/
1204 : : {
1205 : : unsigned char *ncp;
1206 : : Py_ssize_t i;
1207 : : PyObject *rv;
1208 : :
1209 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1210 : 0 : return NULL;
1211 : :
1212 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len);
1213 [ # # ]: 0 : if (rv == NULL)
1214 : 0 : return NULL;
1215 : 0 : ncp = (unsigned char *)PyBytes_AsString(rv);
1216 : :
1217 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1218 [ # # # # : 0 : int val = GETRAWSAMPLE(width, fragment->buf, i);
# # ]
1219 [ # # # # : 0 : SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
# # ]
1220 : : }
1221 : 0 : return rv;
1222 : : }
1223 : :
1224 : : /*[clinic input]
1225 : : audioop.byteswap
1226 : :
1227 : : fragment: Py_buffer
1228 : : width: int
1229 : : /
1230 : :
1231 : : Convert big-endian samples to little-endian and vice versa.
1232 : : [clinic start generated code]*/
1233 : :
1234 : : static PyObject *
1235 : 0 : audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
1236 : : /*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
1237 : : {
1238 : : unsigned char *ncp;
1239 : : Py_ssize_t i;
1240 : : PyObject *rv;
1241 : :
1242 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1243 : 0 : return NULL;
1244 : :
1245 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len);
1246 [ # # ]: 0 : if (rv == NULL)
1247 : 0 : return NULL;
1248 : 0 : ncp = (unsigned char *)PyBytes_AsString(rv);
1249 : :
1250 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1251 : : int j;
1252 [ # # ]: 0 : for (j = 0; j < width; j++)
1253 : 0 : ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
1254 : : }
1255 : 0 : return rv;
1256 : : }
1257 : :
1258 : : /*[clinic input]
1259 : : audioop.lin2lin
1260 : :
1261 : : fragment: Py_buffer
1262 : : width: int
1263 : : newwidth: int
1264 : : /
1265 : :
1266 : : Convert samples between 1-, 2-, 3- and 4-byte formats.
1267 : : [clinic start generated code]*/
1268 : :
1269 : : static PyObject *
1270 : 0 : audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
1271 : : int newwidth)
1272 : : /*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/
1273 : : {
1274 : : unsigned char *ncp;
1275 : : Py_ssize_t i, j;
1276 : : PyObject *rv;
1277 : :
1278 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1279 : 0 : return NULL;
1280 [ # # ]: 0 : if (!audioop_check_size(module, newwidth))
1281 : 0 : return NULL;
1282 : :
1283 [ # # ]: 0 : if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
1284 : 0 : PyErr_SetString(PyExc_MemoryError,
1285 : : "not enough memory for output buffer");
1286 : 0 : return NULL;
1287 : : }
1288 : 0 : rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
1289 [ # # ]: 0 : if (rv == NULL)
1290 : 0 : return NULL;
1291 : 0 : ncp = (unsigned char *)PyBytes_AsString(rv);
1292 : :
1293 [ # # ]: 0 : for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1294 [ # # # # : 0 : int val = GETSAMPLE32(width, fragment->buf, i);
# # ]
1295 [ # # # # : 0 : SETSAMPLE32(newwidth, ncp, j, val);
# # ]
1296 : : }
1297 : 0 : return rv;
1298 : : }
1299 : :
1300 : : static int
1301 : 0 : gcd(int a, int b)
1302 : : {
1303 [ # # ]: 0 : while (b > 0) {
1304 : 0 : int tmp = a % b;
1305 : 0 : a = b;
1306 : 0 : b = tmp;
1307 : : }
1308 : 0 : return a;
1309 : : }
1310 : :
1311 : : /*[clinic input]
1312 : : audioop.ratecv
1313 : :
1314 : : fragment: Py_buffer
1315 : : width: int
1316 : : nchannels: int
1317 : : inrate: int
1318 : : outrate: int
1319 : : state: object
1320 : : weightA: int = 1
1321 : : weightB: int = 0
1322 : : /
1323 : :
1324 : : Convert the frame rate of the input fragment.
1325 : : [clinic start generated code]*/
1326 : :
1327 : : static PyObject *
1328 : 0 : audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
1329 : : int nchannels, int inrate, int outrate, PyObject *state,
1330 : : int weightA, int weightB)
1331 : : /*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/
1332 : : {
1333 : : char *cp, *ncp;
1334 : : Py_ssize_t len;
1335 : : int chan, d, *prev_i, *cur_i, cur_o;
1336 : 0 : PyObject *samps, *str, *rv = NULL, *channel;
1337 : : int bytes_per_frame;
1338 : :
1339 [ # # ]: 0 : if (!audioop_check_size(module, width))
1340 : 0 : return NULL;
1341 [ # # ]: 0 : if (nchannels < 1) {
1342 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1343 : : "# of channels should be >= 1");
1344 : 0 : return NULL;
1345 : : }
1346 [ # # ]: 0 : if (width > INT_MAX / nchannels) {
1347 : : /* This overflow test is rigorously correct because
1348 : : both multiplicands are >= 1. Use the argument names
1349 : : from the docs for the error msg. */
1350 : 0 : PyErr_SetString(PyExc_OverflowError,
1351 : : "width * nchannels too big for a C int");
1352 : 0 : return NULL;
1353 : : }
1354 : 0 : bytes_per_frame = width * nchannels;
1355 [ # # # # ]: 0 : if (weightA < 1 || weightB < 0) {
1356 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1357 : : "weightA should be >= 1, weightB should be >= 0");
1358 : 0 : return NULL;
1359 : : }
1360 : : assert(fragment->len >= 0);
1361 [ # # ]: 0 : if (fragment->len % bytes_per_frame != 0) {
1362 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1363 : : "not a whole number of frames");
1364 : 0 : return NULL;
1365 : : }
1366 [ # # # # ]: 0 : if (inrate <= 0 || outrate <= 0) {
1367 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1368 : : "sampling rate not > 0");
1369 : 0 : return NULL;
1370 : : }
1371 : : /* divide inrate and outrate by their greatest common divisor */
1372 : 0 : d = gcd(inrate, outrate);
1373 : 0 : inrate /= d;
1374 : 0 : outrate /= d;
1375 : : /* divide weightA and weightB by their greatest common divisor */
1376 : 0 : d = gcd(weightA, weightB);
1377 : 0 : weightA /= d;
1378 : 0 : weightB /= d;
1379 : :
1380 [ # # ]: 0 : if ((size_t)nchannels > SIZE_MAX/sizeof(int)) {
1381 : 0 : PyErr_SetString(PyExc_MemoryError,
1382 : : "not enough memory for output buffer");
1383 : 0 : return NULL;
1384 : : }
1385 : 0 : prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1386 : 0 : cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1387 [ # # # # ]: 0 : if (prev_i == NULL || cur_i == NULL) {
1388 : 0 : (void) PyErr_NoMemory();
1389 : 0 : goto exit;
1390 : : }
1391 : :
1392 : 0 : len = fragment->len / bytes_per_frame; /* # of frames */
1393 : :
1394 [ # # ]: 0 : if (state == Py_None) {
1395 : 0 : d = -outrate;
1396 [ # # ]: 0 : for (chan = 0; chan < nchannels; chan++)
1397 : 0 : prev_i[chan] = cur_i[chan] = 0;
1398 : : }
1399 : : else {
1400 [ # # ]: 0 : if (!PyTuple_Check(state)) {
1401 : 0 : PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1402 : 0 : goto exit;
1403 : : }
1404 [ # # ]: 0 : if (!PyArg_ParseTuple(state,
1405 : : "iO!;ratecv(): illegal state argument",
1406 : : &d, &PyTuple_Type, &samps))
1407 : 0 : goto exit;
1408 [ # # ]: 0 : if (PyTuple_Size(samps) != nchannels) {
1409 : 0 : PyErr_SetString(get_audioop_state(module)->AudioopError,
1410 : : "illegal state argument");
1411 : 0 : goto exit;
1412 : : }
1413 [ # # ]: 0 : for (chan = 0; chan < nchannels; chan++) {
1414 : 0 : channel = PyTuple_GetItem(samps, chan);
1415 [ # # ]: 0 : if (!PyTuple_Check(channel)) {
1416 : 0 : PyErr_SetString(PyExc_TypeError,
1417 : : "ratecv(): illegal state argument");
1418 : 0 : goto exit;
1419 : : }
1420 [ # # ]: 0 : if (!PyArg_ParseTuple(channel,
1421 : : "ii;ratecv(): illegal state argument",
1422 : 0 : &prev_i[chan], &cur_i[chan]))
1423 : : {
1424 : 0 : goto exit;
1425 : : }
1426 : : }
1427 : : }
1428 : :
1429 : : /* str <- Space for the output buffer. */
1430 [ # # ]: 0 : if (len == 0)
1431 : 0 : str = PyBytes_FromStringAndSize(NULL, 0);
1432 : : else {
1433 : : /* There are len input frames, so we need (mathematically)
1434 : : ceiling(len*outrate/inrate) output frames, and each frame
1435 : : requires bytes_per_frame bytes. Computing this
1436 : : without spurious overflow is the challenge; we can
1437 : : settle for a reasonable upper bound, though, in this
1438 : : case ceiling(len/inrate) * outrate. */
1439 : :
1440 : : /* compute ceiling(len/inrate) without overflow */
1441 : 0 : Py_ssize_t q = 1 + (len - 1) / inrate;
1442 [ # # ]: 0 : if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
1443 : 0 : str = NULL;
1444 : : else
1445 : 0 : str = PyBytes_FromStringAndSize(NULL,
1446 : 0 : q * outrate * bytes_per_frame);
1447 : : }
1448 [ # # ]: 0 : if (str == NULL) {
1449 : 0 : PyErr_SetString(PyExc_MemoryError,
1450 : : "not enough memory for output buffer");
1451 : 0 : goto exit;
1452 : : }
1453 : 0 : ncp = PyBytes_AsString(str);
1454 : 0 : cp = fragment->buf;
1455 : :
1456 : : for (;;) {
1457 [ # # ]: 0 : while (d < 0) {
1458 [ # # ]: 0 : if (len == 0) {
1459 : 0 : samps = PyTuple_New(nchannels);
1460 [ # # ]: 0 : if (samps == NULL)
1461 : 0 : goto exit;
1462 [ # # ]: 0 : for (chan = 0; chan < nchannels; chan++)
1463 : 0 : PyTuple_SetItem(samps, chan,
1464 : : Py_BuildValue("(ii)",
1465 : 0 : prev_i[chan],
1466 : 0 : cur_i[chan]));
1467 [ # # ]: 0 : if (PyErr_Occurred())
1468 : 0 : goto exit;
1469 : : /* We have checked before that the length
1470 : : * of the string fits into int. */
1471 : 0 : len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
1472 : 0 : rv = PyBytes_FromStringAndSize
1473 : 0 : (PyBytes_AsString(str), len);
1474 : 0 : Py_SETREF(str, rv);
1475 [ # # ]: 0 : if (str == NULL)
1476 : 0 : goto exit;
1477 : 0 : rv = Py_BuildValue("(O(iO))", str, d, samps);
1478 : 0 : Py_DECREF(samps);
1479 : 0 : Py_DECREF(str);
1480 : 0 : goto exit; /* return rv */
1481 : : }
1482 [ # # ]: 0 : for (chan = 0; chan < nchannels; chan++) {
1483 : 0 : prev_i[chan] = cur_i[chan];
1484 [ # # # # : 0 : cur_i[chan] = GETSAMPLE32(width, cp, 0);
# # ]
1485 : 0 : cp += width;
1486 : : /* implements a simple digital filter */
1487 : 0 : cur_i[chan] = (int)(
1488 : 0 : ((double)weightA * (double)cur_i[chan] +
1489 : 0 : (double)weightB * (double)prev_i[chan]) /
1490 : 0 : ((double)weightA + (double)weightB));
1491 : : }
1492 : 0 : len--;
1493 : 0 : d += outrate;
1494 : : }
1495 [ # # ]: 0 : while (d >= 0) {
1496 [ # # ]: 0 : for (chan = 0; chan < nchannels; chan++) {
1497 : 0 : cur_o = (int)(((double)prev_i[chan] * (double)d +
1498 : 0 : (double)cur_i[chan] * (double)(outrate - d)) /
1499 : 0 : (double)outrate);
1500 [ # # # # : 0 : SETSAMPLE32(width, ncp, 0, cur_o);
# # ]
1501 : 0 : ncp += width;
1502 : : }
1503 : 0 : d -= inrate;
1504 : : }
1505 : : }
1506 : 0 : exit:
1507 : 0 : PyMem_Free(prev_i);
1508 : 0 : PyMem_Free(cur_i);
1509 : 0 : return rv;
1510 : : }
1511 : :
1512 : : /*[clinic input]
1513 : : audioop.lin2ulaw
1514 : :
1515 : : fragment: Py_buffer
1516 : : width: int
1517 : : /
1518 : :
1519 : : Convert samples in the audio fragment to u-LAW encoding.
1520 : : [clinic start generated code]*/
1521 : :
1522 : : static PyObject *
1523 : 0 : audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1524 : : /*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
1525 : : {
1526 : : unsigned char *ncp;
1527 : : Py_ssize_t i;
1528 : : PyObject *rv;
1529 : :
1530 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1531 : 0 : return NULL;
1532 : :
1533 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
1534 [ # # ]: 0 : if (rv == NULL)
1535 : 0 : return NULL;
1536 : 0 : ncp = (unsigned char *)PyBytes_AsString(rv);
1537 : :
1538 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1539 [ # # # # : 0 : int val = GETSAMPLE32(width, fragment->buf, i);
# # ]
1540 : 0 : *ncp++ = st_14linear2ulaw(val >> 18);
1541 : : }
1542 : 0 : return rv;
1543 : : }
1544 : :
1545 : : /*[clinic input]
1546 : : audioop.ulaw2lin
1547 : :
1548 : : fragment: Py_buffer
1549 : : width: int
1550 : : /
1551 : :
1552 : : Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1553 : : [clinic start generated code]*/
1554 : :
1555 : : static PyObject *
1556 : 0 : audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1557 : : /*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
1558 : : {
1559 : : unsigned char *cp;
1560 : : signed char *ncp;
1561 : : Py_ssize_t i;
1562 : : PyObject *rv;
1563 : :
1564 [ # # ]: 0 : if (!audioop_check_size(module, width))
1565 : 0 : return NULL;
1566 : :
1567 [ # # ]: 0 : if (fragment->len > PY_SSIZE_T_MAX/width) {
1568 : 0 : PyErr_SetString(PyExc_MemoryError,
1569 : : "not enough memory for output buffer");
1570 : 0 : return NULL;
1571 : : }
1572 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
1573 [ # # ]: 0 : if (rv == NULL)
1574 : 0 : return NULL;
1575 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
1576 : :
1577 : 0 : cp = fragment->buf;
1578 [ # # ]: 0 : for (i = 0; i < fragment->len*width; i += width) {
1579 : 0 : int val = st_ulaw2linear16(*cp++) * (1 << 16);
1580 [ # # # # : 0 : SETSAMPLE32(width, ncp, i, val);
# # ]
1581 : : }
1582 : 0 : return rv;
1583 : : }
1584 : :
1585 : : /*[clinic input]
1586 : : audioop.lin2alaw
1587 : :
1588 : : fragment: Py_buffer
1589 : : width: int
1590 : : /
1591 : :
1592 : : Convert samples in the audio fragment to a-LAW encoding.
1593 : : [clinic start generated code]*/
1594 : :
1595 : : static PyObject *
1596 : 0 : audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1597 : : /*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
1598 : : {
1599 : : unsigned char *ncp;
1600 : : Py_ssize_t i;
1601 : : PyObject *rv;
1602 : :
1603 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1604 : 0 : return NULL;
1605 : :
1606 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
1607 [ # # ]: 0 : if (rv == NULL)
1608 : 0 : return NULL;
1609 : 0 : ncp = (unsigned char *)PyBytes_AsString(rv);
1610 : :
1611 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1612 [ # # # # : 0 : int val = GETSAMPLE32(width, fragment->buf, i);
# # ]
1613 : 0 : *ncp++ = st_linear2alaw(val >> 19);
1614 : : }
1615 : 0 : return rv;
1616 : : }
1617 : :
1618 : : /*[clinic input]
1619 : : audioop.alaw2lin
1620 : :
1621 : : fragment: Py_buffer
1622 : : width: int
1623 : : /
1624 : :
1625 : : Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1626 : : [clinic start generated code]*/
1627 : :
1628 : : static PyObject *
1629 : 0 : audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1630 : : /*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
1631 : : {
1632 : : unsigned char *cp;
1633 : : signed char *ncp;
1634 : : Py_ssize_t i;
1635 : : int val;
1636 : : PyObject *rv;
1637 : :
1638 [ # # ]: 0 : if (!audioop_check_size(module, width))
1639 : 0 : return NULL;
1640 : :
1641 [ # # ]: 0 : if (fragment->len > PY_SSIZE_T_MAX/width) {
1642 : 0 : PyErr_SetString(PyExc_MemoryError,
1643 : : "not enough memory for output buffer");
1644 : 0 : return NULL;
1645 : : }
1646 : 0 : rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
1647 [ # # ]: 0 : if (rv == NULL)
1648 : 0 : return NULL;
1649 : 0 : ncp = (signed char *)PyBytes_AsString(rv);
1650 : 0 : cp = fragment->buf;
1651 : :
1652 [ # # ]: 0 : for (i = 0; i < fragment->len*width; i += width) {
1653 : 0 : val = st_alaw2linear16(*cp++) * (1 << 16);
1654 [ # # # # : 0 : SETSAMPLE32(width, ncp, i, val);
# # ]
1655 : : }
1656 : 0 : return rv;
1657 : : }
1658 : :
1659 : : /*[clinic input]
1660 : : audioop.lin2adpcm
1661 : :
1662 : : fragment: Py_buffer
1663 : : width: int
1664 : : state: object
1665 : : /
1666 : :
1667 : : Convert samples to 4 bit Intel/DVI ADPCM encoding.
1668 : : [clinic start generated code]*/
1669 : :
1670 : : static PyObject *
1671 : 0 : audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
1672 : : PyObject *state)
1673 : : /*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
1674 : : {
1675 : : signed char *ncp;
1676 : : Py_ssize_t i;
1677 : : int step, valpred, delta,
1678 : : index, sign, vpdiff, diff;
1679 : 0 : PyObject *rv = NULL, *str;
1680 : 0 : int outputbuffer = 0, bufferstep;
1681 : :
1682 [ # # ]: 0 : if (!audioop_check_parameters(module, fragment->len, width))
1683 : 0 : return NULL;
1684 : :
1685 : : /* Decode state, should have (value, step) */
1686 [ # # ]: 0 : if ( state == Py_None ) {
1687 : : /* First time, it seems. Set defaults */
1688 : 0 : valpred = 0;
1689 : 0 : index = 0;
1690 : : }
1691 [ # # ]: 0 : else if (!PyTuple_Check(state)) {
1692 : 0 : PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1693 : 0 : return NULL;
1694 : : }
1695 [ # # ]: 0 : else if (!PyArg_ParseTuple(state, "ii;lin2adpcm(): illegal state argument",
1696 : : &valpred, &index))
1697 : : {
1698 : 0 : return NULL;
1699 : : }
1700 [ # # # # ]: 0 : else if (valpred >= 0x8000 || valpred < -0x8000 ||
1701 [ # # ]: 0 : (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1702 : 0 : PyErr_SetString(PyExc_ValueError, "bad state");
1703 : 0 : return NULL;
1704 : : }
1705 : :
1706 : 0 : str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1707 [ # # ]: 0 : if (str == NULL)
1708 : 0 : return NULL;
1709 : 0 : ncp = (signed char *)PyBytes_AsString(str);
1710 : :
1711 : 0 : step = stepsizeTable[index];
1712 : 0 : bufferstep = 1;
1713 : :
1714 [ # # ]: 0 : for (i = 0; i < fragment->len; i += width) {
1715 [ # # # # : 0 : int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
# # ]
1716 : :
1717 : : /* Step 1 - compute difference with previous value */
1718 [ # # ]: 0 : if (val < valpred) {
1719 : 0 : diff = valpred - val;
1720 : 0 : sign = 8;
1721 : : }
1722 : : else {
1723 : 0 : diff = val - valpred;
1724 : 0 : sign = 0;
1725 : : }
1726 : :
1727 : : /* Step 2 - Divide and clamp */
1728 : : /* Note:
1729 : : ** This code *approximately* computes:
1730 : : ** delta = diff*4/step;
1731 : : ** vpdiff = (delta+0.5)*step/4;
1732 : : ** but in shift step bits are dropped. The net result of this
1733 : : ** is that even if you have fast mul/div hardware you cannot
1734 : : ** put it to good use since the fixup would be too expensive.
1735 : : */
1736 : 0 : delta = 0;
1737 : 0 : vpdiff = (step >> 3);
1738 : :
1739 [ # # ]: 0 : if ( diff >= step ) {
1740 : 0 : delta = 4;
1741 : 0 : diff -= step;
1742 : 0 : vpdiff += step;
1743 : : }
1744 : 0 : step >>= 1;
1745 [ # # ]: 0 : if ( diff >= step ) {
1746 : 0 : delta |= 2;
1747 : 0 : diff -= step;
1748 : 0 : vpdiff += step;
1749 : : }
1750 : 0 : step >>= 1;
1751 [ # # ]: 0 : if ( diff >= step ) {
1752 : 0 : delta |= 1;
1753 : 0 : vpdiff += step;
1754 : : }
1755 : :
1756 : : /* Step 3 - Update previous value */
1757 [ # # ]: 0 : if ( sign )
1758 : 0 : valpred -= vpdiff;
1759 : : else
1760 : 0 : valpred += vpdiff;
1761 : :
1762 : : /* Step 4 - Clamp previous value to 16 bits */
1763 [ # # ]: 0 : if ( valpred > 32767 )
1764 : 0 : valpred = 32767;
1765 [ # # ]: 0 : else if ( valpred < -32768 )
1766 : 0 : valpred = -32768;
1767 : :
1768 : : /* Step 5 - Assemble value, update index and step values */
1769 : 0 : delta |= sign;
1770 : :
1771 : 0 : index += indexTable[delta];
1772 [ # # ]: 0 : if ( index < 0 ) index = 0;
1773 [ # # ]: 0 : if ( index > 88 ) index = 88;
1774 : 0 : step = stepsizeTable[index];
1775 : :
1776 : : /* Step 6 - Output value */
1777 [ # # ]: 0 : if ( bufferstep ) {
1778 : 0 : outputbuffer = (delta * (1 << 4)) & 0xf0;
1779 : : } else {
1780 : 0 : *ncp++ = (delta & 0x0f) | outputbuffer;
1781 : : }
1782 : 0 : bufferstep = !bufferstep;
1783 : : }
1784 : 0 : rv = Py_BuildValue("(O(ii))", str, valpred, index);
1785 : 0 : Py_DECREF(str);
1786 : 0 : return rv;
1787 : : }
1788 : :
1789 : : /*[clinic input]
1790 : : audioop.adpcm2lin
1791 : :
1792 : : fragment: Py_buffer
1793 : : width: int
1794 : : state: object
1795 : : /
1796 : :
1797 : : Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1798 : : [clinic start generated code]*/
1799 : :
1800 : : static PyObject *
1801 : 0 : audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
1802 : : PyObject *state)
1803 : : /*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
1804 : : {
1805 : : signed char *cp;
1806 : : signed char *ncp;
1807 : : Py_ssize_t i, outlen;
1808 : : int valpred, step, delta, index, sign, vpdiff;
1809 : : PyObject *rv, *str;
1810 : 0 : int inputbuffer = 0, bufferstep;
1811 : :
1812 [ # # ]: 0 : if (!audioop_check_size(module, width))
1813 : 0 : return NULL;
1814 : :
1815 : : /* Decode state, should have (value, step) */
1816 [ # # ]: 0 : if ( state == Py_None ) {
1817 : : /* First time, it seems. Set defaults */
1818 : 0 : valpred = 0;
1819 : 0 : index = 0;
1820 : : }
1821 [ # # ]: 0 : else if (!PyTuple_Check(state)) {
1822 : 0 : PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1823 : 0 : return NULL;
1824 : : }
1825 [ # # ]: 0 : else if (!PyArg_ParseTuple(state, "ii;adpcm2lin(): illegal state argument",
1826 : : &valpred, &index))
1827 : : {
1828 : 0 : return NULL;
1829 : : }
1830 [ # # # # ]: 0 : else if (valpred >= 0x8000 || valpred < -0x8000 ||
1831 [ # # ]: 0 : (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1832 : 0 : PyErr_SetString(PyExc_ValueError, "bad state");
1833 : 0 : return NULL;
1834 : : }
1835 : :
1836 [ # # ]: 0 : if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
1837 : 0 : PyErr_SetString(PyExc_MemoryError,
1838 : : "not enough memory for output buffer");
1839 : 0 : return NULL;
1840 : : }
1841 : 0 : outlen = fragment->len*width*2;
1842 : 0 : str = PyBytes_FromStringAndSize(NULL, outlen);
1843 [ # # ]: 0 : if (str == NULL)
1844 : 0 : return NULL;
1845 : 0 : ncp = (signed char *)PyBytes_AsString(str);
1846 : 0 : cp = fragment->buf;
1847 : :
1848 : 0 : step = stepsizeTable[index];
1849 : 0 : bufferstep = 0;
1850 : :
1851 [ # # ]: 0 : for (i = 0; i < outlen; i += width) {
1852 : : /* Step 1 - get the delta value and compute next index */
1853 [ # # ]: 0 : if ( bufferstep ) {
1854 : 0 : delta = inputbuffer & 0xf;
1855 : : } else {
1856 : 0 : inputbuffer = *cp++;
1857 : 0 : delta = (inputbuffer >> 4) & 0xf;
1858 : : }
1859 : :
1860 : 0 : bufferstep = !bufferstep;
1861 : :
1862 : : /* Step 2 - Find new index value (for later) */
1863 : 0 : index += indexTable[delta];
1864 [ # # ]: 0 : if ( index < 0 ) index = 0;
1865 [ # # ]: 0 : if ( index > 88 ) index = 88;
1866 : :
1867 : : /* Step 3 - Separate sign and magnitude */
1868 : 0 : sign = delta & 8;
1869 : 0 : delta = delta & 7;
1870 : :
1871 : : /* Step 4 - Compute difference and new predicted value */
1872 : : /*
1873 : : ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1874 : : ** in adpcm_coder.
1875 : : */
1876 : 0 : vpdiff = step >> 3;
1877 [ # # ]: 0 : if ( delta & 4 ) vpdiff += step;
1878 [ # # ]: 0 : if ( delta & 2 ) vpdiff += step>>1;
1879 [ # # ]: 0 : if ( delta & 1 ) vpdiff += step>>2;
1880 : :
1881 [ # # ]: 0 : if ( sign )
1882 : 0 : valpred -= vpdiff;
1883 : : else
1884 : 0 : valpred += vpdiff;
1885 : :
1886 : : /* Step 5 - clamp output value */
1887 [ # # ]: 0 : if ( valpred > 32767 )
1888 : 0 : valpred = 32767;
1889 [ # # ]: 0 : else if ( valpred < -32768 )
1890 : 0 : valpred = -32768;
1891 : :
1892 : : /* Step 6 - Update step value */
1893 : 0 : step = stepsizeTable[index];
1894 : :
1895 : : /* Step 6 - Output value */
1896 [ # # # # : 0 : SETSAMPLE32(width, ncp, i, valpred * (1 << 16));
# # ]
1897 : : }
1898 : :
1899 : 0 : rv = Py_BuildValue("(O(ii))", str, valpred, index);
1900 : 0 : Py_DECREF(str);
1901 : 0 : return rv;
1902 : : }
1903 : :
1904 : : #include "clinic/audioop.c.h"
1905 : :
1906 : : static PyMethodDef audioop_methods[] = {
1907 : : AUDIOOP_MAX_METHODDEF
1908 : : AUDIOOP_MINMAX_METHODDEF
1909 : : AUDIOOP_AVG_METHODDEF
1910 : : AUDIOOP_MAXPP_METHODDEF
1911 : : AUDIOOP_AVGPP_METHODDEF
1912 : : AUDIOOP_RMS_METHODDEF
1913 : : AUDIOOP_FINDFIT_METHODDEF
1914 : : AUDIOOP_FINDMAX_METHODDEF
1915 : : AUDIOOP_FINDFACTOR_METHODDEF
1916 : : AUDIOOP_CROSS_METHODDEF
1917 : : AUDIOOP_MUL_METHODDEF
1918 : : AUDIOOP_ADD_METHODDEF
1919 : : AUDIOOP_BIAS_METHODDEF
1920 : : AUDIOOP_ULAW2LIN_METHODDEF
1921 : : AUDIOOP_LIN2ULAW_METHODDEF
1922 : : AUDIOOP_ALAW2LIN_METHODDEF
1923 : : AUDIOOP_LIN2ALAW_METHODDEF
1924 : : AUDIOOP_LIN2LIN_METHODDEF
1925 : : AUDIOOP_ADPCM2LIN_METHODDEF
1926 : : AUDIOOP_LIN2ADPCM_METHODDEF
1927 : : AUDIOOP_TOMONO_METHODDEF
1928 : : AUDIOOP_TOSTEREO_METHODDEF
1929 : : AUDIOOP_GETSAMPLE_METHODDEF
1930 : : AUDIOOP_REVERSE_METHODDEF
1931 : : AUDIOOP_BYTESWAP_METHODDEF
1932 : : AUDIOOP_RATECV_METHODDEF
1933 : : { 0, 0 }
1934 : : };
1935 : :
1936 : : static int
1937 : 6 : audioop_traverse(PyObject *module, visitproc visit, void *arg)
1938 : : {
1939 : 6 : audioop_state *state = get_audioop_state(module);
1940 [ + - - + ]: 6 : Py_VISIT(state->AudioopError);
1941 : 6 : return 0;
1942 : : }
1943 : :
1944 : : static int
1945 : 2 : audioop_clear(PyObject *module)
1946 : : {
1947 : 2 : audioop_state *state = get_audioop_state(module);
1948 [ + + ]: 2 : Py_CLEAR(state->AudioopError);
1949 : 2 : return 0;
1950 : : }
1951 : :
1952 : : static void
1953 : 1 : audioop_free(void *module) {
1954 : 1 : audioop_clear((PyObject *)module);
1955 : 1 : }
1956 : :
1957 : : static int
1958 : 1 : audioop_exec(PyObject* module)
1959 : : {
1960 : 1 : audioop_state *state = get_audioop_state(module);
1961 : :
1962 : 1 : state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1963 [ - + ]: 1 : if (state->AudioopError == NULL) {
1964 : 0 : return -1;
1965 : : }
1966 : :
1967 : 1 : Py_INCREF(state->AudioopError);
1968 [ - + ]: 1 : if (PyModule_AddObject(module, "error", state->AudioopError) < 0) {
1969 : 0 : Py_DECREF(state->AudioopError);
1970 : 0 : return -1;
1971 : : }
1972 : :
1973 : 1 : return 0;
1974 : : }
1975 : :
1976 : : static PyModuleDef_Slot audioop_slots[] = {
1977 : : {Py_mod_exec, audioop_exec},
1978 : : {0, NULL}
1979 : : };
1980 : :
1981 : : static struct PyModuleDef audioopmodule = {
1982 : : PyModuleDef_HEAD_INIT,
1983 : : "audioop",
1984 : : NULL,
1985 : : sizeof(audioop_state),
1986 : : audioop_methods,
1987 : : audioop_slots,
1988 : : audioop_traverse,
1989 : : audioop_clear,
1990 : : audioop_free
1991 : : };
1992 : :
1993 : : PyMODINIT_FUNC
1994 : 1 : PyInit_audioop(void)
1995 : : {
1996 [ - + ]: 1 : if (PyErr_WarnEx(PyExc_DeprecationWarning,
1997 : : "'audioop' is deprecated and slated for removal in "
1998 : : "Python 3.13",
1999 : : 7)) {
2000 : 0 : return NULL;
2001 : : }
2002 : :
2003 : 1 : return PyModuleDef_Init(&audioopmodule);
2004 : : }
|