1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
4
5 All Rights Reserved
6
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
16
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
20
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
29
30 ******************************************************************/
31
32 #include "Python.h"
33 #include "pymactoolbox.h"
34 #include <Sound.h>
35
36 #pragma options align=mac68k
37 struct SampleRateAvailable_arg {
38 short numrates;
39 Handle rates;
40 };
41
42 struct SampleSizeAvailable_arg {
43 short numsizes;
44 Handle sizes;
45 };
46
47 #pragma options align=reset
48
49 static PyObject *ErrorObject;
50
51
52 /* Convert Python object to unsigned Fixed */
53 static int
PyMac_GetUFixed(PyObject * v,Fixed * f)54 PyMac_GetUFixed(PyObject *v, Fixed *f)
55 {
56 double d;
57 unsigned long uns;
58
59 if( !PyArg_Parse(v, "d", &d))
60 return 0;
61 uns = (unsigned long)(d * 0x10000);
62 *f = (Fixed)uns;
63 return 1;
64 }
65
66 /* Convert a Point to a Python object */
67 static PyObject *
PyMac_BuildUFixed(Fixed f)68 PyMac_BuildUFixed(Fixed f)
69 {
70 double d;
71 unsigned long funs;
72
73 funs = (unsigned long)f;
74
75 d = funs;
76 d = d / 0x10000;
77 return Py_BuildValue("d", d);
78 }
79
80
81 /* ----------------------------------------------------- */
82
83 static char sndih_getChannelAvailable__doc__[] =
84 ""
85 ;
86
87 static PyObject *
sndih_getChannelAvailable(self,args)88 sndih_getChannelAvailable(self, args)
89 PyObject *self; /* Not used */
90 PyObject *args;
91 {
92 long inRefNum;
93 short nchannel;
94 OSErr err;
95
96 if (!PyArg_ParseTuple(args, "l", &inRefNum))
97 return NULL;
98
99 if( (err=SPBGetDeviceInfo(inRefNum, siChannelAvailable, (Ptr)&nchannel)) != noErr )
100 return PyMac_Error(err);
101 return Py_BuildValue("h", nchannel);
102 }
103
104 static char sndih_getNumberChannels__doc__[] =
105 ""
106 ;
107
108 static PyObject *
sndih_getNumberChannels(self,args)109 sndih_getNumberChannels(self, args)
110 PyObject *self; /* Not used */
111 PyObject *args;
112 {
113 long inRefNum;
114 short nchannel;
115 OSErr err;
116
117 if (!PyArg_ParseTuple(args, "l", &inRefNum))
118 return NULL;
119
120 if( (err=SPBGetDeviceInfo(inRefNum, siNumberChannels, (Ptr)&nchannel)) != noErr )
121 return PyMac_Error(err);
122 return Py_BuildValue("h", nchannel);
123 }
124
125 static char sndih_setNumberChannels__doc__[] =
126 ""
127 ;
128
129 static PyObject *
sndih_setNumberChannels(self,args)130 sndih_setNumberChannels(self, args)
131 PyObject *self; /* Not used */
132 PyObject *args;
133 {
134 long inRefNum;
135 short nchannel;
136 OSErr err;
137
138 if (!PyArg_ParseTuple(args, "lh", &inRefNum, &nchannel))
139 return NULL;
140
141 if( (err=SPBSetDeviceInfo(inRefNum, siNumberChannels, (Ptr)&nchannel)) != noErr )
142 return PyMac_Error(err);
143 Py_INCREF(Py_None);
144 return Py_None;
145 }
146
147 static char sndih_getContinuous__doc__[] =
148 ""
149 ;
150
151 static PyObject *
sndih_getContinuous(self,args)152 sndih_getContinuous(self, args)
153 PyObject *self; /* Not used */
154 PyObject *args;
155 {
156 long inRefNum;
157 short onoff;
158 OSErr err;
159
160 if (!PyArg_ParseTuple(args, "l", &inRefNum))
161 return NULL;
162
163 if( (err=SPBGetDeviceInfo(inRefNum, siContinuous, (Ptr)&onoff)) != noErr )
164 return PyMac_Error(err);
165 return Py_BuildValue("h", onoff);
166 }
167
168 static char sndih_setContinuous__doc__[] =
169 ""
170 ;
171
172 static PyObject *
sndih_setContinuous(self,args)173 sndih_setContinuous(self, args)
174 PyObject *self; /* Not used */
175 PyObject *args;
176 {
177 long inRefNum;
178 short onoff;
179 OSErr err;
180
181 if (!PyArg_ParseTuple(args, "lh", &inRefNum, &onoff))
182 return NULL;
183
184 if( (err=SPBSetDeviceInfo(inRefNum, siContinuous, (Ptr)&onoff)) != noErr )
185 return PyMac_Error(err);
186 Py_INCREF(Py_None);
187 return Py_None;
188 }
189
190 static char sndih_getInputSourceNames__doc__[] =
191 ""
192 ;
193
194 static PyObject *
sndih_getInputSourceNames(self,args)195 sndih_getInputSourceNames(self, args)
196 PyObject *self; /* Not used */
197 PyObject *args;
198 {
199 long inRefNum;
200 Handle names;
201 OSErr err;
202
203 if (!PyArg_ParseTuple(args, "l", &inRefNum))
204 return NULL;
205
206 if( (err=SPBGetDeviceInfo(inRefNum, siInputSourceNames, (Ptr)&names)) != noErr )
207 return PyMac_Error(err);
208 return Py_BuildValue("O&", ResObj_New, names);
209 }
210
211 static char sndih_getInputSource__doc__[] =
212 ""
213 ;
214
215 static PyObject *
sndih_getInputSource(self,args)216 sndih_getInputSource(self, args)
217 PyObject *self; /* Not used */
218 PyObject *args;
219 {
220 long inRefNum;
221 short source;
222 OSErr err;
223
224 if (!PyArg_ParseTuple(args, "l", &inRefNum))
225 return NULL;
226
227 if( (err=SPBGetDeviceInfo(inRefNum, siInputSource, (Ptr)&source)) != noErr )
228 return PyMac_Error(err);
229 return Py_BuildValue("h", source);
230 }
231
232 static char sndih_setInputSource__doc__[] =
233 ""
234 ;
235
236 static PyObject *
sndih_setInputSource(self,args)237 sndih_setInputSource(self, args)
238 PyObject *self; /* Not used */
239 PyObject *args;
240 {
241 long inRefNum;
242 short source;
243 OSErr err;
244
245 if (!PyArg_ParseTuple(args, "lh", &inRefNum, &source))
246 return NULL;
247
248 if( (err=SPBSetDeviceInfo(inRefNum, siInputSource, (Ptr)&source)) != noErr )
249 return PyMac_Error(err);
250 Py_INCREF(Py_None);
251 return Py_None;
252 }
253
254 static char sndih_getPlayThruOnOff__doc__[] =
255 ""
256 ;
257
258 static PyObject *
sndih_getPlayThruOnOff(self,args)259 sndih_getPlayThruOnOff(self, args)
260 PyObject *self; /* Not used */
261 PyObject *args;
262 {
263 long inRefNum;
264 short onoff;
265 OSErr err;
266
267 if (!PyArg_ParseTuple(args, "l", &inRefNum))
268 return NULL;
269
270 if( (err=SPBGetDeviceInfo(inRefNum, siPlayThruOnOff, (Ptr)&onoff)) != noErr )
271 return PyMac_Error(err);
272 return Py_BuildValue("h", onoff);
273 }
274
275 static char sndih_setPlayThruOnOff__doc__[] =
276 ""
277 ;
278
279 static PyObject *
sndih_setPlayThruOnOff(self,args)280 sndih_setPlayThruOnOff(self, args)
281 PyObject *self; /* Not used */
282 PyObject *args;
283 {
284 long inRefNum;
285 short onoff;
286 OSErr err;
287
288 if (!PyArg_ParseTuple(args, "lh", &inRefNum, &onoff))
289 return NULL;
290
291 if( (err=SPBSetDeviceInfo(inRefNum, siPlayThruOnOff, (Ptr)&onoff)) != noErr )
292 return PyMac_Error(err);
293 Py_INCREF(Py_None);
294 return Py_None;
295 }
296
297 static char sndih_getSampleRate__doc__[] =
298 ""
299 ;
300
301 static PyObject *
sndih_getSampleRate(self,args)302 sndih_getSampleRate(self, args)
303 PyObject *self; /* Not used */
304 PyObject *args;
305 {
306 long inRefNum;
307 Fixed sample_rate;
308 OSErr err;
309
310 if (!PyArg_ParseTuple(args, "l", &inRefNum))
311 return NULL;
312
313 if( (err=SPBGetDeviceInfo(inRefNum, siSampleRate, (Ptr)&sample_rate)) != noErr )
314 return PyMac_Error(err);
315 return Py_BuildValue("O&", PyMac_BuildUFixed, sample_rate);
316 }
317
318 static char sndih_setSampleRate__doc__[] =
319 ""
320 ;
321
322 static PyObject *
sndih_setSampleRate(self,args)323 sndih_setSampleRate(self, args)
324 PyObject *self; /* Not used */
325 PyObject *args;
326 {
327 long inRefNum;
328 Fixed sample_rate;
329 OSErr err;
330
331 if (!PyArg_ParseTuple(args, "lO&", &inRefNum, PyMac_GetUFixed, &sample_rate))
332 return NULL;
333
334 if( (err=SPBSetDeviceInfo(inRefNum, siSampleRate, (Ptr)&sample_rate)) != noErr )
335 return PyMac_Error(err);
336 Py_INCREF(Py_None);
337 return Py_None;
338 }
339
340 static char sndih_getSampleSize__doc__[] =
341 ""
342 ;
343
344 static PyObject *
sndih_getSampleSize(self,args)345 sndih_getSampleSize(self, args)
346 PyObject *self; /* Not used */
347 PyObject *args;
348 {
349 long inRefNum;
350 short bits;
351 OSErr err;
352
353 if (!PyArg_ParseTuple(args, "l", &inRefNum))
354 return NULL;
355
356 if( (err=SPBGetDeviceInfo(inRefNum, siSampleSize, (Ptr)&bits)) != noErr )
357 return PyMac_Error(err);
358 return Py_BuildValue("h", bits);
359 }
360
361 static char sndih_setSampleSize__doc__[] =
362 ""
363 ;
364
365 static PyObject *
sndih_setSampleSize(self,args)366 sndih_setSampleSize(self, args)
367 PyObject *self; /* Not used */
368 PyObject *args;
369 {
370 long inRefNum;
371 short size;
372 OSErr err;
373
374 if (!PyArg_ParseTuple(args, "lh", &inRefNum, &size))
375 return NULL;
376
377 if( (err=SPBSetDeviceInfo(inRefNum, siSampleSize, (Ptr)&size)) != noErr )
378 return PyMac_Error(err);
379 Py_INCREF(Py_None);
380 return Py_None;
381 }
382
383 static char sndih_getSampleSizeAvailable__doc__[] =
384 ""
385 ;
386
387 static PyObject *
sndih_getSampleSizeAvailable(self,args)388 sndih_getSampleSizeAvailable(self, args)
389 PyObject *self; /* Not used */
390 PyObject *args;
391 {
392 long inRefNum;
393 struct SampleSizeAvailable_arg arg;
394 OSErr err;
395 PyObject *rsizes;
396 short *fsizes;
397 int i;
398
399 arg.sizes = NULL;
400 rsizes = NULL;
401 if (!PyArg_ParseTuple(args, "l", &inRefNum))
402 return NULL;
403
404 if( (err=SPBGetDeviceInfo(inRefNum, siSampleSizeAvailable, (Ptr)&arg)) != noErr ) {
405 return PyMac_Error(err);
406 }
407 fsizes = (short *)*(arg.sizes);
408 /* Handle contains a list of rates */
409 if( (rsizes = PyTuple_New(arg.numsizes)) == NULL)
410 return NULL;
411 for( i=0; i<arg.numsizes; i++ )
412 PyTuple_SetItem(rsizes, i, PyInt_FromLong((long)fsizes[i]));
413 return rsizes;
414 }
415
416 static char sndih_getSampleRateAvailable__doc__[] =
417 ""
418 ;
419
420 static PyObject *
sndih_getSampleRateAvailable(self,args)421 sndih_getSampleRateAvailable(self, args)
422 PyObject *self; /* Not used */
423 PyObject *args;
424 {
425 long inRefNum;
426 struct SampleRateAvailable_arg arg;
427 OSErr err;
428 PyObject *rrates, *obj;
429 Fixed *frates;
430 int i;
431
432 arg.rates = NULL;
433 rrates = NULL;
434 if (!PyArg_ParseTuple(args, "l", &inRefNum))
435 return NULL;
436
437 if( (err=SPBGetDeviceInfo(inRefNum, siSampleRateAvailable, (Ptr)&arg)) != noErr ) {
438 return PyMac_Error(err);
439 }
440 frates = (Fixed *)*(arg.rates);
441 if( arg.numrates == 0 ) {
442 /* The handle contains upper and lowerbound */
443 rrates = Py_BuildValue("O&O&", frates[0], frates[1]);
444 if (rrates == NULL) return NULL;
445 } else {
446 /* Handle contains a list of rates */
447 if( (rrates = PyTuple_New(arg.numrates)) == NULL)
448 return NULL;
449 for( i=0; i<arg.numrates; i++ ) {
450 if( (obj = Py_BuildValue("O&", PyMac_BuildUFixed, frates[i]))==NULL)
451 goto out;
452 PyTuple_SetItem(rrates, i, obj);
453 }
454 }
455 return Py_BuildValue("hO", arg.numrates, rrates);
456 out:
457 Py_XDECREF(rrates);
458 return NULL;
459 }
460
461 /* List of methods defined in the module */
462
463 static struct PyMethodDef sndih_methods[] = {
464 {"getChannelAvailable", (PyCFunction)sndih_getChannelAvailable, METH_VARARGS, sndih_getChannelAvailable__doc__},
465 {"getNumberChannels", (PyCFunction)sndih_getNumberChannels, METH_VARARGS, sndih_getNumberChannels__doc__},
466 {"setNumberChannels", (PyCFunction)sndih_setNumberChannels, METH_VARARGS, sndih_setNumberChannels__doc__},
467 {"getContinuous", (PyCFunction)sndih_getContinuous, METH_VARARGS, sndih_getContinuous__doc__},
468 {"setContinuous", (PyCFunction)sndih_setContinuous, METH_VARARGS, sndih_setContinuous__doc__},
469 {"getInputSourceNames", (PyCFunction)sndih_getInputSourceNames, METH_VARARGS, sndih_getInputSourceNames__doc__},
470 {"getInputSource", (PyCFunction)sndih_getInputSource, METH_VARARGS, sndih_getInputSource__doc__},
471 {"setInputSource", (PyCFunction)sndih_setInputSource, METH_VARARGS, sndih_setInputSource__doc__},
472 {"getPlayThruOnOff", (PyCFunction)sndih_getPlayThruOnOff, METH_VARARGS, sndih_getPlayThruOnOff__doc__},
473 {"setPlayThruOnOff", (PyCFunction)sndih_setPlayThruOnOff, METH_VARARGS, sndih_setPlayThruOnOff__doc__},
474 {"getSampleRate", (PyCFunction)sndih_getSampleRate, METH_VARARGS, sndih_getSampleRate__doc__},
475 {"setSampleRate", (PyCFunction)sndih_setSampleRate, METH_VARARGS, sndih_setSampleRate__doc__},
476 {"getSampleSize", (PyCFunction)sndih_getSampleSize, METH_VARARGS, sndih_getSampleSize__doc__},
477 {"setSampleSize", (PyCFunction)sndih_setSampleSize, METH_VARARGS, sndih_setSampleSize__doc__},
478 {"getSampleSizeAvailable", (PyCFunction)sndih_getSampleSizeAvailable, METH_VARARGS, sndih_getSampleSizeAvailable__doc__},
479 {"getSampleRateAvailable", (PyCFunction)sndih_getSampleRateAvailable, METH_VARARGS, sndih_getSampleRateAvailable__doc__},
480
481 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
482 };
483
484
485 /* Initialization function for the module (*must* be called initSndihooks) */
486
487 static char Sndihooks_module_documentation[] =
488 ""
489 ;
490
491 void
init_Sndihooks()492 init_Sndihooks()
493 {
494 PyObject *m, *d;
495
496 /* Create the module and add the functions */
497 m = Py_InitModule4("_Sndihooks", sndih_methods,
498 Sndihooks_module_documentation,
499 (PyObject*)NULL,PYTHON_API_VERSION);
500
501 /* Add some symbolic constants to the module */
502 d = PyModule_GetDict(m);
503 ErrorObject = PyString_FromString("Sndihooks.error");
504 PyDict_SetItemString(d, "error", ErrorObject);
505
506 /* XXXX Add constants here */
507
508 /* Check for errors */
509 if (PyErr_Occurred())
510 Py_FatalError("can't initialize module Sndihooks");
511 }
512
513