1 #ifndef STANDALONE
2 #include <Python.h>
3 #include "mod_defs.h"
4 #endif
5 #include <stdlib.h>
6 
7 /********************************************************
8  Audio Tools, a module and set of tools for manipulating audio data
9  Copyright (C) 2007-2014  Brian Langenberger
10 
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 *******************************************************/
25 
26 #include "pcm.h"
27 
28 #ifndef MIN
29 #define MIN(x, y) ((x) < (y) ? (x) : (y))
30 #endif
31 #ifndef MAX
32 #define MAX(x, y) ((x) > (y) ? (x) : (y))
33 #endif
34 
35 #ifndef STANDALONE
36 
37 #if PY_MAJOR_VERSION >= 3
38 #ifndef PyInt_AsLong
39 #define PyInt_AsLong PyLong_AsLong
40 #endif
41 #endif
42 
43 PyMethodDef module_methods[] = {
44     {"empty_framelist", (PyCFunction)FrameList_empty,
45      METH_VARARGS, "empty_framelist(channels, bits_per_sample) -> FrameList"},
46     {"from_list", (PyCFunction)FrameList_from_list,
47      METH_VARARGS,
48      "from_list(int_list, channels, bits_per_sample, is_signed) -> FrameList"},
49     {"from_frames", (PyCFunction)FrameList_from_frames,
50      METH_VARARGS,
51      "from_frames(framelist_list) -> FrameList"},
52     {"from_channels", (PyCFunction)FrameList_from_channels,
53      METH_VARARGS,
54      "from_channels(framelist_list) -> FrameList"},
55     {"empty_float_framelist", (PyCFunction)FloatFrameList_empty,
56      METH_VARARGS, "empty_float_framelist(channels) -> FloatFrameList"},
57     {"from_float_frames", (PyCFunction)FloatFrameList_from_frames,
58      METH_VARARGS,
59      "from_float_frames(floatframelist_list) -> FloatFrameList"},
60     {"from_float_channels", (PyCFunction)FloatFrameList_from_channels,
61      METH_VARARGS,
62      "from_float_channels(floatframelist_list) -> FloatFrameList"},
63     {NULL}
64 };
65 
66 /******************
67   FrameList Object
68 *******************/
69 
70 PyGetSetDef FrameList_getseters[] = {
71     {"frames", (getter)FrameList_frames,
72      0, "frame count", NULL},
73     {"channels", (getter)FrameList_channels,
74      0, "channel count", NULL},
75     {"bits_per_sample", (getter)FrameList_bits_per_sample,
76      0, "bits per sample", NULL},
77     {NULL}  /* Sentinel */
78 };
79 
80 PyMethodDef FrameList_methods[] = {
81     {"frame", (PyCFunction)FrameList_frame,
82      METH_VARARGS,
83      "F.frame(i) -> FrameList -- return the given PCM frame"},
84     {"channel", (PyCFunction)FrameList_channel,
85      METH_VARARGS,
86      "F.channel(i) -> FrameList -- return the given channel"},
87     {"to_bytes", (PyCFunction)FrameList_to_bytes,
88      METH_VARARGS,
89      "F.to_bytes(is_big_endian, is_signed) -> string"},
90     {"split", (PyCFunction)FrameList_split,
91      METH_VARARGS,
92      "F.split(i) -> (FrameList,FrameList) -- "
93      "splits the FrameList at the given index"},
94     {"to_float", (PyCFunction)FrameList_to_float,
95      METH_NOARGS,
96      "F.to_float() -> FloatFrameList"},
97     {"from_list", (PyCFunction)FrameList_from_list,
98      METH_VARARGS | METH_CLASS,
99      "FrameList.from_list(int_list, channels, bits_per_sample, is_signed) -> FrameList"
100     },
101     {"from_frames", (PyCFunction)FrameList_from_frames,
102      METH_VARARGS | METH_CLASS,
103      "FrameList.from_frames(framelist_list) -> FrameList"},
104     {"from_channels", (PyCFunction)FrameList_from_channels,
105      METH_VARARGS | METH_CLASS,
106      "FrameList.from_channels(framelist_list) -> FrameList"},
107     {"frame_count", (PyCFunction)FrameList_frame_count,
108      METH_VARARGS,
109      "F.frame_count(bytes) -> int -- "
110      "given a number of bytes, returns the maximum number of frames "
111      "that would fit or a minimum of 1"},
112     {NULL}
113 };
114 
115 static PySequenceMethods pcm_FrameListType_as_sequence = {
116     (lenfunc)FrameList_len,          /* sq_length */
117     (binaryfunc)FrameList_concat,    /* sq_concat */
118     (ssizeargfunc)FrameList_repeat,  /* sq_repeat */
119     (ssizeargfunc)FrameList_GetItem, /* sq_item */
120     (ssizessizeargfunc)NULL,         /* sq_slice */
121     (ssizeobjargproc)NULL,           /* sq_ass_item */
122     (ssizessizeobjargproc)NULL,      /* sq_ass_slice */
123     (objobjproc)NULL,                /* sq_contains */
124     (binaryfunc)FrameList_inplace_concat,   /* sq_inplace_concat */
125     (ssizeargfunc)FrameList_inplace_repeat, /* sq_inplace_repeat */
126 };
127 
128 PyTypeObject pcm_FrameListType = {
129     PyVarObject_HEAD_INIT(NULL, 0)
130     "pcm.FrameList",           /*tp_name*/
131     sizeof(pcm_FrameList),     /*tp_basicsize*/
132     0,                         /*tp_itemsize*/
133     (destructor)FrameList_dealloc, /*tp_dealloc*/
134     0,                         /*tp_print*/
135     0,                         /*tp_getattr*/
136     0,                         /*tp_setattr*/
137     0,                         /*tp_compare*/
138     0,                         /*tp_repr*/
139     0,                         /*tp_as_number*/
140     &pcm_FrameListType_as_sequence, /*tp_as_sequence*/
141     0,                         /*tp_as_mapping*/
142     0,                         /*tp_hash */
143     0,                         /*tp_call*/
144     0,                         /*tp_str*/
145     0,                         /*tp_getattro*/
146     0,                         /*tp_setattro*/
147     0,                         /*tp_as_buffer*/
148     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
149     "FrameList(string, channels, bits_per_sample, is_big_endian, is_signed)",
150     /* tp_doc */
151     0,                         /* tp_traverse */
152     0,                         /* tp_clear */
153     (richcmpfunc)FrameList_richcompare, /* tp_richcompare */
154     0,                         /* tp_weaklistoffset */
155     0,                         /* tp_iter */
156     0,                         /* tp_iternext */
157     FrameList_methods,         /* tp_methods */
158     0,                         /* tp_members */
159     FrameList_getseters,       /* tp_getset */
160     0,                         /* tp_base */
161     0,                         /* tp_dict */
162     0,                         /* tp_descr_get */
163     0,                         /* tp_descr_set */
164     0,                         /* tp_dictoffset */
165     (initproc)FrameList_init,  /* tp_init */
166     0,                         /* tp_alloc */
167     FrameList_new,             /* tp_new */
168 };
169 
170 
171 void
FrameList_dealloc(pcm_FrameList * self)172 FrameList_dealloc(pcm_FrameList* self)
173 {
174     PyMem_Free(self->samples);
175     Py_TYPE(self)->tp_free((PyObject*)self);
176 }
177 
178 PyObject*
FrameList_new(PyTypeObject * type,PyObject * args,PyObject * kwds)179 FrameList_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
180 {
181     pcm_FrameList *self;
182 
183     self = (pcm_FrameList *)type->tp_alloc(type, 0);
184 
185     return (PyObject *)self;
186 }
187 
188 int
FrameList_init(pcm_FrameList * self,PyObject * args,PyObject * kwds)189 FrameList_init(pcm_FrameList *self, PyObject *args, PyObject *kwds)
190 {
191     unsigned char *data;
192 #ifdef PY_SSIZE_T_CLEAN
193     Py_ssize_t data_size;
194 #else
195     int data_size;
196 #endif
197     int is_big_endian;
198     int is_signed;
199     FrameList_char_to_int_converter converter;
200 
201     if (!PyArg_ParseTuple(args, "s#IIii",
202                           &data, &data_size,
203                           &(self->channels),
204                           &(self->bits_per_sample),
205                           &(is_big_endian),
206                           &is_signed))
207         return -1;
208 
209     if (self->channels < 1) {
210         PyErr_SetString(PyExc_ValueError,
211                         "number of channels must be > 0");
212         return -1;
213     } else if ((self->bits_per_sample != 16) &&
214                (self->bits_per_sample != 24) &&
215                (self->bits_per_sample != 8)) {
216         PyErr_SetString(PyExc_ValueError,
217                         "bits_per_sample must be 8, 16 or 24");
218         return -1;
219     } else if (data_size % (self->channels * self->bits_per_sample / 8)) {
220         PyErr_SetString(PyExc_ValueError,
221                         "number of samples must be divisible by "
222                         "bits-per-sample and number of channels");
223         return -1;
224     } else {
225         self->samples_length = data_size / (self->bits_per_sample / 8);
226         self->frames = self->samples_length / self->channels;
227         self->samples = PyMem_Malloc(sizeof(int) * self->samples_length);
228         converter = FrameList_get_char_to_int_converter(self->bits_per_sample,
229                                                         is_big_endian,
230                                                         is_signed);
231         if (converter) {
232             FrameList_char_to_samples(self->samples,
233                                       data,
234                                       converter,
235                                       self->samples_length,
236                                       self->bits_per_sample);
237         } else {
238             PyErr_SetString(PyExc_ValueError,
239                             "unsupported number of bits per sample");
240             return -1;
241         }
242     }
243 
244     return 0;
245 }
246 
247 pcm_FrameList*
FrameList_create(void)248 FrameList_create(void)
249 {
250     return (pcm_FrameList*)_PyObject_New(&pcm_FrameListType);
251 }
252 
253 PyObject*
FrameList_empty(PyObject * dummy,PyObject * args)254 FrameList_empty(PyObject *dummy, PyObject *args)
255 {
256     int channels;
257     int bits_per_sample;
258     pcm_FrameList *framelist;
259 
260     if (!PyArg_ParseTuple(args, "ii", &channels, &bits_per_sample)) {
261         return NULL;
262     }
263 
264     if (channels <= 0) {
265         PyErr_SetString(PyExc_ValueError, "channels must be > 0");
266         return NULL;
267     }
268     if ((bits_per_sample != 8) &&
269         (bits_per_sample != 16) &&
270         (bits_per_sample != 24)) {
271         PyErr_SetString(PyExc_ValueError,
272                         "bits_per_sample must be 8, 16 or 24");
273         return NULL;
274     }
275 
276     framelist = FrameList_create();
277     framelist->frames = 0;
278     framelist->channels = (unsigned)channels;
279     framelist->bits_per_sample = (unsigned)bits_per_sample;
280     framelist->samples = NULL;
281     framelist->samples_length = 0;
282 
283     return (PyObject*)framelist;
284 }
285 
286 int
FrameList_CheckExact(PyObject * o)287 FrameList_CheckExact(PyObject *o)
288 {
289     return Py_TYPE(o) == &pcm_FrameListType;
290 }
291 
292 PyObject*
FrameList_frames(pcm_FrameList * self,void * closure)293 FrameList_frames(pcm_FrameList *self, void* closure)
294 {
295     return Py_BuildValue("i", self->frames);
296 }
297 
298 PyObject*
FrameList_channels(pcm_FrameList * self,void * closure)299 FrameList_channels(pcm_FrameList *self, void* closure)
300 {
301     return Py_BuildValue("i", self->channels);
302 }
303 
304 PyObject*
FrameList_bits_per_sample(pcm_FrameList * self,void * closure)305 FrameList_bits_per_sample(pcm_FrameList *self, void* closure)
306 {
307     return Py_BuildValue("i", self->bits_per_sample);
308 }
309 
310 Py_ssize_t
FrameList_len(pcm_FrameList * o)311 FrameList_len(pcm_FrameList *o)
312 {
313     return o->samples_length;
314 }
315 
316 PyObject
FrameList_richcompare(PyObject * a,PyObject * b,int op)317 *FrameList_richcompare(PyObject *a, PyObject *b, int op)
318 {
319     switch (op) {
320     case Py_EQ:
321         if (FrameList_CheckExact(a) && FrameList_CheckExact(b) &&
322             FrameList_equals((pcm_FrameList*)a, (pcm_FrameList*)b)) {
323             Py_INCREF(Py_True);
324             return Py_True;
325         } else {
326             Py_INCREF(Py_False);
327             return Py_False;
328         }
329     case Py_NE:
330         if (FrameList_CheckExact(a) && FrameList_CheckExact(b) &&
331             FrameList_equals((pcm_FrameList*)a, (pcm_FrameList*)b)) {
332             Py_INCREF(Py_False);
333             return Py_False;
334         } else {
335             Py_INCREF(Py_True);
336             return Py_True;
337         }
338     default:
339         PyErr_SetString(PyExc_TypeError, "unsupported comparison");
340         return NULL;
341     }
342 }
343 
344 int
FrameList_equals(pcm_FrameList * a,pcm_FrameList * b)345 FrameList_equals(pcm_FrameList *a, pcm_FrameList *b)
346 {
347     return ((a->frames == b->frames) &&
348             (a->channels == b->channels) &&
349             (a->bits_per_sample == b->bits_per_sample) &&
350             (a->samples_length == b->samples_length) &&
351             (memcmp(a->samples,
352                     b->samples,
353                     sizeof(int) * a->samples_length) == 0));
354 }
355 
356 PyObject*
FrameList_GetItem(pcm_FrameList * o,Py_ssize_t i)357 FrameList_GetItem(pcm_FrameList *o, Py_ssize_t i)
358 {
359     if ((i >= 0) && (i < o->samples_length)) {
360         return Py_BuildValue("i", o->samples[i]);
361     } else {
362         PyErr_SetString(PyExc_IndexError, "index out of range");
363         return NULL;
364     }
365 }
366 
367 PyObject*
FrameList_frame(pcm_FrameList * self,PyObject * args)368 FrameList_frame(pcm_FrameList *self, PyObject *args)
369 {
370     int frame_number;
371     pcm_FrameList *frame;
372 
373     if (!PyArg_ParseTuple(args, "i", &frame_number))
374         return NULL;
375     if ((frame_number < 0) || (frame_number >= self->frames)) {
376         PyErr_SetString(PyExc_IndexError, "frame number out of range");
377         return NULL;
378     }
379 
380     frame = FrameList_create();
381     frame->frames = 1;
382     frame->channels = self->channels;
383     frame->bits_per_sample = self->bits_per_sample;
384     frame->samples = PyMem_Malloc(sizeof(int) * self->channels);
385     frame->samples_length = self->channels;
386     memcpy(frame->samples,
387            self->samples + (frame_number * self->channels),
388            sizeof(int) * self->channels);
389     return (PyObject*)frame;
390 }
391 
392 PyObject*
FrameList_channel(pcm_FrameList * self,PyObject * args)393 FrameList_channel(pcm_FrameList *self, PyObject *args)
394 {
395     int channel_number;
396     pcm_FrameList *channel;
397     unsigned i;
398 
399     if (!PyArg_ParseTuple(args, "i", &channel_number))
400         return NULL;
401     if ((channel_number < 0) || (channel_number >= self->channels)) {
402         PyErr_SetString(PyExc_IndexError, "channel number out of range");
403         return NULL;
404     }
405 
406     channel = FrameList_create();
407     channel->frames = self->frames;
408     channel->channels = 1;
409     channel->bits_per_sample = self->bits_per_sample;
410     channel->samples = PyMem_Malloc(sizeof(int) * self->frames);
411     channel->samples_length = self->frames;
412 
413     for (i = 0; i < self->frames; i++) {
414         channel->samples[i] = \
415             self->samples[channel_number + (i * self->channels)];
416     }
417 
418     return (PyObject*)channel;
419 }
420 
421 PyObject*
FrameList_to_bytes(pcm_FrameList * self,PyObject * args)422 FrameList_to_bytes(pcm_FrameList *self, PyObject *args)
423 {
424     int is_big_endian;
425     int is_signed;
426     PyObject *bytes_obj;
427     const Py_ssize_t bytes_size = ((self->bits_per_sample / 8) *
428                                    self->samples_length);
429 
430     if (!PyArg_ParseTuple(args, "ii", &is_big_endian, &is_signed)) {
431         return NULL;
432     } else if ((bytes_obj =
433                 PyBytes_FromStringAndSize(NULL, bytes_size)) == NULL) {
434         return NULL;
435     } else {
436         FrameList_samples_to_char(
437              (uint8_t*)PyBytes_AsString(bytes_obj),
438              self->samples,
439              FrameList_get_int_to_char_converter(self->bits_per_sample,
440                                                  is_big_endian,
441                                                  is_signed),
442              self->samples_length,
443              self->bits_per_sample);
444     }
445 
446     return bytes_obj;
447 }
448 
449 PyObject*
FrameList_split(pcm_FrameList * self,PyObject * args)450 FrameList_split(pcm_FrameList *self, PyObject *args)
451 {
452     pcm_FrameList *head;
453     pcm_FrameList *tail;
454     PyObject* tuple;
455     int split_point;
456 
457     if (!PyArg_ParseTuple(args, "i", &split_point)) {
458         return NULL;
459     }
460 
461     if (split_point < 0) {
462         PyErr_SetString(PyExc_IndexError, "split point must be >= 0");
463         return NULL;
464     } else if (split_point >= self->frames) {
465         head = self;
466         Py_INCREF(head);
467         tail = FrameList_create();
468         tail->frames = 0;
469         tail->channels = self->channels;
470         tail->bits_per_sample = self->bits_per_sample;
471         tail->samples_length = 0;
472         tail->samples = NULL;
473     } else if (split_point == 0) {
474         head = FrameList_create();
475         head->frames = 0;
476         head->channels = self->channels;
477         head->bits_per_sample = self->bits_per_sample;
478         head->samples_length = 0;
479         head->samples = NULL;
480         tail = self;
481         Py_INCREF(tail);
482     } else {
483         head = FrameList_create();
484         head->frames = split_point;
485         head->samples_length = (head->frames * self->channels);
486         head->samples = PyMem_Malloc(head->samples_length * sizeof(int));
487         memcpy(head->samples,
488                self->samples,
489                head->samples_length * sizeof(int));
490 
491         tail = FrameList_create();
492         tail->frames = (self->frames - split_point);
493         tail->samples_length = (tail->frames * self->channels);
494         tail->samples = PyMem_Malloc(tail->samples_length * sizeof(int));
495         memcpy(tail->samples,
496                self->samples + head->samples_length,
497                tail->samples_length * sizeof(int));
498 
499         head->channels = tail->channels = self->channels;
500         head->bits_per_sample = tail->bits_per_sample = self->bits_per_sample;
501     }
502 
503     tuple = Py_BuildValue("(O,O)", head, tail);
504     Py_DECREF(head);
505     Py_DECREF(tail);
506     return tuple;
507 }
508 
509 PyObject*
FrameList_concat(pcm_FrameList * a,PyObject * bb)510 FrameList_concat(pcm_FrameList *a, PyObject *bb)
511 {
512     pcm_FrameList *concat;
513     pcm_FrameList *b;
514 
515     if (FrameList_CheckExact(bb)) {
516         b = (pcm_FrameList*)bb;
517     } else {
518         PyErr_SetString(PyExc_TypeError,
519                         "can only concatenate FrameList with other FrameLists"
520                         );
521         return NULL;
522     }
523 
524     if (a->channels != b->channels) {
525         PyErr_SetString(PyExc_ValueError,
526                         "both FrameLists must have the same number of channels"
527                         );
528         return NULL;
529     }
530     if (a->bits_per_sample != b->bits_per_sample) {
531         PyErr_SetString(PyExc_ValueError,
532                         "both FrameLists must have the same number "
533                         "of bits per sample");
534         return NULL;
535     }
536 
537     concat = FrameList_create();
538     concat->frames = a->frames + b->frames;
539     concat->channels = a->channels;
540     concat->bits_per_sample = a->bits_per_sample;
541     concat->samples_length = a->samples_length + b->samples_length;
542     concat->samples = PyMem_Malloc(concat->samples_length * sizeof(int));
543     memcpy(concat->samples, a->samples, a->samples_length * sizeof(int));
544     memcpy(concat->samples + a->samples_length,
545            b->samples,
546            b->samples_length * sizeof(int));
547 
548     return (PyObject*)concat;
549 }
550 
551 PyObject*
FrameList_repeat(pcm_FrameList * a,Py_ssize_t i)552 FrameList_repeat(pcm_FrameList *a, Py_ssize_t i)
553 {
554     pcm_FrameList *repeat = FrameList_create();
555     Py_ssize_t j;
556 
557     repeat->frames = (unsigned int)(a->frames * i);
558     repeat->channels = a->channels;
559     repeat->bits_per_sample = a->bits_per_sample;
560     repeat->samples_length = (unsigned int)(a->samples_length * i);
561     repeat->samples = PyMem_Malloc(sizeof(int) * repeat->samples_length);
562 
563     for (j = 0; j < i; j++) {
564         memcpy(repeat->samples + (j * a->samples_length),
565                a->samples,
566                a->samples_length * sizeof(int));
567     }
568 
569     return (PyObject*)repeat;
570 }
571 
572 PyObject*
FrameList_inplace_concat(pcm_FrameList * a,PyObject * bb)573 FrameList_inplace_concat(pcm_FrameList *a, PyObject *bb)
574 {
575     pcm_FrameList *b;
576     const unsigned int old_samples_length = a->samples_length;
577 
578     if (FrameList_CheckExact(bb)) {
579         b = (pcm_FrameList*)bb;
580     } else{
581         PyErr_SetString(PyExc_TypeError,
582                         "can only concatenate FrameList with other FrameLists"
583             );
584         return NULL;
585     }
586 
587     if (a->channels != b->channels) {
588         PyErr_SetString(PyExc_ValueError,
589                         "both FrameLists must have the same number of channels"
590             );
591         return NULL;
592     }
593     if (a->bits_per_sample != b->bits_per_sample) {
594         PyErr_SetString(PyExc_ValueError,
595                         "both FrameLists must have the same number "
596                         "of bits per sample");
597         return NULL;
598     }
599 
600     a->frames += b->frames;
601     a->samples_length += b->samples_length;
602     a->samples = PyMem_Realloc(a->samples, a->samples_length * sizeof(int));
603     memcpy(a->samples + old_samples_length,
604            b->samples,
605            b->samples_length * sizeof(int));
606 
607     Py_INCREF(a);
608     return (PyObject*)a;
609 }
610 
611 PyObject*
FrameList_inplace_repeat(pcm_FrameList * a,Py_ssize_t i)612 FrameList_inplace_repeat(pcm_FrameList *a, Py_ssize_t i)
613 {
614     const unsigned int original_length = a->samples_length;
615     Py_ssize_t j;
616 
617     a->frames = (unsigned int)(a->frames * i);
618     a->samples_length = (unsigned int)(a->samples_length * i);
619     a->samples = PyMem_Realloc(a->samples, a->samples_length * sizeof(int));
620 
621     for (j = 1; j < i; j++) {
622         memcpy(a->samples + (j * original_length),
623                a->samples,
624                original_length * sizeof(int));
625     }
626 
627     Py_INCREF(a);
628     return (PyObject*)a;
629 }
630 
631 PyObject*
FrameList_to_float(pcm_FrameList * self,PyObject * args)632 FrameList_to_float(pcm_FrameList *self, PyObject *args)
633 {
634     unsigned i;
635     const int adjustment = 1 << (self->bits_per_sample - 1);
636     pcm_FloatFrameList *framelist = FloatFrameList_create();
637     framelist->frames = self->frames;
638     framelist->channels = self->channels;
639     framelist->samples_length = self->samples_length;
640     framelist->samples = PyMem_Malloc(sizeof(double) * framelist->samples_length);
641 
642     for (i = 0; i < self->samples_length; i++) {
643         framelist->samples[i] = ((double)self->samples[i]) / adjustment;
644     }
645 
646     return (PyObject*)framelist;
647 }
648 
649 PyObject*
FrameList_frame_count(pcm_FrameList * self,PyObject * args)650 FrameList_frame_count(pcm_FrameList *self, PyObject *args)
651 {
652     int byte_count;
653     int bytes_per_frame = self->channels * (self->bits_per_sample / 8);
654 
655     if (!PyArg_ParseTuple(args, "i", &byte_count))
656         return NULL;
657     else {
658         byte_count -= (byte_count % bytes_per_frame);
659         return Py_BuildValue("i",
660                              byte_count ? byte_count / bytes_per_frame : 1);
661     }
662 }
663 
664 #endif
665 
666 void
FrameList_char_to_samples(int * samples,unsigned char * data,FrameList_char_to_int_converter converter,unsigned samples_length,int bits_per_sample)667 FrameList_char_to_samples(int *samples,
668                           unsigned char *data,
669                           FrameList_char_to_int_converter converter,
670                           unsigned samples_length,
671                           int bits_per_sample)
672 {
673     int bytes_per_sample = bits_per_sample / 8;
674     int i;
675 
676     for (i = 0; i < samples_length; i++, data += bytes_per_sample) {
677         samples[i] = converter(data);
678     }
679 }
680 
681 #ifndef STANDALONE
682 PyObject*
FrameList_from_list(PyObject * dummy,PyObject * args)683 FrameList_from_list(PyObject *dummy, PyObject *args)
684 {
685     pcm_FrameList *framelist;
686     PyObject *list;
687     Py_ssize_t list_len, i;
688     long integer_val;
689     int adjustment;
690     int channels;
691     int bits_per_sample;
692     int is_signed;
693 
694     if (!PyArg_ParseTuple(args, "Oiii",
695                           &list,
696                           &channels,
697                           &bits_per_sample,
698                           &is_signed)) {
699         return NULL;
700     }
701 
702     if ((list_len = PySequence_Size(list)) == -1) {
703         return NULL;
704     }
705 
706     if (channels < 1) {
707         PyErr_SetString(PyExc_ValueError, "channels must be > 0");
708         return NULL;
709     }
710 
711     if ((bits_per_sample != 8) &&
712         (bits_per_sample != 16) &&
713         (bits_per_sample != 24)) {
714         PyErr_SetString(PyExc_ValueError,
715                         "unsupported number of bits per sample");
716         return NULL;
717     }
718 
719     if (list_len % channels) {
720         PyErr_SetString(PyExc_ValueError,
721                         "number of samples must be divisible by "
722                         "number of channels");
723         return NULL;
724     }
725 
726     if (is_signed) {
727         adjustment = 0;
728     } else {
729         adjustment = (1 << (bits_per_sample - 1));
730     }
731 
732     framelist = FrameList_create();
733     framelist->channels = channels;
734     framelist->bits_per_sample = bits_per_sample;
735     framelist->samples = PyMem_Malloc(sizeof(int) * list_len);
736     framelist->samples_length = (unsigned int)list_len;
737     framelist->frames = (unsigned int)list_len / framelist->channels;
738     for (i = 0; i < list_len; i++) {
739         PyObject *integer_obj;
740         if ((integer_obj = PySequence_GetItem(list, i)) == NULL) {
741             Py_DECREF((PyObject*)framelist);
742             return NULL;
743         }
744         integer_val = PyInt_AsLong(integer_obj);
745         Py_DECREF(integer_obj);
746         if ((integer_val == -1) && PyErr_Occurred()) {
747             Py_DECREF((PyObject*)framelist);
748             return NULL;
749         }
750         framelist->samples[i] = (int)(integer_val - adjustment);
751     }
752 
753     return (PyObject*)framelist;
754 }
755 
756 PyObject*
FrameList_from_frames(PyObject * dummy,PyObject * args)757 FrameList_from_frames(PyObject *dummy, PyObject *args)
758 {
759     PyObject *list;
760     Py_ssize_t list_len, i;
761     pcm_FrameList *output_frame;
762     PyObject *initial_frame_obj;
763     pcm_FrameList *initial_frame;
764 
765     if (!PyArg_ParseTuple(args, "O", &list)) {
766         return NULL;
767     }
768 
769     if ((list_len = PySequence_Size(list)) == -1) {
770         return NULL;
771     }
772 
773     /*get first FrameList as a base
774       for its channels/bits_per_sample values*/
775     if ((initial_frame_obj = PySequence_GetItem(list, 0)) == NULL) {
776         return NULL;
777     }
778 
779     if (FrameList_CheckExact(initial_frame_obj)) {
780         initial_frame = (pcm_FrameList*)initial_frame_obj;
781     } else {
782         PyErr_SetString(PyExc_TypeError,
783                         "frames must be of type FrameList");
784         Py_DECREF(initial_frame_obj);
785         return NULL;
786     }
787 
788     if (initial_frame->frames != 1) {
789         PyErr_SetString(PyExc_ValueError,
790                         "all subframes must be 1 frame long");
791         Py_DECREF(initial_frame_obj);
792         return NULL;
793     }
794 
795     /*create output FrameList from initial values*/
796     output_frame = FrameList_create();
797     output_frame->frames = (unsigned int)list_len;
798     output_frame->channels = initial_frame->channels;
799     output_frame->bits_per_sample = initial_frame->bits_per_sample;
800     output_frame->samples_length =
801         output_frame->frames * output_frame->channels;
802     output_frame->samples =
803         PyMem_Malloc(sizeof(int) * output_frame->samples_length);
804 
805     memcpy(output_frame->samples,
806            initial_frame->samples,
807            sizeof(int) * initial_frame->samples_length);
808 
809     /*we're done with initial frame*/
810     Py_DECREF((PyObject*)initial_frame);
811 
812     /*process remaining FrameLists in list*/
813     for (i = 1; i < list_len; i++) {
814         PyObject *list_frame_obj;
815         pcm_FrameList *list_frame;
816 
817         if ((list_frame_obj = PySequence_GetItem(list, i)) == NULL) {
818             Py_DECREF((PyObject*)output_frame);
819             return NULL;
820         }
821 
822         if (FrameList_CheckExact(list_frame_obj)) {
823             list_frame = (pcm_FrameList*)list_frame_obj;
824         } else {
825             Py_DECREF((PyObject*)output_frame);
826             Py_DECREF(list_frame_obj);
827             PyErr_SetString(PyExc_TypeError,
828                             "frames must be of type FrameList");
829             return NULL;
830         }
831 
832         if (list_frame->frames != 1) {
833             Py_DECREF((PyObject*)output_frame);
834             Py_DECREF(list_frame_obj);
835             PyErr_SetString(PyExc_ValueError,
836                             "all subframes must be 1 frame long");
837             return NULL;
838         }
839 
840         if (output_frame->channels != list_frame->channels) {
841             Py_DECREF((PyObject*)output_frame);
842             Py_DECREF(list_frame_obj);
843             PyErr_SetString(PyExc_ValueError,
844                             "all subframes must have the same "
845                             "number of channels");
846             return NULL;
847         }
848 
849         if (output_frame->bits_per_sample != list_frame->bits_per_sample) {
850             Py_DECREF((PyObject*)output_frame);
851             Py_DECREF(list_frame_obj);
852             PyErr_SetString(PyExc_ValueError,
853                             "all subframes must have the same "
854                             "number of bits per sample");
855             return NULL;
856         }
857 
858         memcpy(output_frame->samples + (i * output_frame->channels),
859                list_frame->samples,
860                sizeof(int) * list_frame->samples_length);
861 
862         Py_DECREF(list_frame_obj);
863     }
864 
865     return (PyObject*)output_frame;
866 }
867 
868 PyObject*
FrameList_from_channels(PyObject * dummy,PyObject * args)869 FrameList_from_channels(PyObject *dummy, PyObject *args)
870 {
871     PyObject *list;
872     Py_ssize_t list_len, i;
873     pcm_FrameList *output_frame;
874     PyObject *initial_frame_obj;
875     pcm_FrameList *initial_frame;
876     unsigned j;
877 
878     if (!PyArg_ParseTuple(args, "O", &list)) {
879         return NULL;
880     }
881 
882     if ((list_len = PySequence_Size(list)) == -1) {
883         return NULL;
884     }
885 
886     /*get first FrameList as a base
887       for its frames/bits_per_sample values*/
888     if ((initial_frame_obj = PySequence_GetItem(list, 0)) == NULL) {
889         return NULL;
890     }
891 
892     if (FrameList_CheckExact(initial_frame_obj)) {
893         initial_frame = (pcm_FrameList*)initial_frame_obj;
894     } else {
895         PyErr_SetString(PyExc_TypeError,
896                         "channels must be of type FrameList");
897         Py_DECREF(initial_frame_obj);
898         return NULL;
899     }
900 
901     if (initial_frame->channels != 1) {
902         PyErr_SetString(PyExc_ValueError,
903                         "all channels must be 1 channel wide");
904         Py_DECREF(initial_frame_obj);
905         return NULL;
906     }
907 
908     /*create output FrameList from initial values*/
909     output_frame = FrameList_create();
910     output_frame->frames = initial_frame->frames;
911     output_frame->channels = (unsigned int)list_len;
912     output_frame->bits_per_sample = initial_frame->bits_per_sample;
913     output_frame->samples_length =
914         output_frame->frames * output_frame->channels;
915     output_frame->samples =
916         PyMem_Malloc(sizeof(int) * output_frame->samples_length);
917 
918     for (j = 0; j < initial_frame->samples_length; j++) {
919         output_frame->samples[j * list_len] = initial_frame->samples[j];
920     }
921 
922     /*we're done with initial frame*/
923     Py_DECREF(initial_frame_obj);
924 
925     /*process remaining FrameLists in list*/
926     for (i = 1; i < list_len; i++) {
927         PyObject *list_frame_obj;
928         pcm_FrameList *list_frame;
929 
930         if ((list_frame_obj = PySequence_GetItem(list, i)) == NULL) {
931             Py_DECREF((PyObject*)output_frame);
932             return NULL;
933         }
934 
935         if (FrameList_CheckExact(list_frame_obj)) {
936             list_frame = (pcm_FrameList*)list_frame_obj;
937         } else {
938             Py_DECREF((PyObject*)output_frame);
939             Py_DECREF(list_frame_obj);
940             PyErr_SetString(PyExc_TypeError,
941                             "channels must be of type FrameList");
942             return NULL;
943         }
944 
945         if (list_frame->channels != 1) {
946             Py_DECREF((PyObject*)output_frame);
947             Py_DECREF(list_frame_obj);
948             PyErr_SetString(PyExc_ValueError,
949                             "all channels must be 1 channel wide");
950             return NULL;
951         }
952 
953         if (output_frame->frames != list_frame->frames) {
954             Py_DECREF((PyObject*)output_frame);
955             Py_DECREF(list_frame_obj);
956             PyErr_SetString(PyExc_ValueError,
957                             "all channels must have the same "
958                             "number of frames");
959             return NULL;
960         }
961         if (output_frame->bits_per_sample != list_frame->bits_per_sample) {
962             Py_DECREF((PyObject*)output_frame);
963             Py_DECREF(list_frame_obj);
964             PyErr_SetString(PyExc_ValueError,
965                             "all channels must have the same "
966                             "number of bits per sample");
967             return NULL;
968         }
969 
970 
971         for (j = 0; j < list_frame->samples_length; j++) {
972             output_frame->samples[(j * list_len) + i] = list_frame->samples[j];
973         }
974 
975         Py_DECREF(list_frame_obj);
976     }
977 
978     return (PyObject*)output_frame;
979 }
980 
981 int
FrameList_converter(PyObject * obj,void ** framelist)982 FrameList_converter(PyObject* obj, void** framelist)
983 {
984     if (PyObject_TypeCheck(obj, &pcm_FrameListType)) {
985         *framelist = obj;
986         return 1;
987     } else {
988         PyErr_SetString(PyExc_TypeError, "not a FrameList object");
989         return 0;
990     }
991 }
992 
993 /***********************
994   FloatFrameList Object
995 ************************/
996 
997 PyGetSetDef FloatFrameList_getseters[] = {
998     {"frames", (getter)FloatFrameList_frames, 0, "frame count", NULL},
999     {"channels", (getter)FloatFrameList_channels, 0, "channel count", NULL},
1000     {NULL}  /* Sentinel */
1001 };
1002 
1003 PyMethodDef FloatFrameList_methods[] = {
1004     {"frame", (PyCFunction)FloatFrameList_frame,
1005      METH_VARARGS,
1006      "FF.frame(i) -> FloatFrameList -- return the given PCM frame"},
1007     {"channel", (PyCFunction)FloatFrameList_channel,
1008      METH_VARARGS,
1009      "FF.channel(i) -> FloatFrameList -- return the given channel"},
1010     {"split", (PyCFunction)FloatFrameList_split,
1011      METH_VARARGS,
1012      "FF.split(i) -> (FloatFrameList,FloatFrameList) -- "
1013      "splits the FloatFrameList at the given index"},
1014     {"from_frames", (PyCFunction)FloatFrameList_from_frames,
1015      METH_VARARGS | METH_CLASS,
1016      "FloatFrameList.from_frames(floatframelist_list) -> FloatFrameList"},
1017     {"from_channels", (PyCFunction)FloatFrameList_from_channels,
1018      METH_VARARGS | METH_CLASS,
1019      "FloatFrameList.from_channels(floatframelist_list) -> FloatFrameList"},
1020     {"to_int", (PyCFunction)FloatFrameList_to_int,
1021      METH_VARARGS,
1022      "FF.to_int(bits_per_sample) -> FrameList"},
1023     {NULL}
1024 };
1025 
1026 static PySequenceMethods pcm_FloatFrameListType_as_sequence = {
1027     (lenfunc)FloatFrameList_len,          /* sq_length */
1028     (binaryfunc)FloatFrameList_concat,    /* sq_concat */
1029     (ssizeargfunc)FloatFrameList_repeat,  /* sq_repeat */
1030     (ssizeargfunc)FloatFrameList_GetItem, /* sq_item */
1031     (ssizessizeargfunc)NULL,              /* sq_slice */
1032     (ssizeobjargproc)NULL,                /* sq_ass_item */
1033     (ssizessizeobjargproc)NULL,           /* sq_ass_slice */
1034     (objobjproc)NULL,                     /* sq_contains */
1035     (binaryfunc)FloatFrameList_inplace_concat,   /* sq_inplace_concat */
1036     (ssizeargfunc)FloatFrameList_inplace_repeat, /* sq_inplace_repeat */
1037 };
1038 
1039 PyTypeObject pcm_FloatFrameListType = {
1040     PyVarObject_HEAD_INIT(NULL, 0)
1041     "pcm.FloatFrameList",      /*tp_name*/
1042     sizeof(pcm_FloatFrameList), /*tp_basicsize*/
1043     0,                         /*tp_itemsize*/
1044     (destructor)FloatFrameList_dealloc, /*tp_dealloc*/
1045     0,                         /*tp_print*/
1046     0,                         /*tp_getattr*/
1047     0,                         /*tp_setattr*/
1048     0,                         /*tp_compare*/
1049     0,                         /*tp_repr*/
1050     0,                         /*tp_as_number*/
1051     &pcm_FloatFrameListType_as_sequence, /*tp_as_sequence*/
1052     0,                         /*tp_as_mapping*/
1053     0,                         /*tp_hash */
1054     0,                         /*tp_call*/
1055     0,                         /*tp_str*/
1056     0,                         /*tp_getattro*/
1057     0,                         /*tp_setattro*/
1058     0,                         /*tp_as_buffer*/
1059     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1060     "FloatFrameList(float_list, channels)",  /* tp_doc */
1061     0,                         /* tp_traverse */
1062     0,                         /* tp_clear */
1063     (richcmpfunc)FloatFrameList_richcompare, /* tp_richcompare */
1064     0,                         /* tp_weaklistoffset */
1065     0,                         /* tp_iter */
1066     0,                         /* tp_iternext */
1067     FloatFrameList_methods,    /* tp_methods */
1068     0,                         /* tp_members */
1069     FloatFrameList_getseters,  /* tp_getset */
1070     0,                         /* tp_base */
1071     0,                         /* tp_dict */
1072     0,                         /* tp_descr_get */
1073     0,                         /* tp_descr_set */
1074     0,                         /* tp_dictoffset */
1075     (initproc)FloatFrameList_init,  /* tp_init */
1076     0,                         /* tp_alloc */
1077     FloatFrameList_new,        /* tp_new */
1078 };
1079 
1080 void
FloatFrameList_dealloc(pcm_FloatFrameList * self)1081 FloatFrameList_dealloc(pcm_FloatFrameList* self)
1082 {
1083     PyMem_Free(self->samples);
1084     Py_TYPE(self)->tp_free((PyObject*)self);
1085 }
1086 
1087 PyObject*
FloatFrameList_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1088 FloatFrameList_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1089 {
1090     pcm_FloatFrameList *self;
1091 
1092     self = (pcm_FloatFrameList *)type->tp_alloc(type, 0);
1093 
1094     return (PyObject *)self;
1095 }
1096 
1097 int
FloatFrameList_init(pcm_FloatFrameList * self,PyObject * args,PyObject * kwds)1098 FloatFrameList_init(pcm_FloatFrameList *self, PyObject *args, PyObject *kwds)
1099 {
1100     PyObject *data;
1101     Py_ssize_t data_size;
1102     Py_ssize_t i;
1103 
1104     if (!PyArg_ParseTuple(args, "OI",
1105                           &data,
1106                           &(self->channels)))
1107         return -1;
1108 
1109     if (self->channels < 1) {
1110         PyErr_SetString(PyExc_ValueError,
1111                         "number of channels must be > 0");
1112         return -1;
1113     } else if ((data_size = PySequence_Size(data)) == -1) {
1114         return -1;
1115     } else if (data_size % (self->channels)) {
1116         PyErr_SetString(PyExc_ValueError,
1117                         "number of samples must be divisible by "
1118                         "number of channels");
1119         return -1;
1120     } else {
1121         self->samples_length = (unsigned int)data_size;
1122         self->frames = (self->samples_length / self->channels);
1123         self->samples = PyMem_Malloc(sizeof(double) * self->samples_length);
1124     }
1125 
1126     for (i = 0; i < data_size; i++) {
1127         PyObject *data_item;
1128         if ((data_item = PySequence_GetItem(data, i)) == NULL)
1129             /*this shouldn't happen unless "data" changes mid-function*/
1130             return -1;
1131 
1132         if (((self->samples[i] = PyFloat_AsDouble(data_item)) == -1) &&
1133             PyErr_Occurred()) {
1134             Py_DECREF(data_item);
1135             return -1;
1136         }
1137         Py_DECREF(data_item);
1138     }
1139 
1140     return 0;
1141 }
1142 
1143 pcm_FloatFrameList*
FloatFrameList_create(void)1144 FloatFrameList_create(void)
1145 {
1146     return (pcm_FloatFrameList*)_PyObject_New(&pcm_FloatFrameListType);
1147 }
1148 
1149 PyObject*
FloatFrameList_empty(PyObject * dummy,PyObject * args)1150 FloatFrameList_empty(PyObject *dummy, PyObject *args)
1151 {
1152     int channels;
1153     pcm_FloatFrameList *framelist;
1154 
1155     if (!PyArg_ParseTuple(args, "i", &channels)) {
1156         return NULL;
1157     }
1158 
1159     if (channels <= 0) {
1160         PyErr_SetString(PyExc_ValueError, "channels must be > 0");
1161         return NULL;
1162     }
1163 
1164     framelist = FloatFrameList_create();
1165     framelist->frames = 0;
1166     framelist->channels = (unsigned)channels;
1167     framelist->samples = NULL;
1168     framelist->samples_length = 0;
1169     return (PyObject*)framelist;
1170 }
1171 
1172 int
FloatFrameList_CheckExact(PyObject * o)1173 FloatFrameList_CheckExact(PyObject *o)
1174 {
1175     return Py_TYPE(o) == &pcm_FloatFrameListType;
1176 }
1177 
1178 PyObject*
FloatFrameList_frames(pcm_FloatFrameList * self,void * closure)1179 FloatFrameList_frames(pcm_FloatFrameList *self, void* closure)
1180 {
1181     return Py_BuildValue("i", self->frames);
1182 }
1183 
1184 PyObject*
FloatFrameList_channels(pcm_FloatFrameList * self,void * closure)1185 FloatFrameList_channels(pcm_FloatFrameList *self, void* closure)
1186 {
1187     return Py_BuildValue("i", self->channels);
1188 }
1189 
1190 Py_ssize_t
FloatFrameList_len(pcm_FloatFrameList * o)1191 FloatFrameList_len(pcm_FloatFrameList *o)
1192 {
1193     return o->samples_length;
1194 }
1195 
1196 PyObject
FloatFrameList_richcompare(PyObject * a,PyObject * b,int op)1197 *FloatFrameList_richcompare(PyObject *a, PyObject *b, int op)
1198 {
1199     switch (op) {
1200     case Py_EQ:
1201         if (FloatFrameList_CheckExact(a) &&
1202             FloatFrameList_CheckExact(b) &&
1203             FloatFrameList_equals((pcm_FloatFrameList*)a,
1204                                   (pcm_FloatFrameList*)b)) {
1205             Py_INCREF(Py_True);
1206             return Py_True;
1207         } else {
1208             Py_INCREF(Py_False);
1209             return Py_False;
1210         }
1211     case Py_NE:
1212         if (FloatFrameList_CheckExact(a) &&
1213             FloatFrameList_CheckExact(b) &&
1214             FloatFrameList_equals((pcm_FloatFrameList*)a,
1215                                   (pcm_FloatFrameList*)b)) {
1216             Py_INCREF(Py_False);
1217             return Py_False;
1218         } else {
1219             Py_INCREF(Py_True);
1220             return Py_True;
1221         }
1222     default:
1223         PyErr_SetString(PyExc_TypeError, "unsupported comparison");
1224         return NULL;
1225     }
1226 }
1227 
1228 int
FloatFrameList_equals(pcm_FloatFrameList * a,pcm_FloatFrameList * b)1229 FloatFrameList_equals(pcm_FloatFrameList *a, pcm_FloatFrameList *b)
1230 {
1231     return ((a->frames == b->frames) &&
1232             (a->channels == b->channels) &&
1233             (a->samples_length == b->samples_length) &&
1234             (memcmp(a->samples,
1235                     b->samples,
1236                     sizeof(double) * a->samples_length) == 0));
1237 }
1238 
1239 PyObject*
FloatFrameList_GetItem(pcm_FloatFrameList * o,Py_ssize_t i)1240 FloatFrameList_GetItem(pcm_FloatFrameList *o, Py_ssize_t i)
1241 {
1242     if ((i >= o->samples_length) || (i < 0)) {
1243         PyErr_SetString(PyExc_IndexError, "index out of range");
1244         return NULL;
1245     } else {
1246         return Py_BuildValue("d", o->samples[i]);
1247     }
1248 }
1249 
1250 PyObject*
FloatFrameList_frame(pcm_FloatFrameList * self,PyObject * args)1251 FloatFrameList_frame(pcm_FloatFrameList *self, PyObject *args)
1252 {
1253     int frame_number;
1254     pcm_FloatFrameList *frame;
1255 
1256     if (!PyArg_ParseTuple(args, "i", &frame_number))
1257         return NULL;
1258     if ((frame_number < 0) || (frame_number >= self->frames)) {
1259         PyErr_SetString(PyExc_IndexError, "frame number out of range");
1260         return NULL;
1261     }
1262 
1263     frame = FloatFrameList_create();
1264     frame->frames = 1;
1265     frame->channels = self->channels;
1266     frame->samples = PyMem_Malloc(sizeof(double) * self->channels);
1267     frame->samples_length = self->channels;
1268     memcpy(frame->samples,
1269            self->samples + (frame_number * self->channels),
1270            sizeof(double) * self->channels);
1271     return (PyObject*)frame;
1272 }
1273 
1274 PyObject*
FloatFrameList_channel(pcm_FloatFrameList * self,PyObject * args)1275 FloatFrameList_channel(pcm_FloatFrameList *self, PyObject *args)
1276 {
1277     int channel_number;
1278     pcm_FloatFrameList *channel;
1279     unsigned i, j;
1280     unsigned samples_length;
1281     int total_channels;
1282 
1283     if (!PyArg_ParseTuple(args, "i", &channel_number))
1284         return NULL;
1285     if ((channel_number < 0) || (channel_number >= self->channels)) {
1286         PyErr_SetString(PyExc_IndexError, "channel number out of range");
1287         return NULL;
1288     }
1289 
1290     channel = FloatFrameList_create();
1291     channel->frames = self->frames;
1292     channel->channels = 1;
1293     channel->samples = PyMem_Malloc(sizeof(double) * self->frames);
1294     channel->samples_length = self->frames;
1295 
1296     samples_length = self->samples_length;
1297     total_channels = self->channels;
1298     for (j=0, i = channel_number;
1299          i < samples_length;
1300          j++, i += total_channels) {
1301         channel->samples[j] = self->samples[i];
1302     }
1303 
1304     return (PyObject*)channel;
1305 }
1306 
1307 PyObject*
FloatFrameList_to_int(pcm_FloatFrameList * self,PyObject * args)1308 FloatFrameList_to_int(pcm_FloatFrameList *self, PyObject *args)
1309 {
1310     unsigned i;
1311     int adjustment;
1312     int sample_min;
1313     int sample_max;
1314     pcm_FrameList *framelist;
1315     int bits_per_sample;
1316 
1317     if (!PyArg_ParseTuple(args, "i", &bits_per_sample))
1318         return NULL;
1319 
1320     framelist = FrameList_create();
1321     framelist->frames = self->frames;
1322     framelist->channels = self->channels;
1323     framelist->bits_per_sample = bits_per_sample;
1324     framelist->samples_length = self->samples_length;
1325     framelist->samples = PyMem_Malloc(sizeof(int) * framelist->samples_length);
1326 
1327     adjustment = 1 << (bits_per_sample - 1);
1328     sample_min = -adjustment;
1329     sample_max = adjustment - 1;
1330     for (i = 0; i < self->samples_length; i++) {
1331         const int int_sample = (int)(self->samples[i] * adjustment);
1332         framelist->samples[i] =  MAX(MIN(int_sample, sample_max), sample_min);
1333     }
1334 
1335     return (PyObject*)framelist;
1336 }
1337 
1338 PyObject*
FloatFrameList_split(pcm_FloatFrameList * self,PyObject * args)1339 FloatFrameList_split(pcm_FloatFrameList *self, PyObject *args)
1340 {
1341     pcm_FloatFrameList *head;
1342     pcm_FloatFrameList *tail;
1343     PyObject* tuple;
1344     int split_point;
1345 
1346     if (!PyArg_ParseTuple(args, "i", &split_point)) {
1347         return NULL;
1348     }
1349 
1350     if (split_point < 0) {
1351         PyErr_SetString(PyExc_IndexError, "split point must be >= 0");
1352         return NULL;
1353     } else if (split_point >= self->frames) {
1354         head = self;
1355         Py_INCREF(head);
1356         tail = FloatFrameList_create();
1357         tail->frames = 0;
1358         tail->channels = self->channels;
1359         tail->samples_length = 0;
1360         tail->samples = NULL;
1361     } else if (split_point == 0) {
1362         head = FloatFrameList_create();
1363         head->frames = 0;
1364         head->channels = self->channels;
1365         head->samples_length = 0;
1366         head->samples = NULL;
1367         tail = self;
1368         Py_INCREF(tail);
1369     } else {
1370         head = FloatFrameList_create();
1371         head->frames = split_point;
1372         head->samples_length = (head->frames * self->channels);
1373         head->samples = PyMem_Malloc(head->samples_length * sizeof(double));
1374         memcpy(head->samples,
1375                self->samples,
1376                head->samples_length * sizeof(double));
1377 
1378         tail = FloatFrameList_create();
1379         tail->frames = (self->frames - split_point);
1380         tail->samples_length = (tail->frames * self->channels);
1381         tail->samples = PyMem_Malloc(tail->samples_length * sizeof(double));
1382         memcpy(tail->samples,
1383                self->samples + head->samples_length,
1384                tail->samples_length * sizeof(double));
1385 
1386         head->channels = tail->channels = self->channels;
1387     }
1388 
1389     tuple = Py_BuildValue("(O,O)", head, tail);
1390     Py_DECREF(head);
1391     Py_DECREF(tail);
1392     return tuple;
1393 }
1394 
1395 PyObject*
FloatFrameList_concat(pcm_FloatFrameList * a,PyObject * bb)1396 FloatFrameList_concat(pcm_FloatFrameList *a, PyObject *bb)
1397 {
1398     pcm_FloatFrameList *concat;
1399     pcm_FloatFrameList *b;
1400 
1401     if (FloatFrameList_CheckExact(bb)) {
1402         b = (pcm_FloatFrameList*)bb;
1403     } else {
1404         PyErr_SetString(PyExc_TypeError,
1405                         "can only concatenate FloatFrameList "
1406                         "with other FloatFrameLists");
1407         return NULL;
1408     }
1409 
1410     if (a->channels != b->channels) {
1411         PyErr_SetString(PyExc_ValueError,
1412                         "both FloatFrameLists must have the same "
1413                         "number of channels");
1414         return NULL;
1415     }
1416 
1417     concat = FloatFrameList_create();
1418     concat->frames = a->frames + b->frames;
1419     concat->channels = a->channels;
1420     concat->samples_length = a->samples_length + b->samples_length;
1421     concat->samples = PyMem_Malloc(concat->samples_length * sizeof(double));
1422     memcpy(concat->samples, a->samples, a->samples_length * sizeof(double));
1423     memcpy(concat->samples + a->samples_length,
1424            b->samples,
1425            b->samples_length * sizeof(double));
1426 
1427     return (PyObject*)concat;
1428 }
1429 
1430 
1431 PyObject*
FloatFrameList_repeat(pcm_FloatFrameList * a,Py_ssize_t i)1432 FloatFrameList_repeat(pcm_FloatFrameList *a, Py_ssize_t i)
1433 {
1434     pcm_FloatFrameList *repeat = FloatFrameList_create();
1435     Py_ssize_t j;
1436 
1437     repeat->frames = (unsigned int)(a->frames * i);
1438     repeat->channels = a->channels;
1439     repeat->samples_length = (unsigned int)(a->samples_length * i);
1440     repeat->samples = PyMem_Malloc(sizeof(double) * repeat->samples_length);
1441 
1442     for (j = 0; j < i; j++) {
1443         memcpy(repeat->samples + (j * a->samples_length),
1444                a->samples,
1445                a->samples_length * sizeof(double));
1446     }
1447 
1448     return (PyObject*)repeat;
1449 }
1450 
1451 PyObject*
FloatFrameList_inplace_concat(pcm_FloatFrameList * a,PyObject * bb)1452 FloatFrameList_inplace_concat(pcm_FloatFrameList *a, PyObject *bb)
1453 {
1454     pcm_FloatFrameList *b;
1455     const unsigned int old_samples_length = a->samples_length;
1456 
1457     if (FloatFrameList_CheckExact(bb)) {
1458         b = (pcm_FloatFrameList*)bb;
1459     } else {
1460         PyErr_SetString(PyExc_TypeError,
1461                         "can only concatenate FloatFrameList "
1462                         "with other FloatFrameLists");
1463         return NULL;
1464     }
1465 
1466     if (a->channels != b->channels) {
1467         PyErr_SetString(PyExc_ValueError,
1468                         "both FloatFrameLists must have the same "
1469                         "number of channels");
1470         return NULL;
1471     }
1472 
1473     a->frames += b->frames;
1474     a->samples_length += b->samples_length;
1475     a->samples = PyMem_Realloc(a->samples, a->samples_length * sizeof(double));
1476     memcpy(a->samples + old_samples_length,
1477            b->samples,
1478            b->samples_length * sizeof(double));
1479 
1480     Py_INCREF(a);
1481     return (PyObject*)a;
1482 }
1483 
1484 PyObject*
FloatFrameList_inplace_repeat(pcm_FloatFrameList * a,Py_ssize_t i)1485 FloatFrameList_inplace_repeat(pcm_FloatFrameList *a, Py_ssize_t i)
1486 {
1487     const unsigned int original_length = a->samples_length;
1488     Py_ssize_t j;
1489 
1490     a->frames = (unsigned int)(a->frames * i);
1491     a->samples_length = (unsigned int)(a->samples_length * i);
1492     a->samples = PyMem_Realloc(a->samples, a->samples_length * sizeof(double));
1493 
1494     for (j = 1; j < i; j++) {
1495         memcpy(a->samples + (j * original_length),
1496                a->samples,
1497                original_length * sizeof(double));
1498     }
1499 
1500     Py_INCREF(a);
1501     return (PyObject*)a;
1502 }
1503 
1504 PyObject*
FloatFrameList_from_frames(PyObject * dummy,PyObject * args)1505 FloatFrameList_from_frames(PyObject *dummy, PyObject *args)
1506 {
1507     PyObject *list;
1508     Py_ssize_t list_len, i;
1509     pcm_FloatFrameList *output_frame;
1510     PyObject *initial_frame_obj;
1511     pcm_FloatFrameList *initial_frame;
1512 
1513     if (!PyArg_ParseTuple(args, "O", &list)) {
1514         return NULL;
1515     }
1516 
1517 
1518     if ((list_len = PySequence_Size(list)) == -1) {
1519         return NULL;
1520     }
1521 
1522     /*get first FrameList as a base for its channels value*/
1523     if ((initial_frame_obj = PySequence_GetItem(list, 0)) == NULL) {
1524         return NULL;
1525     }
1526 
1527     if (FloatFrameList_CheckExact(initial_frame_obj)) {
1528         initial_frame = (pcm_FloatFrameList*)initial_frame_obj;
1529     } else {
1530         PyErr_SetString(PyExc_TypeError,
1531                         "frames must be of type FloatFrameList");
1532         Py_DECREF(initial_frame_obj);
1533         return NULL;
1534     }
1535 
1536     if (initial_frame->frames != 1) {
1537         PyErr_SetString(PyExc_ValueError,
1538                         "all subframes must be 1 frame long");
1539         Py_DECREF(initial_frame_obj);
1540         return NULL;
1541     }
1542 
1543     output_frame = FloatFrameList_create();
1544     output_frame->frames = (unsigned int)list_len;
1545     output_frame->channels = initial_frame->channels;
1546     output_frame->samples_length =
1547         output_frame->frames * output_frame->channels;
1548     output_frame->samples =
1549         PyMem_Malloc(sizeof(double) * output_frame->samples_length);
1550 
1551     memcpy(output_frame->samples,
1552            initial_frame->samples,
1553            sizeof(double) * initial_frame->samples_length);
1554 
1555     /*we're done with initial frame*/
1556     Py_DECREF((PyObject*)initial_frame);
1557 
1558     /*process remaining FloatFrameLists in list*/
1559     for (i = 1; i < list_len; i++) {
1560         PyObject *list_frame_obj;
1561         pcm_FloatFrameList *list_frame;
1562 
1563         if ((list_frame_obj = PySequence_GetItem(list, i)) == NULL) {
1564             Py_DECREF((PyObject*)output_frame);
1565             return NULL;
1566         }
1567 
1568         if (FloatFrameList_CheckExact(list_frame_obj)) {
1569             list_frame = (pcm_FloatFrameList*)list_frame_obj;
1570         } else {
1571             Py_DECREF((PyObject*)output_frame);
1572             Py_DECREF(list_frame_obj);
1573             PyErr_SetString(PyExc_TypeError,
1574                             "frames must be of type FloatFrameList");
1575             return NULL;
1576         }
1577 
1578         if (list_frame->frames != 1) {
1579             Py_DECREF((PyObject*)output_frame);
1580             Py_DECREF(list_frame_obj);
1581             PyErr_SetString(PyExc_ValueError,
1582                             "all subframes must be 1 frame long");
1583             return NULL;
1584         }
1585         if (output_frame->channels != list_frame->channels) {
1586             Py_DECREF((PyObject*)output_frame);
1587             Py_DECREF(list_frame_obj);
1588             PyErr_SetString(PyExc_ValueError,
1589                             "all subframes must have the same "
1590                             "number of channels");
1591             return NULL;
1592         }
1593 
1594         memcpy(output_frame->samples + (i * output_frame->channels),
1595                list_frame->samples,
1596                sizeof(double) * list_frame->samples_length);
1597 
1598         Py_DECREF(list_frame_obj);
1599     }
1600 
1601     return (PyObject*)output_frame;
1602 }
1603 
1604 PyObject*
FloatFrameList_from_channels(PyObject * dummy,PyObject * args)1605 FloatFrameList_from_channels(PyObject *dummy, PyObject *args)
1606 {
1607     PyObject *list;
1608     Py_ssize_t list_len, i;
1609     pcm_FloatFrameList *output_frame;
1610     PyObject *initial_frame_obj;
1611     pcm_FloatFrameList *initial_frame;
1612     unsigned j;
1613 
1614     if (!PyArg_ParseTuple(args, "O", &list)) {
1615         return NULL;
1616     }
1617 
1618     if ((list_len = PySequence_Size(list)) == -1) {
1619         return NULL;
1620     }
1621 
1622     /*get first FloatFrameList as a base for its frames values*/
1623     if ((initial_frame_obj = PySequence_GetItem(list, 0)) == NULL) {
1624         return NULL;
1625     }
1626 
1627     if (FloatFrameList_CheckExact(initial_frame_obj)) {
1628         initial_frame = (pcm_FloatFrameList*)initial_frame_obj;
1629     } else {
1630         PyErr_SetString(PyExc_TypeError,
1631                         "channels must be of type FloatFrameList");
1632         Py_DECREF(initial_frame_obj);
1633         return NULL;
1634     }
1635 
1636     if (initial_frame->channels != 1) {
1637         PyErr_SetString(PyExc_ValueError,
1638                         "all channels must be 1 channel wide");
1639         Py_DECREF(initial_frame_obj);
1640         return NULL;
1641     }
1642 
1643     /*create output FloatFrameList from initial values*/
1644     output_frame = FloatFrameList_create();
1645     output_frame->frames = initial_frame->frames;
1646     output_frame->channels = (unsigned int)list_len;
1647     output_frame->samples_length =
1648         output_frame->frames * output_frame->channels;
1649     output_frame->samples =
1650         PyMem_Malloc(sizeof(double) * output_frame->samples_length);
1651 
1652     for (j = 0; j < initial_frame->samples_length; j++) {
1653         output_frame->samples[j * list_len] = initial_frame->samples[j];
1654     }
1655 
1656     /*we're done with initial frame*/
1657     Py_DECREF(initial_frame_obj);
1658 
1659     /*process remaining FloatFrameLists in list*/
1660     for (i = 1; i < list_len; i++) {
1661         PyObject *list_frame_obj;
1662         pcm_FloatFrameList *list_frame;
1663 
1664         if ((list_frame_obj = PySequence_GetItem(list, i)) == NULL) {
1665             Py_DECREF((PyObject*)output_frame);
1666             return NULL;
1667         }
1668 
1669         if (FloatFrameList_CheckExact(list_frame_obj)) {
1670             list_frame = (pcm_FloatFrameList*)list_frame_obj;
1671         } else {
1672             Py_DECREF((PyObject*)output_frame);
1673             Py_DECREF(list_frame_obj);
1674             PyErr_SetString(PyExc_TypeError,
1675                             "channels must be of type FloatFrameList");
1676             return NULL;
1677         }
1678 
1679         if (list_frame->channels != 1) {
1680             Py_DECREF((PyObject*)output_frame);
1681             Py_DECREF(list_frame_obj);
1682             PyErr_SetString(PyExc_ValueError,
1683                             "all channels must be 1 channel wide");
1684             return NULL;
1685         }
1686 
1687         if (output_frame->frames != list_frame->frames) {
1688             Py_DECREF((PyObject*)output_frame);
1689             Py_DECREF(list_frame_obj);
1690             PyErr_SetString(PyExc_ValueError,
1691                             "all channels must have the same "
1692                             "number of frames");
1693             return NULL;
1694         }
1695 
1696         for (j = 0; j < list_frame->samples_length; j++) {
1697             output_frame->samples[(j * list_len) + i] = list_frame->samples[j];
1698         }
1699 
1700         Py_DECREF(list_frame_obj);
1701     }
1702 
1703     return (PyObject*)output_frame;
1704 }
1705 
1706 int
FloatFrameList_converter(PyObject * obj,void ** floatframelist)1707 FloatFrameList_converter(PyObject* obj, void** floatframelist)
1708 {
1709     if (PyObject_TypeCheck(obj, &pcm_FloatFrameListType)) {
1710         *floatframelist = obj;
1711         return 1;
1712     } else {
1713         PyErr_SetString(PyExc_TypeError, "not a FloatFrameList object");
1714         return 0;
1715     }
1716 }
1717 
MOD_INIT(pcm)1718 MOD_INIT(pcm)
1719 {
1720     PyObject* m;
1721 
1722     MOD_DEF(m, "pcm", "a PCM FrameList handling module", module_methods)
1723 
1724     if (!m)
1725         return MOD_ERROR_VAL;
1726 
1727     pcm_FrameListType.tp_new = PyType_GenericNew;
1728     if (PyType_Ready(&pcm_FrameListType) < 0)
1729         return MOD_ERROR_VAL;
1730 
1731     pcm_FloatFrameListType.tp_new = PyType_GenericNew;
1732     if (PyType_Ready(&pcm_FloatFrameListType) < 0)
1733         return MOD_ERROR_VAL;
1734 
1735     Py_INCREF(&pcm_FrameListType);
1736     PyModule_AddObject(m, "FrameList",
1737                        (PyObject *)&pcm_FrameListType);
1738     Py_INCREF(&pcm_FloatFrameListType);
1739     PyModule_AddObject(m, "FloatFrameList",
1740                        (PyObject *)&pcm_FloatFrameListType);
1741 
1742     return MOD_SUCCESS_VAL(m);
1743 }
1744 
1745 #endif
1746 
1747 FrameList_char_to_int_converter
FrameList_get_char_to_int_converter(int bits_per_sample,int is_big_endian,int is_signed)1748 FrameList_get_char_to_int_converter(int bits_per_sample,
1749                                     int is_big_endian,
1750                                     int is_signed)
1751 {
1752     switch (bits_per_sample) {
1753     case 8:
1754         switch (is_big_endian) {
1755         case 0:
1756             switch (is_signed) {
1757             case 0:  /*8 bits-per-sample, little-endian, unsigned*/
1758                 return FrameList_U8_char_to_int;
1759             default: /*8 bits-per-sample, little-endian, signed*/
1760                 return FrameList_S8_char_to_int;
1761             }
1762         default:
1763             switch (is_signed) {
1764             case 0:  /*8 bits-per-sample, big-endian, unsigned*/
1765                 return FrameList_U8_char_to_int;
1766             default: /*8 bits-per-sample, big-endian, signed*/
1767                 return FrameList_S8_char_to_int;
1768             }
1769         }
1770     case 16:
1771         switch (is_big_endian) {
1772         case 0:
1773             switch (is_signed) {
1774             case 0:  /*16 bits-per-sample, little-endian, unsigned*/
1775                 return FrameList_UL16_char_to_int;
1776             default: /*16 bits-per-sample, little-endian, signed*/
1777                 return FrameList_SL16_char_to_int;
1778             }
1779         default:
1780             switch (is_signed) {
1781             case 0:  /*16 bits-per-sample, big-endian, unsigned*/
1782                 return FrameList_UB16_char_to_int;
1783             default: /*16 bits-per-sample, big-endian, signed*/
1784                 return FrameList_SB16_char_to_int;
1785             }
1786         }
1787     case 24:
1788         switch (is_big_endian) {
1789         case 0:
1790             switch (is_signed) {
1791             case 0:  /*24 bits-per-sample, little-endian, unsigned*/
1792                 return FrameList_UL24_char_to_int;
1793             default: /*24 bits-per-sample, little-endian, signed*/
1794                 return FrameList_SL24_char_to_int;
1795             }
1796         default:
1797             switch (is_signed) {
1798             case 0:  /*24 bits-per-sample, big-endian, unsigned*/
1799                 return FrameList_UB24_char_to_int;
1800             default: /*24 bits-per-sample, big-endian, signed*/
1801                 return FrameList_SB24_char_to_int;
1802             }
1803         }
1804     default:
1805         return NULL;
1806     }
1807 }
1808 
1809 int
FrameList_U8_char_to_int(unsigned char * s)1810 FrameList_U8_char_to_int(unsigned char *s)
1811 {
1812     return ((int)s[0]) - (1 << 7);
1813 }
1814 
1815 int
FrameList_S8_char_to_int(unsigned char * s)1816 FrameList_S8_char_to_int(unsigned char *s)
1817 {
1818     if (s[0] & 0x80) {
1819         /*negative*/
1820         return -(int)(0x100 - s[0]);
1821     } else {
1822         /*positive*/
1823         return (int)s[0];
1824     }
1825 }
1826 
1827 int
FrameList_UB16_char_to_int(unsigned char * s)1828 FrameList_UB16_char_to_int(unsigned char *s)
1829 {
1830     return ((int)(s[0] << 8) | s[1]) - (1 << 15);
1831 }
1832 
1833 int
FrameList_UL16_char_to_int(unsigned char * s)1834 FrameList_UL16_char_to_int(unsigned char *s)
1835 {
1836     return ((int)(s[1] << 8) | s[0]) - (1 << 15);
1837 }
1838 
1839 int
FrameList_SL16_char_to_int(unsigned char * s)1840 FrameList_SL16_char_to_int(unsigned char *s)
1841 {
1842     if (s[1] & 0x80) {
1843         /*negative*/
1844         return -(int)(0x10000 - ((s[1] << 8) | s[0]));
1845     } else {
1846         /*positive*/
1847         return (int)(s[1] << 8) | s[0];
1848     }
1849 }
1850 
1851 int
FrameList_SB16_char_to_int(unsigned char * s)1852 FrameList_SB16_char_to_int(unsigned char *s)
1853 {
1854     if (s[0] & 0x80) {
1855         /*negative*/
1856         return -(int)(0x10000 - ((s[0] << 8) | s[1]));
1857     } else {
1858         /*positive*/
1859         return (int)(s[0] << 8) | s[1];
1860     }
1861 }
1862 
1863 int
FrameList_UL24_char_to_int(unsigned char * s)1864 FrameList_UL24_char_to_int(unsigned char *s)
1865 {
1866     return ((int)((s[2] << 16) | (s[1] << 8) | s[0])) - (1 << 23);
1867 }
1868 
1869 int
FrameList_UB24_char_to_int(unsigned char * s)1870 FrameList_UB24_char_to_int(unsigned char *s)
1871 {
1872     return ((int)((s[0] << 16) | (s[1] << 8) | s[2])) - (1 << 23);
1873 }
1874 
1875 int
FrameList_SL24_char_to_int(unsigned char * s)1876 FrameList_SL24_char_to_int(unsigned char *s)
1877 {
1878     if (s[2] & 0x80) {
1879         /*negative*/
1880         return -(int)(0x1000000 - ((s[2] << 16) | (s[1] << 8) | s[0]));
1881     } else {
1882         /*positive*/
1883         return (int)((s[2] << 16) | (s[1] << 8) | s[0]);
1884     }
1885 }
1886 
1887 int
FrameList_SB24_char_to_int(unsigned char * s)1888 FrameList_SB24_char_to_int(unsigned char *s)
1889 {
1890     if (s[0] & 0x80) {
1891         /*negative*/
1892         return -(int)(0x1000000 - ((s[0] << 16) | (s[1] << 8) | s[2]));
1893     } else {
1894         /*positive*/
1895         return (int)((s[0] << 16) | (s[1] << 8) | s[2]);
1896     }
1897 }
1898 
1899 void
FrameList_samples_to_char(unsigned char * data,int * samples,FrameList_int_to_char_converter converter,unsigned samples_length,int bits_per_sample)1900 FrameList_samples_to_char(unsigned char *data,
1901                           int *samples,
1902                           FrameList_int_to_char_converter converter,
1903                           unsigned samples_length,
1904                           int bits_per_sample)
1905 {
1906     int bytes_per_sample = bits_per_sample / 8;
1907     int i;
1908 
1909     for (i = 0; i < samples_length; i++, data += bytes_per_sample) {
1910         converter(samples[i], data);
1911     }
1912 }
1913 
1914 FrameList_int_to_char_converter
FrameList_get_int_to_char_converter(int bits_per_sample,int is_big_endian,int is_signed)1915 FrameList_get_int_to_char_converter(int bits_per_sample,
1916                                     int is_big_endian,
1917                                     int is_signed)
1918 {
1919     switch (bits_per_sample) {
1920     case 8:
1921         switch (is_big_endian) {
1922         case 0:
1923             switch (is_signed) {
1924             case 0:  /*8 bits-per-sample, little-endian, unsigned*/
1925                 return FrameList_int_to_U8_char;
1926             default: /*8 bits-per-sample, little-endian, signed*/
1927                 return FrameList_int_to_S8_char;
1928             }
1929         default:
1930             switch (is_signed) {
1931             case 0:  /*8 bits-per-sample, big-endian, unsigned*/
1932                 return FrameList_int_to_U8_char;
1933             default: /*8 bits-per-sample, big-endian, signed*/
1934                 return FrameList_int_to_S8_char;
1935             }
1936         }
1937     case 16:
1938         switch (is_big_endian) {
1939         case 0:
1940             switch (is_signed) {
1941             case 0:  /*16 bits-per-sample, little-endian, unsigned*/
1942                 return FrameList_int_to_UL16_char;
1943             default: /*16 bits-per-sample, little-endian, signed*/
1944                 return FrameList_int_to_SL16_char;
1945             }
1946         default:
1947             switch (is_signed) {
1948             case 0:  /*16 bits-per-sample, big-endian, unsigned*/
1949                 return FrameList_int_to_UB16_char;
1950             default: /*16 bits-per-sample, big-endian, signed*/
1951                 return FrameList_int_to_SB16_char;
1952             }
1953         }
1954     case 24:
1955         switch (is_big_endian) {
1956         case 0:
1957             switch (is_signed) {
1958             case 0:  /*24 bits-per-sample, little-endian, unsigned*/
1959                 return FrameList_int_to_UL24_char;
1960             default: /*24 bits-per-sample, little-endian, signed*/
1961                 return FrameList_int_to_SL24_char;
1962             }
1963         default:
1964             switch (is_signed) {
1965             case 0:  /*24 bits-per-sample, big-endian, unsigned*/
1966                 return FrameList_int_to_UB24_char;
1967             default: /*24 bits-per-sample, big-endian, signed*/
1968                 return FrameList_int_to_SB24_char;
1969             }
1970         }
1971     default:
1972         return NULL;
1973     }
1974 }
1975 
1976 void
FrameList_int_to_S8_char(int i,unsigned char * s)1977 FrameList_int_to_S8_char(int i, unsigned char *s)
1978 {
1979     if (i > 0x7F)
1980         i = 0x7F;  /*avoid overflow*/
1981     else if (i < -0x80)
1982         i = -0x80; /*avoid underflow*/
1983 
1984     if (i >= 0) {
1985         /*positive*/
1986         s[0] = i;
1987     } else {
1988         /*negative*/
1989         s[0] = (1 << 8) - (-i);
1990     }
1991 }
1992 
1993 void
FrameList_int_to_U8_char(int i,unsigned char * s)1994 FrameList_int_to_U8_char(int i, unsigned char *s)
1995 {
1996     i += (1 << 7);
1997     s[0] = i & 0xFF;
1998 }
1999 
2000 void
FrameList_int_to_UB16_char(int i,unsigned char * s)2001 FrameList_int_to_UB16_char(int i, unsigned char *s)
2002 {
2003     i += (1 << 15);
2004     s[0] = (i >> 8) & 0xFF;
2005     s[1] = i & 0xFF;
2006 }
2007 
2008 void
FrameList_int_to_SB16_char(int i,unsigned char * s)2009 FrameList_int_to_SB16_char(int i, unsigned char *s)
2010 {
2011     if (i > 0x7FFF)
2012         i = 0x7FFF;
2013     else if (i < -0x8000)
2014         i = -0x8000;
2015 
2016     if (i < 0) {
2017         i = (1 << 16) - (-i);
2018     }
2019 
2020     s[0] = i >> 8;
2021     s[1] = i & 0xFF;
2022 }
2023 
2024 void
FrameList_int_to_UL16_char(int i,unsigned char * s)2025 FrameList_int_to_UL16_char(int i, unsigned char *s)
2026 {
2027     i += (1 << 15);
2028     s[1] = (i >> 8) & 0xFF;
2029     s[0] = i & 0xFF;
2030 }
2031 
2032 void
FrameList_int_to_SL16_char(int i,unsigned char * s)2033 FrameList_int_to_SL16_char(int i, unsigned char *s)
2034 {
2035     if (i > 0x7FFF)
2036         i = 0x7FFF;
2037     else if (i < -0x8000)
2038         i = -0x8000;
2039 
2040     if (i < 0) {
2041         i = (1 << 16) - (-i);
2042     }
2043 
2044     s[1] = i >> 8;
2045     s[0] = i & 0xFF;
2046 }
2047 
2048 void
FrameList_int_to_UB24_char(int i,unsigned char * s)2049 FrameList_int_to_UB24_char(int i, unsigned char *s)
2050 {
2051     i += (1 << 23);
2052     s[0] = (i >> 16) & 0xFF;
2053     s[1] = (i >> 8) & 0xFF;
2054     s[2] = i & 0xFF;
2055 }
2056 
2057 void
FrameList_int_to_SB24_char(int i,unsigned char * s)2058 FrameList_int_to_SB24_char(int i, unsigned char *s)
2059 {
2060     if (i > 0x7FFFFF)
2061         i = 0x7FFFFF;
2062     else if (i < -0x800000)
2063         i = -0x800000;
2064 
2065     if (i < 0) {
2066         i = (1 << 24) - (-i);
2067     }
2068 
2069     s[0] = i >> 16;
2070     s[1] = (i >> 8) & 0xFF;
2071     s[2] = i & 0xFF;
2072 }
2073 
2074 void
FrameList_int_to_UL24_char(int i,unsigned char * s)2075 FrameList_int_to_UL24_char(int i, unsigned char *s)
2076 {
2077     i += (1 << 23);
2078     s[2] = (i >> 16) & 0xFF;
2079     s[1] = (i >> 8) & 0xFF;
2080     s[0] = i & 0xFF;
2081 }
2082 
2083 void
FrameList_int_to_SL24_char(int i,unsigned char * s)2084 FrameList_int_to_SL24_char(int i, unsigned char *s)
2085 {
2086     if (i > 0x7FFFFF)
2087         i = 0x7FFFFF;
2088     else if (i < -0x800000)
2089         i = -0x800000;
2090 
2091     if (i < 0) {
2092         i = (1 << 24) - (-i);
2093     }
2094 
2095     s[2] = i >> 16;
2096     s[1] = (i >> 8) & 0xFF;
2097     s[0] = i & 0xFF;
2098 }
2099