1 #include <Python.h>
2 #include <cdio/paranoia/cdda.h>
3 #include <cdio/paranoia/paranoia.h>
4 #include "array.h"
5 
6 /********************************************************
7  Audio Tools, a module and set of tools for manipulating audio data
8  Copyright (C) 2007-2014  Brian Langenberger
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 *******************************************************/
24 
25 static PyMethodDef cdioMethods[] = {
26     {NULL, NULL, 0, NULL}  /*sentinel*/
27 };
28 
29 struct cdio_log {
30     int read;
31     int verify;
32     int fixup_edge;
33     int fixup_atom;
34     int scratch;
35     int repair;
36     int skip;
37     int drift;
38     int backoff;
39     int overlap;
40     int fixup_dropped;
41     int fixup_duped;
42     int readerr;
43 };
44 
45 /*global pointer to the current cdio_log state
46   to be used by the cddareader_callback*/
47 struct cdio_log *log_state = NULL;
48 
49 static void
50 cddareader_callback(long int i, paranoia_cb_mode_t mode);
51 
52 /*audiotools.cdio.CDDAReader object*/
53 typedef struct cdio_CDDAReader_s {
54     PyObject_HEAD
55     int is_cd_image;
56     int is_logging;
57     struct cdio_log log;
58     union {
59         struct {
60             CdIo_t *image;
61             lsn_t current_sector;
62             lsn_t final_sector;
63         } image;
64         struct {
65             cdrom_drive_t *drive;
66             cdrom_paranoia_t *paranoia;
67             lsn_t current_sector;
68             lsn_t final_sector;
69         } drive;
70     } _;
71     int (*first_track_num)(struct cdio_CDDAReader_s *self);
72     int (*last_track_num)(struct cdio_CDDAReader_s *self);
73     int (*track_lsn)(struct cdio_CDDAReader_s *self, int track_num);
74     int (*track_last_lsn)(struct cdio_CDDAReader_s *self, int track_num);
75     int (*first_sector)(struct cdio_CDDAReader_s *self);
76     int (*last_sector)(struct cdio_CDDAReader_s *self);
77     int (*read)(struct cdio_CDDAReader_s *self,
78                 unsigned to_read,
79                 a_int *samples);
80     unsigned (*seek)(struct cdio_CDDAReader_s *self, unsigned sector);
81     void (*set_speed)(struct cdio_CDDAReader_s *self, int new_speed);
82     void (*dealloc)(struct cdio_CDDAReader_s *self);
83 
84     int closed;
85     PyObject *audiotools_pcm;
86 } cdio_CDDAReader;
87 
88 static PyObject*
89 CDDAReader_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
90 
91 static int
92 CDDAReader_init(cdio_CDDAReader *self, PyObject *args, PyObject *kwds);
93 
94 static int
95 CDDAReader_init_image(cdio_CDDAReader *self, const char *device);
96 
97 static int
98 CDDAReader_init_device(cdio_CDDAReader *self, const char *device);
99 
100 static void
101 CDDAReader_dealloc(cdio_CDDAReader *self);
102 
103 static void
104 CDDAReader_dealloc_image(cdio_CDDAReader *self);
105 
106 static void
107 CDDAReader_dealloc_device(cdio_CDDAReader *self);
108 
109 static PyObject*
110 CDDAReader_sample_rate(cdio_CDDAReader *self, void *closure);
111 
112 static PyObject*
113 CDDAReader_bits_per_sample(cdio_CDDAReader *self, void *closure);
114 
115 static PyObject*
116 CDDAReader_channels(cdio_CDDAReader *self, void *closure);
117 
118 static PyObject*
119 CDDAReader_channel_mask(cdio_CDDAReader *self, void *closure);
120 
121 static PyObject*
122 CDDAReader_is_cd_image(cdio_CDDAReader *self, void *closure);
123 
124 static int
125 CDDAReader_first_track_num_image(cdio_CDDAReader *self);
126 
127 static int
128 CDDAReader_first_track_num_device(cdio_CDDAReader *self);
129 
130 static int
131 CDDAReader_last_track_num_image(cdio_CDDAReader *self);
132 
133 static int
134 CDDAReader_last_track_num_device(cdio_CDDAReader *self);
135 
136 static int
137 CDDAReader_track_lsn_image(cdio_CDDAReader *self, int track_num);
138 
139 static int
140 CDDAReader_track_lsn_device(cdio_CDDAReader *self, int track_num);
141 
142 static int
143 CDDAReader_track_last_lsn_image(cdio_CDDAReader *self, int track_num);
144 
145 static int
146 CDDAReader_track_last_lsn_device(cdio_CDDAReader *self, int track_num);
147 
148 static PyObject*
149 CDDAReader_track_offsets(cdio_CDDAReader *self, void *closure);
150 
151 static PyObject*
152 CDDAReader_track_lengths(cdio_CDDAReader *self, void *closure);
153 
154 static PyObject*
155 CDDAReader_first_sector(cdio_CDDAReader *self, void *closure);
156 
157 static int
158 CDDAReader_first_sector_image(cdio_CDDAReader *self);
159 
160 static int
161 CDDAReader_first_sector_device(cdio_CDDAReader *self);
162 
163 static PyObject*
164 CDDAReader_last_sector(cdio_CDDAReader *self, void *closure);
165 
166 static int
167 CDDAReader_last_sector_image(cdio_CDDAReader *self);
168 
169 static int
170 CDDAReader_last_sector_device(cdio_CDDAReader *self);
171 
172 static PyGetSetDef CDDAReader_getseters[] = {
173     {"sample_rate",
174      (getter)CDDAReader_sample_rate, NULL, "sample rate", NULL},
175     {"bits_per_sample",
176      (getter)CDDAReader_bits_per_sample, NULL, "bits per sample", NULL},
177     {"channels",
178      (getter)CDDAReader_channels, NULL, "channels", NULL},
179     {"channel_mask",
180      (getter)CDDAReader_channel_mask, NULL, "channel mask", NULL},
181     {"is_cd_image",
182      (getter)CDDAReader_is_cd_image, NULL, "is CD image", NULL},
183     {"track_offsets",
184      (getter)CDDAReader_track_offsets, NULL, "track offsets", NULL},
185     {"track_lengths",
186      (getter)CDDAReader_track_lengths, NULL, "track lengths", NULL},
187     {"first_sector",
188      (getter)CDDAReader_first_sector, NULL, "first sector", NULL},
189     {"last_sector",
190      (getter)CDDAReader_last_sector, NULL, "last sector", NULL},
191     {NULL}
192 };
193 
194 static PyObject*
195 CDDAReader_read(cdio_CDDAReader* self, PyObject *args);
196 
197 static int
198 CDDAReader_read_image(cdio_CDDAReader *self,
199                       unsigned sectors_to_read,
200                       a_int *samples);
201 
202 static int
203 CDDAReader_read_device(cdio_CDDAReader *self,
204                        unsigned sectors_to_read,
205                        a_int *samples);
206 
207 static PyObject*
208 CDDAReader_seek(cdio_CDDAReader* self, PyObject *args);
209 
210 static unsigned
211 CDDAReader_seek_image(cdio_CDDAReader *self, unsigned sector);
212 
213 static unsigned
214 CDDAReader_seek_device(cdio_CDDAReader *self, unsigned sector);
215 
216 static PyObject*
217 CDDAReader_close(cdio_CDDAReader* self, PyObject *args);
218 
219 static PyObject*
220 CDDAReader_set_speed(cdio_CDDAReader *self, PyObject *args);
221 
222 static void
223 CDDAReader_set_speed_image(cdio_CDDAReader *self, int new_speed);
224 
225 static void
226 CDDAReader_set_speed_device(cdio_CDDAReader *self, int new_speed);
227 
228 static int
229 cddareader_set_log_item(PyObject *dict, const char *key, int value);
230 
231 static PyObject*
232 CDDAReader_log(cdio_CDDAReader *self, PyObject *args);
233 
234 static PyObject*
235 CDDAReader_reset_log(cdio_CDDAReader *self, PyObject *args);
236 
237 static void
238 cddareader_reset_log(struct cdio_log *log);
239 
240 static PyMethodDef CDDAReader_methods[] = {
241     {"read", (PyCFunction)CDDAReader_read,
242      METH_VARARGS, "read(pcm_frames) -> Framelist"},
243     {"seek", (PyCFunction)CDDAReader_seek,
244      METH_VARARGS, "seek(pcm_frames)"},
245     {"close", (PyCFunction)CDDAReader_close,
246      METH_NOARGS, "closes CD stream"},
247     {"set_speed", (PyCFunction)CDDAReader_set_speed,
248      METH_VARARGS, "set_speed(speed)"},
249     {"log", (PyCFunction)CDDAReader_log,
250      METH_NOARGS, "log() -> {item:value, ...}"},
251     {"reset_log", (PyCFunction)CDDAReader_reset_log,
252      METH_NOARGS, "resets read log"},
253     {NULL}
254 };
255 
256 static PyTypeObject cdio_CDDAReaderType = {
257     PyVarObject_HEAD_INIT(NULL, 0)
258     "cdio.CDDAReader",         /*tp_name*/
259     sizeof(cdio_CDDAReader),   /*tp_basicsize*/
260     0,                         /*tp_itemsize*/
261     (destructor)CDDAReader_dealloc, /*tp_dealloc*/
262     0,                         /*tp_print*/
263     0,                         /*tp_getattr*/
264     0,                         /*tp_setattr*/
265     0,                         /*tp_compare*/
266     0,                         /*tp_repr*/
267     0,                         /*tp_as_number*/
268     0,                         /*tp_as_sequence*/
269     0,                         /*tp_as_mapping*/
270     0,                         /*tp_hash */
271     0,                         /*tp_call*/
272     0,                         /*tp_str*/
273     0,                         /*tp_getattro*/
274     0,                         /*tp_setattro*/
275     0,                         /*tp_as_buffer*/
276     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
277     "CDDAReader objects",      /* tp_doc */
278     0,                         /* tp_traverse */
279     0,                         /* tp_clear */
280     0,                         /* tp_richcompare */
281     0,                         /* tp_weaklistoffset */
282     0,                         /* tp_iter */
283     0,                         /* tp_iternext */
284     CDDAReader_methods,        /* tp_methods */
285     0,                         /* tp_members */
286     CDDAReader_getseters,      /* tp_getset */
287     0,                         /* tp_base */
288     0,                         /* tp_dict */
289     0,                         /* tp_descr_get */
290     0,                         /* tp_descr_set */
291     0,                         /* tp_dictoffset */
292     (initproc)CDDAReader_init, /* tp_init */
293     0,                         /* tp_alloc */
294     CDDAReader_new,            /* tp_new */
295 };
296