1 #ifndef STANDALONE
2 #include <Python.h>
3 #endif
4 #include "array.h"
5 #include "pcm.h"
6 #include <stdint.h>
7 
8 /********************************************************
9  Audio Tools, a module and set of tools for manipulating audio data
10  Copyright (C) 2007-2014  Brian Langenberger
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25 *******************************************************/
26 
27 #ifndef STANDALONE
28 /******************************************************
29                array_* to FrameList utilities
30 *******************************************************/
31 
32 
33 /*returns an audiotools.pcm module object for generating blank FrameLists
34   or NULL on error
35   this must be PyXDECREF()ed once no longer needed*/
36 PyObject*
37 open_audiotools_pcm(void);
38 
39 /*given a list of flattened PCM data,
40   returns a new FrameList object containing that data
41   with the given number of channels and bits per sample
42   which Python will presumably DECREF once no longer needed
43   or returns NULL with an exception set on error*/
44 PyObject*
45 a_int_to_FrameList(PyObject* audiotools_pcm,
46                    a_int* samples,
47                    unsigned int channels,
48                    unsigned int bits_per_sample);
49 
50 /*given a list of channel data lists,
51   returns a new FrameList object
52   which Python will presumably DECREF once no longer needed
53   or returns NULL with an exception set on error*/
54 PyObject*
55 aa_int_to_FrameList(PyObject* audiotools_pcm,
56                     aa_int* channels,
57                     unsigned int bits_per_sample);
58 
59 /*returns an empty FrameList object with the given number of channels
60   typically returned at the end of a stream*/
61 PyObject*
62 empty_FrameList(PyObject* audiotools_pcm,
63                 unsigned int channels,
64                 unsigned int bits_per_sample);
65 
66 
67 /******************************************************
68                PCMReader to array_ia utilities
69 *******************************************************/
70 
71 
72 struct pcmreader_callback;
73 struct pcmreader_s;
74 
75 /*wraps a low-level pcmreader object
76   around the given Python PCMReader object
77   or returns NULL with an exception set
78   if an error occurs during the wrapping procedure
79 
80   the object should be deallocated with  reader->del(reader)  when finished
81 
82   Python object is INCREFed by this function
83   and DECREFed by del() once no longer in use*/
84 struct pcmreader_s*
85 open_pcmreader(PyObject* pcmreader);
86 
87 /*for use with the PyArg_ParseTuple function*/
88 int
89 pcmreader_converter(PyObject* obj, void** pcmreader);
90 
91 typedef struct pcmreader_s {
92     PyObject* pcmreader_obj;
93     PyObject* framelist_type;
94 
95     unsigned int sample_rate;
96     unsigned int channels;
97     unsigned int channel_mask;
98     unsigned int bits_per_sample;
99     unsigned int bytes_per_sample;
100 
101     struct pcmreader_callback* callbacks;
102 
103     /*reads up to the given number of PCM frames
104       to the given set of channel data
105       which is reset and appended to as needed
106 
107       returns 0 on success, 1 if there's an exception during reading*/
108     int (*read)(struct pcmreader_s* reader,
109                 unsigned pcm_frames,
110                 aa_int* channels);
111 
112     /*forwards a call to "close" to the wrapped PCMReader object*/
113     void (*close)(struct pcmreader_s* reader);
114 
115     /*adds a callback function to be called on each successful read()
116       its first argument is user data
117       the second is the PCM data as a string
118       with the given signed/endianness values
119       the third is the length of that PCM data in bytes*/
120     void (*add_callback)(struct pcmreader_s* reader,
121                          void (*callback)(void*, unsigned char*, unsigned long),
122                          void *user_data,
123                          int is_signed,
124                          int little_endian);
125 
126     /*deletes and decrefs any attached callbacks
127       clears any attached buffer
128       and decrefs any wrapped PCMReader objects*/
129     void (*del)(struct pcmreader_s* reader);
130 } pcmreader;
131 
132 #else
133 
134 struct pcmreader_callback;
135 struct pcmreader_s;
136 
137 /*wraps a low-level pcmreader object
138   around the given file object of PCM data
139 
140   the object should be deallocated with  reader->del(reader)  when finished*/
141 struct pcmreader_s* open_pcmreader(FILE* file,
142                                    unsigned int sample_rate,
143                                    unsigned int channels,
144                                    unsigned int channel_mask,
145                                    unsigned int bits_per_sample,
146                                    unsigned int big_endian,
147                                    unsigned int is_signed);
148 
149 typedef struct pcmreader_s {
150     FILE* file;
151 
152     unsigned int sample_rate;
153     unsigned int channels;
154     unsigned int channel_mask;
155     unsigned int bits_per_sample;
156     unsigned int bytes_per_sample;
157 
158     unsigned int big_endian;
159     unsigned int is_signed;
160 
161     unsigned buffer_size;
162     uint8_t* buffer;
163     unsigned callback_buffer_size;
164     uint8_t* callback_buffer;
165     FrameList_char_to_int_converter buffer_converter;
166 
167     struct pcmreader_callback* callbacks;
168 
169     /*reads up to the given number of PCM frames
170       to the given set of channel data
171       which is reset and appended to as needed
172 
173       returns 0 on success, 1 if there's an exception during reading*/
174     int (*read)(struct pcmreader_s* reader,
175                  unsigned pcm_frames,
176                  aa_int* channels);
177 
178     /*forwards a call to "close" to the wrapped PCMReader object*/
179     void (*close)(struct pcmreader_s* reader);
180 
181     /*adds a callback function to be called on each successful read()
182       its first argument is user data
183       the second is the PCM data as a string
184       with the given signed/endianness values
185       the third is the length of that PCM data in bytes*/
186     void (*add_callback)(struct pcmreader_s* reader,
187                          void (*callback)(void*, unsigned char*, unsigned long),
188                          void *user_data,
189                          int is_signed,
190                          int little_endian);
191 
192     /*deletes and decrefs any attached callbacks
193       clears any attached buffer
194       and decrefs any wrapped PCMReader objects*/
195     void (*del)(struct pcmreader_s* reader);
196 } pcmreader;
197 
198 #endif
199 
200 int pcmreader_read(struct pcmreader_s* reader,
201                    unsigned pcm_frames,
202                    aa_int* channels);
203 
204 void pcmreader_close(struct pcmreader_s* reader);
205 
206 void pcmreader_add_callback(struct pcmreader_s* reader,
207                             void (*callback)(void*,
208                                              unsigned char*,
209                                              unsigned long),
210                             void *user_data,
211                             int is_signed,
212                             int little_endian);
213 
214 void pcmreader_del(struct pcmreader_s* reader);
215 
216 struct pcmreader_callback {
217     void (*callback)(void*, unsigned char*, unsigned long);
218     int is_signed;
219     int little_endian;
220     void *user_data;
221     struct pcmreader_callback *next;
222 };
223