PageRenderTime 86ms CodeModel.GetById 3ms app.highlight 62ms RepoModel.GetById 2ms app.codeStats 0ms

/Mac/Modules/snd/_Sndmodule.c

http://unladen-swallow.googlecode.com/
C | 1161 lines | 1035 code | 108 blank | 18 comment | 138 complexity | 1fe03c09cc8cc0f22850918b95a0b244 MD5 | raw file
   1
   2/* ========================== Module _Snd =========================== */
   3
   4#include "Python.h"
   5
   6#ifndef __LP64__
   7
   8
   9#include "pymactoolbox.h"
  10
  11/* Macro to test whether a weak-loaded CFM function exists */
  12#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
  13        PyErr_SetString(PyExc_NotImplementedError, \
  14        "Not available in this shared library/OS version"); \
  15        return NULL; \
  16    }} while(0)
  17
  18
  19#include <Carbon/Carbon.h>
  20
  21/* Convert a SndCommand argument */
  22static int
  23SndCmd_Convert(PyObject *v, SndCommand *pc)
  24{
  25        int len;
  26        pc->param1 = 0;
  27        pc->param2 = 0;
  28        if (PyTuple_Check(v)) {
  29                if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
  30                        return 1;
  31                PyErr_Clear();
  32                return PyArg_ParseTuple(v, "Hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
  33        }
  34        return PyArg_Parse(v, "H", &pc->cmd);
  35}
  36
  37static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
  38static pascal void SPB_completion(SPBPtr my_spb); /* Forward */
  39
  40static PyObject *Snd_Error;
  41
  42/* --------------------- Object type SndChannel --------------------- */
  43
  44static PyTypeObject SndChannel_Type;
  45
  46#define SndCh_Check(x) ((x)->ob_type == &SndChannel_Type || PyObject_TypeCheck((x), &SndChannel_Type))
  47
  48typedef struct SndChannelObject {
  49	PyObject_HEAD
  50	SndChannelPtr ob_itself;
  51	/* Members used to implement callbacks: */
  52	PyObject *ob_callback;
  53	long ob_A5;
  54	SndCommand ob_cmd;
  55} SndChannelObject;
  56
  57static PyObject *SndCh_New(SndChannelPtr itself)
  58{
  59	SndChannelObject *it;
  60	it = PyObject_NEW(SndChannelObject, &SndChannel_Type);
  61	if (it == NULL) return NULL;
  62	it->ob_itself = itself;
  63	it->ob_callback = NULL;
  64	it->ob_A5 = SetCurrentA5();
  65	return (PyObject *)it;
  66}
  67
  68static void SndCh_dealloc(SndChannelObject *self)
  69{
  70	SndDisposeChannel(self->ob_itself, 1);
  71	Py_XDECREF(self->ob_callback);
  72	PyObject_Free((PyObject *)self);
  73}
  74
  75static PyObject *SndCh_SndDoCommand(SndChannelObject *_self, PyObject *_args)
  76{
  77	PyObject *_res = NULL;
  78	OSErr _err;
  79	SndCommand cmd;
  80	Boolean noWait;
  81	if (!PyArg_ParseTuple(_args, "O&b",
  82	                      SndCmd_Convert, &cmd,
  83	                      &noWait))
  84		return NULL;
  85	_err = SndDoCommand(_self->ob_itself,
  86	                    &cmd,
  87	                    noWait);
  88	if (_err != noErr) return PyMac_Error(_err);
  89	Py_INCREF(Py_None);
  90	_res = Py_None;
  91	return _res;
  92}
  93
  94static PyObject *SndCh_SndDoImmediate(SndChannelObject *_self, PyObject *_args)
  95{
  96	PyObject *_res = NULL;
  97	OSErr _err;
  98	SndCommand cmd;
  99	if (!PyArg_ParseTuple(_args, "O&",
 100	                      SndCmd_Convert, &cmd))
 101		return NULL;
 102	_err = SndDoImmediate(_self->ob_itself,
 103	                      &cmd);
 104	if (_err != noErr) return PyMac_Error(_err);
 105	Py_INCREF(Py_None);
 106	_res = Py_None;
 107	return _res;
 108}
 109
 110static PyObject *SndCh_SndPlay(SndChannelObject *_self, PyObject *_args)
 111{
 112	PyObject *_res = NULL;
 113	OSErr _err;
 114	SndListHandle sndHandle;
 115	Boolean async;
 116	if (!PyArg_ParseTuple(_args, "O&b",
 117	                      ResObj_Convert, &sndHandle,
 118	                      &async))
 119		return NULL;
 120	_err = SndPlay(_self->ob_itself,
 121	               sndHandle,
 122	               async);
 123	if (_err != noErr) return PyMac_Error(_err);
 124	Py_INCREF(Py_None);
 125	_res = Py_None;
 126	return _res;
 127}
 128
 129static PyObject *SndCh_SndChannelStatus(SndChannelObject *_self, PyObject *_args)
 130{
 131	PyObject *_res = NULL;
 132	OSErr _err;
 133	short theLength;
 134	SCStatus theStatus__out__;
 135	if (!PyArg_ParseTuple(_args, "h",
 136	                      &theLength))
 137		return NULL;
 138	_err = SndChannelStatus(_self->ob_itself,
 139	                        theLength,
 140	                        &theStatus__out__);
 141	if (_err != noErr) return PyMac_Error(_err);
 142	_res = Py_BuildValue("s#",
 143	                     (char *)&theStatus__out__, (int)sizeof(SCStatus));
 144	return _res;
 145}
 146
 147static PyObject *SndCh_SndGetInfo(SndChannelObject *_self, PyObject *_args)
 148{
 149	PyObject *_res = NULL;
 150	OSErr _err;
 151	OSType selector;
 152	void * infoPtr;
 153	if (!PyArg_ParseTuple(_args, "O&w",
 154	                      PyMac_GetOSType, &selector,
 155	                      &infoPtr))
 156		return NULL;
 157	_err = SndGetInfo(_self->ob_itself,
 158	                  selector,
 159	                  infoPtr);
 160	if (_err != noErr) return PyMac_Error(_err);
 161	Py_INCREF(Py_None);
 162	_res = Py_None;
 163	return _res;
 164}
 165
 166static PyObject *SndCh_SndSetInfo(SndChannelObject *_self, PyObject *_args)
 167{
 168	PyObject *_res = NULL;
 169	OSErr _err;
 170	OSType selector;
 171	void * infoPtr;
 172	if (!PyArg_ParseTuple(_args, "O&w",
 173	                      PyMac_GetOSType, &selector,
 174	                      &infoPtr))
 175		return NULL;
 176	_err = SndSetInfo(_self->ob_itself,
 177	                  selector,
 178	                  infoPtr);
 179	if (_err != noErr) return PyMac_Error(_err);
 180	Py_INCREF(Py_None);
 181	_res = Py_None;
 182	return _res;
 183}
 184
 185static PyMethodDef SndCh_methods[] = {
 186	{"SndDoCommand", (PyCFunction)SndCh_SndDoCommand, 1,
 187	 PyDoc_STR("(SndCommand cmd, Boolean noWait) -> None")},
 188	{"SndDoImmediate", (PyCFunction)SndCh_SndDoImmediate, 1,
 189	 PyDoc_STR("(SndCommand cmd) -> None")},
 190	{"SndPlay", (PyCFunction)SndCh_SndPlay, 1,
 191	 PyDoc_STR("(SndListHandle sndHandle, Boolean async) -> None")},
 192	{"SndChannelStatus", (PyCFunction)SndCh_SndChannelStatus, 1,
 193	 PyDoc_STR("(short theLength) -> (SCStatus theStatus)")},
 194	{"SndGetInfo", (PyCFunction)SndCh_SndGetInfo, 1,
 195	 PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
 196	{"SndSetInfo", (PyCFunction)SndCh_SndSetInfo, 1,
 197	 PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
 198	{NULL, NULL, 0}
 199};
 200
 201#define SndCh_getsetlist NULL
 202
 203
 204#define SndCh_compare NULL
 205
 206#define SndCh_repr NULL
 207
 208#define SndCh_hash NULL
 209
 210static PyTypeObject SndChannel_Type = {
 211	PyObject_HEAD_INIT(NULL)
 212	0, /*ob_size*/
 213	"_Snd.SndChannel", /*tp_name*/
 214	sizeof(SndChannelObject), /*tp_basicsize*/
 215	0, /*tp_itemsize*/
 216	/* methods */
 217	(destructor) SndCh_dealloc, /*tp_dealloc*/
 218	0, /*tp_print*/
 219	(getattrfunc)0, /*tp_getattr*/
 220	(setattrfunc)0, /*tp_setattr*/
 221	(cmpfunc) SndCh_compare, /*tp_compare*/
 222	(reprfunc) SndCh_repr, /*tp_repr*/
 223	(PyNumberMethods *)0, /* tp_as_number */
 224	(PySequenceMethods *)0, /* tp_as_sequence */
 225	(PyMappingMethods *)0, /* tp_as_mapping */
 226	(hashfunc) SndCh_hash, /*tp_hash*/
 227	0, /*tp_call*/
 228	0, /*tp_str*/
 229	PyObject_GenericGetAttr, /*tp_getattro*/
 230	PyObject_GenericSetAttr, /*tp_setattro */
 231	0, /*tp_as_buffer*/
 232	Py_TPFLAGS_DEFAULT, /* tp_flags */
 233	0, /*tp_doc*/
 234	0, /*tp_traverse*/
 235	0, /*tp_clear*/
 236	0, /*tp_richcompare*/
 237	0, /*tp_weaklistoffset*/
 238	0, /*tp_iter*/
 239	0, /*tp_iternext*/
 240	SndCh_methods, /* tp_methods */
 241	0, /*tp_members*/
 242	SndCh_getsetlist, /*tp_getset*/
 243	0, /*tp_base*/
 244	0, /*tp_dict*/
 245	0, /*tp_descr_get*/
 246	0, /*tp_descr_set*/
 247	0, /*tp_dictoffset*/
 248	0, /*tp_init*/
 249	0, /*tp_alloc*/
 250	0, /*tp_new*/
 251	0, /*tp_free*/
 252};
 253
 254/* ------------------- End object type SndChannel ------------------- */
 255
 256
 257/* ------------------------ Object type SPB ------------------------- */
 258
 259static PyTypeObject SPB_Type;
 260
 261#define SPBObj_Check(x) ((x)->ob_type == &SPB_Type || PyObject_TypeCheck((x), &SPB_Type))
 262
 263typedef struct SPBObject {
 264	PyObject_HEAD
 265	/* Members used to implement callbacks: */
 266	PyObject *ob_completion;
 267	PyObject *ob_interrupt;
 268	PyObject *ob_thiscallback;
 269	long ob_A5;
 270	SPB ob_spb;
 271} SPBObject;
 272
 273static PyObject *SPBObj_New(void)
 274{
 275	SPBObject *it;
 276	it = PyObject_NEW(SPBObject, &SPB_Type);
 277	if (it == NULL) return NULL;
 278	it->ob_completion = NULL;
 279	it->ob_interrupt = NULL;
 280	it->ob_thiscallback = NULL;
 281	it->ob_A5 = SetCurrentA5();
 282	memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));
 283	it->ob_spb.userLong = (long)it;
 284	return (PyObject *)it;
 285}
 286static int SPBObj_Convert(PyObject *v, SPBPtr *p_itself)
 287{
 288	if (!SPBObj_Check(v))
 289	{
 290		PyErr_SetString(PyExc_TypeError, "SPB required");
 291		return 0;
 292	}
 293	*p_itself = &((SPBObject *)v)->ob_spb;
 294	return 1;
 295}
 296
 297static void SPBObj_dealloc(SPBObject *self)
 298{
 299	/* Cleanup of self->ob_itself goes here */
 300	self->ob_spb.userLong = 0;
 301	self->ob_thiscallback = 0;
 302	Py_XDECREF(self->ob_completion);
 303	Py_XDECREF(self->ob_interrupt);
 304	PyObject_Free((PyObject *)self);
 305}
 306
 307static PyMethodDef SPBObj_methods[] = {
 308	{NULL, NULL, 0}
 309};
 310
 311static PyObject *SPBObj_get_inRefNum(SPBObject *self, void *closure)
 312{
 313	return Py_BuildValue("l", self->ob_spb.inRefNum);
 314}
 315
 316static int SPBObj_set_inRefNum(SPBObject *self, PyObject *v, void *closure)
 317{
 318	return -1 + PyArg_Parse(v, "l", &self->ob_spb.inRefNum);
 319	return 0;
 320}
 321
 322static PyObject *SPBObj_get_count(SPBObject *self, void *closure)
 323{
 324	return Py_BuildValue("l", self->ob_spb.count);
 325}
 326
 327static int SPBObj_set_count(SPBObject *self, PyObject *v, void *closure)
 328{
 329	return -1 + PyArg_Parse(v, "l", &self->ob_spb.count);
 330	return 0;
 331}
 332
 333static PyObject *SPBObj_get_milliseconds(SPBObject *self, void *closure)
 334{
 335	return Py_BuildValue("l", self->ob_spb.milliseconds);
 336}
 337
 338static int SPBObj_set_milliseconds(SPBObject *self, PyObject *v, void *closure)
 339{
 340	return -1 + PyArg_Parse(v, "l", &self->ob_spb.milliseconds);
 341	return 0;
 342}
 343
 344static PyObject *SPBObj_get_error(SPBObject *self, void *closure)
 345{
 346	return Py_BuildValue("h", self->ob_spb.error);
 347}
 348
 349#define SPBObj_set_error NULL
 350
 351#define SPBObj_get_completionRoutine NULL
 352
 353static int SPBObj_set_completionRoutine(SPBObject *self, PyObject *v, void *closure)
 354{
 355	self->ob_spb.completionRoutine = NewSICompletionUPP(SPB_completion);
 356	            self->ob_completion = v;
 357	            Py_INCREF(v);
 358	            return 0;
 359	return 0;
 360}
 361
 362static PyGetSetDef SPBObj_getsetlist[] = {
 363	{"inRefNum", (getter)SPBObj_get_inRefNum, (setter)SPBObj_set_inRefNum, NULL},
 364	{"count", (getter)SPBObj_get_count, (setter)SPBObj_set_count, NULL},
 365	{"milliseconds", (getter)SPBObj_get_milliseconds, (setter)SPBObj_set_milliseconds, NULL},
 366	{"error", (getter)SPBObj_get_error, (setter)SPBObj_set_error, NULL},
 367	{"completionRoutine", (getter)SPBObj_get_completionRoutine, (setter)SPBObj_set_completionRoutine, NULL},
 368	{NULL, NULL, NULL, NULL},
 369};
 370
 371
 372#define SPBObj_compare NULL
 373
 374#define SPBObj_repr NULL
 375
 376#define SPBObj_hash NULL
 377
 378static PyTypeObject SPB_Type = {
 379	PyObject_HEAD_INIT(NULL)
 380	0, /*ob_size*/
 381	"_Snd.SPB", /*tp_name*/
 382	sizeof(SPBObject), /*tp_basicsize*/
 383	0, /*tp_itemsize*/
 384	/* methods */
 385	(destructor) SPBObj_dealloc, /*tp_dealloc*/
 386	0, /*tp_print*/
 387	(getattrfunc)0, /*tp_getattr*/
 388	(setattrfunc)0, /*tp_setattr*/
 389	(cmpfunc) SPBObj_compare, /*tp_compare*/
 390	(reprfunc) SPBObj_repr, /*tp_repr*/
 391	(PyNumberMethods *)0, /* tp_as_number */
 392	(PySequenceMethods *)0, /* tp_as_sequence */
 393	(PyMappingMethods *)0, /* tp_as_mapping */
 394	(hashfunc) SPBObj_hash, /*tp_hash*/
 395	0, /*tp_call*/
 396	0, /*tp_str*/
 397	PyObject_GenericGetAttr, /*tp_getattro*/
 398	PyObject_GenericSetAttr, /*tp_setattro */
 399	0, /*tp_as_buffer*/
 400	Py_TPFLAGS_DEFAULT, /* tp_flags */
 401	0, /*tp_doc*/
 402	0, /*tp_traverse*/
 403	0, /*tp_clear*/
 404	0, /*tp_richcompare*/
 405	0, /*tp_weaklistoffset*/
 406	0, /*tp_iter*/
 407	0, /*tp_iternext*/
 408	SPBObj_methods, /* tp_methods */
 409	0, /*tp_members*/
 410	SPBObj_getsetlist, /*tp_getset*/
 411	0, /*tp_base*/
 412	0, /*tp_dict*/
 413	0, /*tp_descr_get*/
 414	0, /*tp_descr_set*/
 415	0, /*tp_dictoffset*/
 416	0, /*tp_init*/
 417	0, /*tp_alloc*/
 418	0, /*tp_new*/
 419	0, /*tp_free*/
 420};
 421
 422/* ---------------------- End object type SPB ----------------------- */
 423
 424
 425static PyObject *Snd_SPB(PyObject *_self, PyObject *_args)
 426{
 427	PyObject *_res = NULL;
 428	_res = SPBObj_New(); return _res;
 429}
 430
 431static PyObject *Snd_SysBeep(PyObject *_self, PyObject *_args)
 432{
 433	PyObject *_res = NULL;
 434	short duration;
 435	if (!PyArg_ParseTuple(_args, "h",
 436	                      &duration))
 437		return NULL;
 438	SysBeep(duration);
 439	Py_INCREF(Py_None);
 440	_res = Py_None;
 441	return _res;
 442}
 443
 444static PyObject *Snd_SndNewChannel(PyObject *_self, PyObject *_args)
 445{
 446	PyObject *_res = NULL;
 447	OSErr _err;
 448	SndChannelPtr chan = 0;
 449	short synth;
 450	long init;
 451	PyObject* userRoutine;
 452	if (!PyArg_ParseTuple(_args, "hlO",
 453	                      &synth,
 454	                      &init,
 455	                      &userRoutine))
 456		return NULL;
 457	if (userRoutine != Py_None && !PyCallable_Check(userRoutine))
 458	{
 459		PyErr_SetString(PyExc_TypeError, "callback must be callable");
 460		goto userRoutine__error__;
 461	}
 462	_err = SndNewChannel(&chan,
 463	                     synth,
 464	                     init,
 465	                     NewSndCallBackUPP(SndCh_UserRoutine));
 466	if (_err != noErr) return PyMac_Error(_err);
 467	_res = Py_BuildValue("O&",
 468	                     SndCh_New, chan);
 469	if (_res != NULL && userRoutine != Py_None)
 470	{
 471		SndChannelObject *p = (SndChannelObject *)_res;
 472		p->ob_itself->userInfo = (long)p;
 473		Py_INCREF(userRoutine);
 474		p->ob_callback = userRoutine;
 475	}
 476 userRoutine__error__: ;
 477	return _res;
 478}
 479
 480static PyObject *Snd_SndSoundManagerVersion(PyObject *_self, PyObject *_args)
 481{
 482	PyObject *_res = NULL;
 483	NumVersion _rv;
 484	if (!PyArg_ParseTuple(_args, ""))
 485		return NULL;
 486	_rv = SndSoundManagerVersion();
 487	_res = Py_BuildValue("O&",
 488	                     PyMac_BuildNumVersion, _rv);
 489	return _res;
 490}
 491
 492static PyObject *Snd_SndManagerStatus(PyObject *_self, PyObject *_args)
 493{
 494	PyObject *_res = NULL;
 495	OSErr _err;
 496	short theLength;
 497	SMStatus theStatus__out__;
 498	if (!PyArg_ParseTuple(_args, "h",
 499	                      &theLength))
 500		return NULL;
 501	_err = SndManagerStatus(theLength,
 502	                        &theStatus__out__);
 503	if (_err != noErr) return PyMac_Error(_err);
 504	_res = Py_BuildValue("s#",
 505	                     (char *)&theStatus__out__, (int)sizeof(SMStatus));
 506	return _res;
 507}
 508
 509static PyObject *Snd_SndGetSysBeepState(PyObject *_self, PyObject *_args)
 510{
 511	PyObject *_res = NULL;
 512	short sysBeepState;
 513	if (!PyArg_ParseTuple(_args, ""))
 514		return NULL;
 515	SndGetSysBeepState(&sysBeepState);
 516	_res = Py_BuildValue("h",
 517	                     sysBeepState);
 518	return _res;
 519}
 520
 521static PyObject *Snd_SndSetSysBeepState(PyObject *_self, PyObject *_args)
 522{
 523	PyObject *_res = NULL;
 524	OSErr _err;
 525	short sysBeepState;
 526	if (!PyArg_ParseTuple(_args, "h",
 527	                      &sysBeepState))
 528		return NULL;
 529	_err = SndSetSysBeepState(sysBeepState);
 530	if (_err != noErr) return PyMac_Error(_err);
 531	Py_INCREF(Py_None);
 532	_res = Py_None;
 533	return _res;
 534}
 535
 536static PyObject *Snd_GetSysBeepVolume(PyObject *_self, PyObject *_args)
 537{
 538	PyObject *_res = NULL;
 539	OSErr _err;
 540	long level;
 541	if (!PyArg_ParseTuple(_args, ""))
 542		return NULL;
 543	_err = GetSysBeepVolume(&level);
 544	if (_err != noErr) return PyMac_Error(_err);
 545	_res = Py_BuildValue("l",
 546	                     level);
 547	return _res;
 548}
 549
 550static PyObject *Snd_SetSysBeepVolume(PyObject *_self, PyObject *_args)
 551{
 552	PyObject *_res = NULL;
 553	OSErr _err;
 554	long level;
 555	if (!PyArg_ParseTuple(_args, "l",
 556	                      &level))
 557		return NULL;
 558	_err = SetSysBeepVolume(level);
 559	if (_err != noErr) return PyMac_Error(_err);
 560	Py_INCREF(Py_None);
 561	_res = Py_None;
 562	return _res;
 563}
 564
 565static PyObject *Snd_GetDefaultOutputVolume(PyObject *_self, PyObject *_args)
 566{
 567	PyObject *_res = NULL;
 568	OSErr _err;
 569	long level;
 570	if (!PyArg_ParseTuple(_args, ""))
 571		return NULL;
 572	_err = GetDefaultOutputVolume(&level);
 573	if (_err != noErr) return PyMac_Error(_err);
 574	_res = Py_BuildValue("l",
 575	                     level);
 576	return _res;
 577}
 578
 579static PyObject *Snd_SetDefaultOutputVolume(PyObject *_self, PyObject *_args)
 580{
 581	PyObject *_res = NULL;
 582	OSErr _err;
 583	long level;
 584	if (!PyArg_ParseTuple(_args, "l",
 585	                      &level))
 586		return NULL;
 587	_err = SetDefaultOutputVolume(level);
 588	if (_err != noErr) return PyMac_Error(_err);
 589	Py_INCREF(Py_None);
 590	_res = Py_None;
 591	return _res;
 592}
 593
 594static PyObject *Snd_GetSoundHeaderOffset(PyObject *_self, PyObject *_args)
 595{
 596	PyObject *_res = NULL;
 597	OSErr _err;
 598	SndListHandle sndHandle;
 599	long offset;
 600	if (!PyArg_ParseTuple(_args, "O&",
 601	                      ResObj_Convert, &sndHandle))
 602		return NULL;
 603	_err = GetSoundHeaderOffset(sndHandle,
 604	                            &offset);
 605	if (_err != noErr) return PyMac_Error(_err);
 606	_res = Py_BuildValue("l",
 607	                     offset);
 608	return _res;
 609}
 610
 611static PyObject *Snd_GetCompressionInfo(PyObject *_self, PyObject *_args)
 612{
 613	PyObject *_res = NULL;
 614	OSErr _err;
 615	short compressionID;
 616	OSType format;
 617	short numChannels;
 618	short sampleSize;
 619	CompressionInfo cp__out__;
 620	if (!PyArg_ParseTuple(_args, "hO&hh",
 621	                      &compressionID,
 622	                      PyMac_GetOSType, &format,
 623	                      &numChannels,
 624	                      &sampleSize))
 625		return NULL;
 626	_err = GetCompressionInfo(compressionID,
 627	                          format,
 628	                          numChannels,
 629	                          sampleSize,
 630	                          &cp__out__);
 631	if (_err != noErr) return PyMac_Error(_err);
 632	_res = Py_BuildValue("s#",
 633	                     (char *)&cp__out__, (int)sizeof(CompressionInfo));
 634	return _res;
 635}
 636
 637static PyObject *Snd_SetSoundPreference(PyObject *_self, PyObject *_args)
 638{
 639	PyObject *_res = NULL;
 640	OSErr _err;
 641	OSType theType;
 642	Str255 name;
 643	Handle settings;
 644	if (!PyArg_ParseTuple(_args, "O&O&",
 645	                      PyMac_GetOSType, &theType,
 646	                      ResObj_Convert, &settings))
 647		return NULL;
 648	_err = SetSoundPreference(theType,
 649	                          name,
 650	                          settings);
 651	if (_err != noErr) return PyMac_Error(_err);
 652	_res = Py_BuildValue("O&",
 653	                     PyMac_BuildStr255, name);
 654	return _res;
 655}
 656
 657static PyObject *Snd_GetSoundPreference(PyObject *_self, PyObject *_args)
 658{
 659	PyObject *_res = NULL;
 660	OSErr _err;
 661	OSType theType;
 662	Str255 name;
 663	Handle settings;
 664	if (!PyArg_ParseTuple(_args, "O&O&",
 665	                      PyMac_GetOSType, &theType,
 666	                      ResObj_Convert, &settings))
 667		return NULL;
 668	_err = GetSoundPreference(theType,
 669	                          name,
 670	                          settings);
 671	if (_err != noErr) return PyMac_Error(_err);
 672	_res = Py_BuildValue("O&",
 673	                     PyMac_BuildStr255, name);
 674	return _res;
 675}
 676
 677static PyObject *Snd_GetCompressionName(PyObject *_self, PyObject *_args)
 678{
 679	PyObject *_res = NULL;
 680	OSErr _err;
 681	OSType compressionType;
 682	Str255 compressionName;
 683	if (!PyArg_ParseTuple(_args, "O&",
 684	                      PyMac_GetOSType, &compressionType))
 685		return NULL;
 686	_err = GetCompressionName(compressionType,
 687	                          compressionName);
 688	if (_err != noErr) return PyMac_Error(_err);
 689	_res = Py_BuildValue("O&",
 690	                     PyMac_BuildStr255, compressionName);
 691	return _res;
 692}
 693
 694static PyObject *Snd_SPBVersion(PyObject *_self, PyObject *_args)
 695{
 696	PyObject *_res = NULL;
 697	NumVersion _rv;
 698	if (!PyArg_ParseTuple(_args, ""))
 699		return NULL;
 700	_rv = SPBVersion();
 701	_res = Py_BuildValue("O&",
 702	                     PyMac_BuildNumVersion, _rv);
 703	return _res;
 704}
 705
 706static PyObject *Snd_SndRecord(PyObject *_self, PyObject *_args)
 707{
 708	PyObject *_res = NULL;
 709	OSErr _err;
 710	Point corner;
 711	OSType quality;
 712	SndListHandle sndHandle;
 713	if (!PyArg_ParseTuple(_args, "O&O&",
 714	                      PyMac_GetPoint, &corner,
 715	                      PyMac_GetOSType, &quality))
 716		return NULL;
 717	_err = SndRecord((ModalFilterUPP)0,
 718	                 corner,
 719	                 quality,
 720	                 &sndHandle);
 721	if (_err != noErr) return PyMac_Error(_err);
 722	_res = Py_BuildValue("O&",
 723	                     ResObj_New, sndHandle);
 724	return _res;
 725}
 726
 727static PyObject *Snd_SPBSignInDevice(PyObject *_self, PyObject *_args)
 728{
 729	PyObject *_res = NULL;
 730	OSErr _err;
 731	short deviceRefNum;
 732	Str255 deviceName;
 733	if (!PyArg_ParseTuple(_args, "hO&",
 734	                      &deviceRefNum,
 735	                      PyMac_GetStr255, deviceName))
 736		return NULL;
 737	_err = SPBSignInDevice(deviceRefNum,
 738	                       deviceName);
 739	if (_err != noErr) return PyMac_Error(_err);
 740	Py_INCREF(Py_None);
 741	_res = Py_None;
 742	return _res;
 743}
 744
 745static PyObject *Snd_SPBSignOutDevice(PyObject *_self, PyObject *_args)
 746{
 747	PyObject *_res = NULL;
 748	OSErr _err;
 749	short deviceRefNum;
 750	if (!PyArg_ParseTuple(_args, "h",
 751	                      &deviceRefNum))
 752		return NULL;
 753	_err = SPBSignOutDevice(deviceRefNum);
 754	if (_err != noErr) return PyMac_Error(_err);
 755	Py_INCREF(Py_None);
 756	_res = Py_None;
 757	return _res;
 758}
 759
 760static PyObject *Snd_SPBGetIndexedDevice(PyObject *_self, PyObject *_args)
 761{
 762	PyObject *_res = NULL;
 763	OSErr _err;
 764	short count;
 765	Str255 deviceName;
 766	Handle deviceIconHandle;
 767	if (!PyArg_ParseTuple(_args, "h",
 768	                      &count))
 769		return NULL;
 770	_err = SPBGetIndexedDevice(count,
 771	                           deviceName,
 772	                           &deviceIconHandle);
 773	if (_err != noErr) return PyMac_Error(_err);
 774	_res = Py_BuildValue("O&O&",
 775	                     PyMac_BuildStr255, deviceName,
 776	                     ResObj_New, deviceIconHandle);
 777	return _res;
 778}
 779
 780static PyObject *Snd_SPBOpenDevice(PyObject *_self, PyObject *_args)
 781{
 782	PyObject *_res = NULL;
 783	OSErr _err;
 784	Str255 deviceName;
 785	short permission;
 786	long inRefNum;
 787	if (!PyArg_ParseTuple(_args, "O&h",
 788	                      PyMac_GetStr255, deviceName,
 789	                      &permission))
 790		return NULL;
 791	_err = SPBOpenDevice(deviceName,
 792	                     permission,
 793	                     &inRefNum);
 794	if (_err != noErr) return PyMac_Error(_err);
 795	_res = Py_BuildValue("l",
 796	                     inRefNum);
 797	return _res;
 798}
 799
 800static PyObject *Snd_SPBCloseDevice(PyObject *_self, PyObject *_args)
 801{
 802	PyObject *_res = NULL;
 803	OSErr _err;
 804	long inRefNum;
 805	if (!PyArg_ParseTuple(_args, "l",
 806	                      &inRefNum))
 807		return NULL;
 808	_err = SPBCloseDevice(inRefNum);
 809	if (_err != noErr) return PyMac_Error(_err);
 810	Py_INCREF(Py_None);
 811	_res = Py_None;
 812	return _res;
 813}
 814
 815static PyObject *Snd_SPBRecord(PyObject *_self, PyObject *_args)
 816{
 817	PyObject *_res = NULL;
 818	OSErr _err;
 819	SPBPtr inParamPtr;
 820	Boolean asynchFlag;
 821	if (!PyArg_ParseTuple(_args, "O&b",
 822	                      SPBObj_Convert, &inParamPtr,
 823	                      &asynchFlag))
 824		return NULL;
 825	_err = SPBRecord(inParamPtr,
 826	                 asynchFlag);
 827	if (_err != noErr) return PyMac_Error(_err);
 828	Py_INCREF(Py_None);
 829	_res = Py_None;
 830	return _res;
 831}
 832
 833static PyObject *Snd_SPBPauseRecording(PyObject *_self, PyObject *_args)
 834{
 835	PyObject *_res = NULL;
 836	OSErr _err;
 837	long inRefNum;
 838	if (!PyArg_ParseTuple(_args, "l",
 839	                      &inRefNum))
 840		return NULL;
 841	_err = SPBPauseRecording(inRefNum);
 842	if (_err != noErr) return PyMac_Error(_err);
 843	Py_INCREF(Py_None);
 844	_res = Py_None;
 845	return _res;
 846}
 847
 848static PyObject *Snd_SPBResumeRecording(PyObject *_self, PyObject *_args)
 849{
 850	PyObject *_res = NULL;
 851	OSErr _err;
 852	long inRefNum;
 853	if (!PyArg_ParseTuple(_args, "l",
 854	                      &inRefNum))
 855		return NULL;
 856	_err = SPBResumeRecording(inRefNum);
 857	if (_err != noErr) return PyMac_Error(_err);
 858	Py_INCREF(Py_None);
 859	_res = Py_None;
 860	return _res;
 861}
 862
 863static PyObject *Snd_SPBStopRecording(PyObject *_self, PyObject *_args)
 864{
 865	PyObject *_res = NULL;
 866	OSErr _err;
 867	long inRefNum;
 868	if (!PyArg_ParseTuple(_args, "l",
 869	                      &inRefNum))
 870		return NULL;
 871	_err = SPBStopRecording(inRefNum);
 872	if (_err != noErr) return PyMac_Error(_err);
 873	Py_INCREF(Py_None);
 874	_res = Py_None;
 875	return _res;
 876}
 877
 878static PyObject *Snd_SPBGetRecordingStatus(PyObject *_self, PyObject *_args)
 879{
 880	PyObject *_res = NULL;
 881	OSErr _err;
 882	long inRefNum;
 883	short recordingStatus;
 884	short meterLevel;
 885	unsigned long totalSamplesToRecord;
 886	unsigned long numberOfSamplesRecorded;
 887	unsigned long totalMsecsToRecord;
 888	unsigned long numberOfMsecsRecorded;
 889	if (!PyArg_ParseTuple(_args, "l",
 890	                      &inRefNum))
 891		return NULL;
 892	_err = SPBGetRecordingStatus(inRefNum,
 893	                             &recordingStatus,
 894	                             &meterLevel,
 895	                             &totalSamplesToRecord,
 896	                             &numberOfSamplesRecorded,
 897	                             &totalMsecsToRecord,
 898	                             &numberOfMsecsRecorded);
 899	if (_err != noErr) return PyMac_Error(_err);
 900	_res = Py_BuildValue("hhllll",
 901	                     recordingStatus,
 902	                     meterLevel,
 903	                     totalSamplesToRecord,
 904	                     numberOfSamplesRecorded,
 905	                     totalMsecsToRecord,
 906	                     numberOfMsecsRecorded);
 907	return _res;
 908}
 909
 910static PyObject *Snd_SPBGetDeviceInfo(PyObject *_self, PyObject *_args)
 911{
 912	PyObject *_res = NULL;
 913	OSErr _err;
 914	long inRefNum;
 915	OSType infoType;
 916	void * infoData;
 917	if (!PyArg_ParseTuple(_args, "lO&w",
 918	                      &inRefNum,
 919	                      PyMac_GetOSType, &infoType,
 920	                      &infoData))
 921		return NULL;
 922	_err = SPBGetDeviceInfo(inRefNum,
 923	                        infoType,
 924	                        infoData);
 925	if (_err != noErr) return PyMac_Error(_err);
 926	Py_INCREF(Py_None);
 927	_res = Py_None;
 928	return _res;
 929}
 930
 931static PyObject *Snd_SPBSetDeviceInfo(PyObject *_self, PyObject *_args)
 932{
 933	PyObject *_res = NULL;
 934	OSErr _err;
 935	long inRefNum;
 936	OSType infoType;
 937	void * infoData;
 938	if (!PyArg_ParseTuple(_args, "lO&w",
 939	                      &inRefNum,
 940	                      PyMac_GetOSType, &infoType,
 941	                      &infoData))
 942		return NULL;
 943	_err = SPBSetDeviceInfo(inRefNum,
 944	                        infoType,
 945	                        infoData);
 946	if (_err != noErr) return PyMac_Error(_err);
 947	Py_INCREF(Py_None);
 948	_res = Py_None;
 949	return _res;
 950}
 951
 952static PyObject *Snd_SPBMillisecondsToBytes(PyObject *_self, PyObject *_args)
 953{
 954	PyObject *_res = NULL;
 955	OSErr _err;
 956	long inRefNum;
 957	long milliseconds;
 958	if (!PyArg_ParseTuple(_args, "l",
 959	                      &inRefNum))
 960		return NULL;
 961	_err = SPBMillisecondsToBytes(inRefNum,
 962	                              &milliseconds);
 963	if (_err != noErr) return PyMac_Error(_err);
 964	_res = Py_BuildValue("l",
 965	                     milliseconds);
 966	return _res;
 967}
 968
 969static PyObject *Snd_SPBBytesToMilliseconds(PyObject *_self, PyObject *_args)
 970{
 971	PyObject *_res = NULL;
 972	OSErr _err;
 973	long inRefNum;
 974	long byteCount;
 975	if (!PyArg_ParseTuple(_args, "l",
 976	                      &inRefNum))
 977		return NULL;
 978	_err = SPBBytesToMilliseconds(inRefNum,
 979	                              &byteCount);
 980	if (_err != noErr) return PyMac_Error(_err);
 981	_res = Py_BuildValue("l",
 982	                     byteCount);
 983	return _res;
 984}
 985#endif /* __LP64__ */
 986
 987static PyMethodDef Snd_methods[] = {
 988#ifndef __LP64__
 989	{"SPB", (PyCFunction)Snd_SPB, 1,
 990	 PyDoc_STR(NULL)},
 991	{"SysBeep", (PyCFunction)Snd_SysBeep, 1,
 992	 PyDoc_STR("(short duration) -> None")},
 993	{"SndNewChannel", (PyCFunction)Snd_SndNewChannel, 1,
 994	 PyDoc_STR("(short synth, long init, PyObject* userRoutine) -> (SndChannelPtr chan)")},
 995	{"SndSoundManagerVersion", (PyCFunction)Snd_SndSoundManagerVersion, 1,
 996	 PyDoc_STR("() -> (NumVersion _rv)")},
 997	{"SndManagerStatus", (PyCFunction)Snd_SndManagerStatus, 1,
 998	 PyDoc_STR("(short theLength) -> (SMStatus theStatus)")},
 999	{"SndGetSysBeepState", (PyCFunction)Snd_SndGetSysBeepState, 1,
1000	 PyDoc_STR("() -> (short sysBeepState)")},
1001	{"SndSetSysBeepState", (PyCFunction)Snd_SndSetSysBeepState, 1,
1002	 PyDoc_STR("(short sysBeepState) -> None")},
1003	{"GetSysBeepVolume", (PyCFunction)Snd_GetSysBeepVolume, 1,
1004	 PyDoc_STR("() -> (long level)")},
1005	{"SetSysBeepVolume", (PyCFunction)Snd_SetSysBeepVolume, 1,
1006	 PyDoc_STR("(long level) -> None")},
1007	{"GetDefaultOutputVolume", (PyCFunction)Snd_GetDefaultOutputVolume, 1,
1008	 PyDoc_STR("() -> (long level)")},
1009	{"SetDefaultOutputVolume", (PyCFunction)Snd_SetDefaultOutputVolume, 1,
1010	 PyDoc_STR("(long level) -> None")},
1011	{"GetSoundHeaderOffset", (PyCFunction)Snd_GetSoundHeaderOffset, 1,
1012	 PyDoc_STR("(SndListHandle sndHandle) -> (long offset)")},
1013	{"GetCompressionInfo", (PyCFunction)Snd_GetCompressionInfo, 1,
1014	 PyDoc_STR("(short compressionID, OSType format, short numChannels, short sampleSize) -> (CompressionInfo cp)")},
1015	{"SetSoundPreference", (PyCFunction)Snd_SetSoundPreference, 1,
1016	 PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
1017	{"GetSoundPreference", (PyCFunction)Snd_GetSoundPreference, 1,
1018	 PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
1019	{"GetCompressionName", (PyCFunction)Snd_GetCompressionName, 1,
1020	 PyDoc_STR("(OSType compressionType) -> (Str255 compressionName)")},
1021	{"SPBVersion", (PyCFunction)Snd_SPBVersion, 1,
1022	 PyDoc_STR("() -> (NumVersion _rv)")},
1023	{"SndRecord", (PyCFunction)Snd_SndRecord, 1,
1024	 PyDoc_STR("(Point corner, OSType quality) -> (SndListHandle sndHandle)")},
1025	{"SPBSignInDevice", (PyCFunction)Snd_SPBSignInDevice, 1,
1026	 PyDoc_STR("(short deviceRefNum, Str255 deviceName) -> None")},
1027	{"SPBSignOutDevice", (PyCFunction)Snd_SPBSignOutDevice, 1,
1028	 PyDoc_STR("(short deviceRefNum) -> None")},
1029	{"SPBGetIndexedDevice", (PyCFunction)Snd_SPBGetIndexedDevice, 1,
1030	 PyDoc_STR("(short count) -> (Str255 deviceName, Handle deviceIconHandle)")},
1031	{"SPBOpenDevice", (PyCFunction)Snd_SPBOpenDevice, 1,
1032	 PyDoc_STR("(Str255 deviceName, short permission) -> (long inRefNum)")},
1033	{"SPBCloseDevice", (PyCFunction)Snd_SPBCloseDevice, 1,
1034	 PyDoc_STR("(long inRefNum) -> None")},
1035	{"SPBRecord", (PyCFunction)Snd_SPBRecord, 1,
1036	 PyDoc_STR("(SPBPtr inParamPtr, Boolean asynchFlag) -> None")},
1037	{"SPBPauseRecording", (PyCFunction)Snd_SPBPauseRecording, 1,
1038	 PyDoc_STR("(long inRefNum) -> None")},
1039	{"SPBResumeRecording", (PyCFunction)Snd_SPBResumeRecording, 1,
1040	 PyDoc_STR("(long inRefNum) -> None")},
1041	{"SPBStopRecording", (PyCFunction)Snd_SPBStopRecording, 1,
1042	 PyDoc_STR("(long inRefNum) -> None")},
1043	{"SPBGetRecordingStatus", (PyCFunction)Snd_SPBGetRecordingStatus, 1,
1044	 PyDoc_STR("(long inRefNum) -> (short recordingStatus, short meterLevel, unsigned long totalSamplesToRecord, unsigned long numberOfSamplesRecorded, unsigned long totalMsecsToRecord, unsigned long numberOfMsecsRecorded)")},
1045	{"SPBGetDeviceInfo", (PyCFunction)Snd_SPBGetDeviceInfo, 1,
1046	 PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
1047	{"SPBSetDeviceInfo", (PyCFunction)Snd_SPBSetDeviceInfo, 1,
1048	 PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
1049	{"SPBMillisecondsToBytes", (PyCFunction)Snd_SPBMillisecondsToBytes, 1,
1050	 PyDoc_STR("(long inRefNum) -> (long milliseconds)")},
1051	{"SPBBytesToMilliseconds", (PyCFunction)Snd_SPBBytesToMilliseconds, 1,
1052	 PyDoc_STR("(long inRefNum) -> (long byteCount)")},
1053#endif /* __LP64__ */
1054	{NULL, NULL, 0}
1055};
1056
1057
1058#ifndef __LP64__
1059
1060/* Routine passed to Py_AddPendingCall -- call the Python callback */
1061static int
1062SndCh_CallCallBack(void *arg)
1063{
1064        SndChannelObject *p = (SndChannelObject *)arg;
1065        PyObject *args;
1066        PyObject *res;
1067        args = Py_BuildValue("(O(hhl))",
1068                             p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
1069        res = PyEval_CallObject(p->ob_callback, args);
1070        Py_DECREF(args);
1071        if (res == NULL)
1072                return -1;
1073        Py_DECREF(res);
1074        return 0;
1075}
1076
1077/* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
1078static pascal void
1079SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
1080{
1081        SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
1082        if (p->ob_callback != NULL) {
1083                long A5 = SetA5(p->ob_A5);
1084                p->ob_cmd = *cmd;
1085                Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
1086                SetA5(A5);
1087        }
1088}
1089
1090/* SPB callbacks - Schedule callbacks to Python */
1091static int
1092SPB_CallCallBack(void *arg)
1093{
1094        SPBObject *p = (SPBObject *)arg;
1095        PyObject *args;
1096        PyObject *res;
1097
1098        if ( p->ob_thiscallback == 0 ) return 0;
1099        args = Py_BuildValue("(O)", p);
1100        res = PyEval_CallObject(p->ob_thiscallback, args);
1101        p->ob_thiscallback = 0;
1102        Py_DECREF(args);
1103        if (res == NULL)
1104                return -1;
1105        Py_DECREF(res);
1106        return 0;
1107}
1108
1109static pascal void
1110SPB_completion(SPBPtr my_spb)
1111{
1112        SPBObject *p = (SPBObject *)(my_spb->userLong);
1113
1114        if (p && p->ob_completion) {
1115                long A5 = SetA5(p->ob_A5);
1116                p->ob_thiscallback = p->ob_completion;  /* Hope we cannot get two at the same time */
1117                Py_AddPendingCall(SPB_CallCallBack, (void *)p);
1118                SetA5(A5);
1119        }
1120}
1121#endif /* __LP64__ */
1122
1123
1124
1125void init_Snd(void)
1126{
1127	PyObject *m;
1128#ifndef __LP64__
1129	PyObject *d;
1130#endif /* __LP64__ */
1131
1132
1133
1134
1135
1136	m = Py_InitModule("_Snd", Snd_methods);
1137#ifndef __LP64__
1138	d = PyModule_GetDict(m);
1139	Snd_Error = PyMac_GetOSErrException();
1140	if (Snd_Error == NULL ||
1141	    PyDict_SetItemString(d, "Error", Snd_Error) != 0)
1142		return;
1143	SndChannel_Type.ob_type = &PyType_Type;
1144	if (PyType_Ready(&SndChannel_Type) < 0) return;
1145	Py_INCREF(&SndChannel_Type);
1146	PyModule_AddObject(m, "SndChannel", (PyObject *)&SndChannel_Type);
1147	/* Backward-compatible name */
1148	Py_INCREF(&SndChannel_Type);
1149	PyModule_AddObject(m, "SndChannelType", (PyObject *)&SndChannel_Type);
1150	SPB_Type.ob_type = &PyType_Type;
1151	if (PyType_Ready(&SPB_Type) < 0) return;
1152	Py_INCREF(&SPB_Type);
1153	PyModule_AddObject(m, "SPB", (PyObject *)&SPB_Type);
1154	/* Backward-compatible name */
1155	Py_INCREF(&SPB_Type);
1156	PyModule_AddObject(m, "SPBType", (PyObject *)&SPB_Type);
1157#endif /* __LP64__ */
1158}
1159
1160/* ======================== End module _Snd ========================= */
1161