symbian-qemu-0.9.1-12/python-2.6.1/Mac/Modules/snd/_Sndmodule.c
author johnathan.white@2718R8BGH51.accenture.com
Mon, 08 Mar 2010 18:45:03 +0000
changeset 46 b6935a90ca64
parent 1 2fb8b9db1c86
permissions -rw-r--r--
Modify framebuffer and NGA framebuffer to read screen size from board model dtb file. Optimise memory usuage of frame buffer Add example minigui application with hooks to profiler (which writes results to S:\). Modified NGA framebuffer to run its own dfc queue at high priority


/* ========================== Module _Snd =========================== */

#include "Python.h"

#ifndef __LP64__


#include "pymactoolbox.h"

/* Macro to test whether a weak-loaded CFM function exists */
#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\
        PyErr_SetString(PyExc_NotImplementedError, \
        "Not available in this shared library/OS version"); \
        return NULL; \
    }} while(0)


#include <Carbon/Carbon.h>

/* Convert a SndCommand argument */
static int
SndCmd_Convert(PyObject *v, SndCommand *pc)
{
        int len;
        pc->param1 = 0;
        pc->param2 = 0;
        if (PyTuple_Check(v)) {
                if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
                        return 1;
                PyErr_Clear();
                return PyArg_ParseTuple(v, "Hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
        }
        return PyArg_Parse(v, "H", &pc->cmd);
}

static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
static pascal void SPB_completion(SPBPtr my_spb); /* Forward */

static PyObject *Snd_Error;

/* --------------------- Object type SndChannel --------------------- */

static PyTypeObject SndChannel_Type;

#define SndCh_Check(x) ((x)->ob_type == &SndChannel_Type || PyObject_TypeCheck((x), &SndChannel_Type))

typedef struct SndChannelObject {
	PyObject_HEAD
	SndChannelPtr ob_itself;
	/* Members used to implement callbacks: */
	PyObject *ob_callback;
	long ob_A5;
	SndCommand ob_cmd;
} SndChannelObject;

static PyObject *SndCh_New(SndChannelPtr itself)
{
	SndChannelObject *it;
	it = PyObject_NEW(SndChannelObject, &SndChannel_Type);
	if (it == NULL) return NULL;
	it->ob_itself = itself;
	it->ob_callback = NULL;
	it->ob_A5 = SetCurrentA5();
	return (PyObject *)it;
}

static void SndCh_dealloc(SndChannelObject *self)
{
	SndDisposeChannel(self->ob_itself, 1);
	Py_XDECREF(self->ob_callback);
	PyObject_Free((PyObject *)self);
}

static PyObject *SndCh_SndDoCommand(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SndCommand cmd;
	Boolean noWait;
	if (!PyArg_ParseTuple(_args, "O&b",
	                      SndCmd_Convert, &cmd,
	                      &noWait))
		return NULL;
	_err = SndDoCommand(_self->ob_itself,
	                    &cmd,
	                    noWait);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *SndCh_SndDoImmediate(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SndCommand cmd;
	if (!PyArg_ParseTuple(_args, "O&",
	                      SndCmd_Convert, &cmd))
		return NULL;
	_err = SndDoImmediate(_self->ob_itself,
	                      &cmd);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *SndCh_SndPlay(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SndListHandle sndHandle;
	Boolean async;
	if (!PyArg_ParseTuple(_args, "O&b",
	                      ResObj_Convert, &sndHandle,
	                      &async))
		return NULL;
	_err = SndPlay(_self->ob_itself,
	               sndHandle,
	               async);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *SndCh_SndChannelStatus(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short theLength;
	SCStatus theStatus__out__;
	if (!PyArg_ParseTuple(_args, "h",
	                      &theLength))
		return NULL;
	_err = SndChannelStatus(_self->ob_itself,
	                        theLength,
	                        &theStatus__out__);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("s#",
	                     (char *)&theStatus__out__, (int)sizeof(SCStatus));
	return _res;
}

static PyObject *SndCh_SndGetInfo(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	OSType selector;
	void * infoPtr;
	if (!PyArg_ParseTuple(_args, "O&w",
	                      PyMac_GetOSType, &selector,
	                      &infoPtr))
		return NULL;
	_err = SndGetInfo(_self->ob_itself,
	                  selector,
	                  infoPtr);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *SndCh_SndSetInfo(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	OSType selector;
	void * infoPtr;
	if (!PyArg_ParseTuple(_args, "O&w",
	                      PyMac_GetOSType, &selector,
	                      &infoPtr))
		return NULL;
	_err = SndSetInfo(_self->ob_itself,
	                  selector,
	                  infoPtr);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyMethodDef SndCh_methods[] = {
	{"SndDoCommand", (PyCFunction)SndCh_SndDoCommand, 1,
	 PyDoc_STR("(SndCommand cmd, Boolean noWait) -> None")},
	{"SndDoImmediate", (PyCFunction)SndCh_SndDoImmediate, 1,
	 PyDoc_STR("(SndCommand cmd) -> None")},
	{"SndPlay", (PyCFunction)SndCh_SndPlay, 1,
	 PyDoc_STR("(SndListHandle sndHandle, Boolean async) -> None")},
	{"SndChannelStatus", (PyCFunction)SndCh_SndChannelStatus, 1,
	 PyDoc_STR("(short theLength) -> (SCStatus theStatus)")},
	{"SndGetInfo", (PyCFunction)SndCh_SndGetInfo, 1,
	 PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
	{"SndSetInfo", (PyCFunction)SndCh_SndSetInfo, 1,
	 PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
	{NULL, NULL, 0}
};

#define SndCh_getsetlist NULL


#define SndCh_compare NULL

#define SndCh_repr NULL

#define SndCh_hash NULL

static PyTypeObject SndChannel_Type = {
	PyObject_HEAD_INIT(NULL)
	0, /*ob_size*/
	"_Snd.SndChannel", /*tp_name*/
	sizeof(SndChannelObject), /*tp_basicsize*/
	0, /*tp_itemsize*/
	/* methods */
	(destructor) SndCh_dealloc, /*tp_dealloc*/
	0, /*tp_print*/
	(getattrfunc)0, /*tp_getattr*/
	(setattrfunc)0, /*tp_setattr*/
	(cmpfunc) SndCh_compare, /*tp_compare*/
	(reprfunc) SndCh_repr, /*tp_repr*/
	(PyNumberMethods *)0, /* tp_as_number */
	(PySequenceMethods *)0, /* tp_as_sequence */
	(PyMappingMethods *)0, /* tp_as_mapping */
	(hashfunc) SndCh_hash, /*tp_hash*/
	0, /*tp_call*/
	0, /*tp_str*/
	PyObject_GenericGetAttr, /*tp_getattro*/
	PyObject_GenericSetAttr, /*tp_setattro */
	0, /*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT, /* tp_flags */
	0, /*tp_doc*/
	0, /*tp_traverse*/
	0, /*tp_clear*/
	0, /*tp_richcompare*/
	0, /*tp_weaklistoffset*/
	0, /*tp_iter*/
	0, /*tp_iternext*/
	SndCh_methods, /* tp_methods */
	0, /*tp_members*/
	SndCh_getsetlist, /*tp_getset*/
	0, /*tp_base*/
	0, /*tp_dict*/
	0, /*tp_descr_get*/
	0, /*tp_descr_set*/
	0, /*tp_dictoffset*/
	0, /*tp_init*/
	0, /*tp_alloc*/
	0, /*tp_new*/
	0, /*tp_free*/
};

/* ------------------- End object type SndChannel ------------------- */


/* ------------------------ Object type SPB ------------------------- */

static PyTypeObject SPB_Type;

#define SPBObj_Check(x) ((x)->ob_type == &SPB_Type || PyObject_TypeCheck((x), &SPB_Type))

typedef struct SPBObject {
	PyObject_HEAD
	/* Members used to implement callbacks: */
	PyObject *ob_completion;
	PyObject *ob_interrupt;
	PyObject *ob_thiscallback;
	long ob_A5;
	SPB ob_spb;
} SPBObject;

static PyObject *SPBObj_New(void)
{
	SPBObject *it;
	it = PyObject_NEW(SPBObject, &SPB_Type);
	if (it == NULL) return NULL;
	it->ob_completion = NULL;
	it->ob_interrupt = NULL;
	it->ob_thiscallback = NULL;
	it->ob_A5 = SetCurrentA5();
	memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));
	it->ob_spb.userLong = (long)it;
	return (PyObject *)it;
}
static int SPBObj_Convert(PyObject *v, SPBPtr *p_itself)
{
	if (!SPBObj_Check(v))
	{
		PyErr_SetString(PyExc_TypeError, "SPB required");
		return 0;
	}
	*p_itself = &((SPBObject *)v)->ob_spb;
	return 1;
}

static void SPBObj_dealloc(SPBObject *self)
{
	/* Cleanup of self->ob_itself goes here */
	self->ob_spb.userLong = 0;
	self->ob_thiscallback = 0;
	Py_XDECREF(self->ob_completion);
	Py_XDECREF(self->ob_interrupt);
	PyObject_Free((PyObject *)self);
}

static PyMethodDef SPBObj_methods[] = {
	{NULL, NULL, 0}
};

static PyObject *SPBObj_get_inRefNum(SPBObject *self, void *closure)
{
	return Py_BuildValue("l", self->ob_spb.inRefNum);
}

static int SPBObj_set_inRefNum(SPBObject *self, PyObject *v, void *closure)
{
	return -1 + PyArg_Parse(v, "l", &self->ob_spb.inRefNum);
	return 0;
}

static PyObject *SPBObj_get_count(SPBObject *self, void *closure)
{
	return Py_BuildValue("l", self->ob_spb.count);
}

static int SPBObj_set_count(SPBObject *self, PyObject *v, void *closure)
{
	return -1 + PyArg_Parse(v, "l", &self->ob_spb.count);
	return 0;
}

static PyObject *SPBObj_get_milliseconds(SPBObject *self, void *closure)
{
	return Py_BuildValue("l", self->ob_spb.milliseconds);
}

static int SPBObj_set_milliseconds(SPBObject *self, PyObject *v, void *closure)
{
	return -1 + PyArg_Parse(v, "l", &self->ob_spb.milliseconds);
	return 0;
}

static PyObject *SPBObj_get_error(SPBObject *self, void *closure)
{
	return Py_BuildValue("h", self->ob_spb.error);
}

#define SPBObj_set_error NULL

#define SPBObj_get_completionRoutine NULL

static int SPBObj_set_completionRoutine(SPBObject *self, PyObject *v, void *closure)
{
	self->ob_spb.completionRoutine = NewSICompletionUPP(SPB_completion);
	            self->ob_completion = v;
	            Py_INCREF(v);
	            return 0;
	return 0;
}

static PyGetSetDef SPBObj_getsetlist[] = {
	{"inRefNum", (getter)SPBObj_get_inRefNum, (setter)SPBObj_set_inRefNum, NULL},
	{"count", (getter)SPBObj_get_count, (setter)SPBObj_set_count, NULL},
	{"milliseconds", (getter)SPBObj_get_milliseconds, (setter)SPBObj_set_milliseconds, NULL},
	{"error", (getter)SPBObj_get_error, (setter)SPBObj_set_error, NULL},
	{"completionRoutine", (getter)SPBObj_get_completionRoutine, (setter)SPBObj_set_completionRoutine, NULL},
	{NULL, NULL, NULL, NULL},
};


#define SPBObj_compare NULL

#define SPBObj_repr NULL

#define SPBObj_hash NULL

static PyTypeObject SPB_Type = {
	PyObject_HEAD_INIT(NULL)
	0, /*ob_size*/
	"_Snd.SPB", /*tp_name*/
	sizeof(SPBObject), /*tp_basicsize*/
	0, /*tp_itemsize*/
	/* methods */
	(destructor) SPBObj_dealloc, /*tp_dealloc*/
	0, /*tp_print*/
	(getattrfunc)0, /*tp_getattr*/
	(setattrfunc)0, /*tp_setattr*/
	(cmpfunc) SPBObj_compare, /*tp_compare*/
	(reprfunc) SPBObj_repr, /*tp_repr*/
	(PyNumberMethods *)0, /* tp_as_number */
	(PySequenceMethods *)0, /* tp_as_sequence */
	(PyMappingMethods *)0, /* tp_as_mapping */
	(hashfunc) SPBObj_hash, /*tp_hash*/
	0, /*tp_call*/
	0, /*tp_str*/
	PyObject_GenericGetAttr, /*tp_getattro*/
	PyObject_GenericSetAttr, /*tp_setattro */
	0, /*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT, /* tp_flags */
	0, /*tp_doc*/
	0, /*tp_traverse*/
	0, /*tp_clear*/
	0, /*tp_richcompare*/
	0, /*tp_weaklistoffset*/
	0, /*tp_iter*/
	0, /*tp_iternext*/
	SPBObj_methods, /* tp_methods */
	0, /*tp_members*/
	SPBObj_getsetlist, /*tp_getset*/
	0, /*tp_base*/
	0, /*tp_dict*/
	0, /*tp_descr_get*/
	0, /*tp_descr_set*/
	0, /*tp_dictoffset*/
	0, /*tp_init*/
	0, /*tp_alloc*/
	0, /*tp_new*/
	0, /*tp_free*/
};

/* ---------------------- End object type SPB ----------------------- */


static PyObject *Snd_SPB(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	_res = SPBObj_New(); return _res;
}

static PyObject *Snd_SysBeep(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	short duration;
	if (!PyArg_ParseTuple(_args, "h",
	                      &duration))
		return NULL;
	SysBeep(duration);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SndNewChannel(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SndChannelPtr chan = 0;
	short synth;
	long init;
	PyObject* userRoutine;
	if (!PyArg_ParseTuple(_args, "hlO",
	                      &synth,
	                      &init,
	                      &userRoutine))
		return NULL;
	if (userRoutine != Py_None && !PyCallable_Check(userRoutine))
	{
		PyErr_SetString(PyExc_TypeError, "callback must be callable");
		goto userRoutine__error__;
	}
	_err = SndNewChannel(&chan,
	                     synth,
	                     init,
	                     NewSndCallBackUPP(SndCh_UserRoutine));
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&",
	                     SndCh_New, chan);
	if (_res != NULL && userRoutine != Py_None)
	{
		SndChannelObject *p = (SndChannelObject *)_res;
		p->ob_itself->userInfo = (long)p;
		Py_INCREF(userRoutine);
		p->ob_callback = userRoutine;
	}
 userRoutine__error__: ;
	return _res;
}

static PyObject *Snd_SndSoundManagerVersion(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	NumVersion _rv;
	if (!PyArg_ParseTuple(_args, ""))
		return NULL;
	_rv = SndSoundManagerVersion();
	_res = Py_BuildValue("O&",
	                     PyMac_BuildNumVersion, _rv);
	return _res;
}

static PyObject *Snd_SndManagerStatus(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short theLength;
	SMStatus theStatus__out__;
	if (!PyArg_ParseTuple(_args, "h",
	                      &theLength))
		return NULL;
	_err = SndManagerStatus(theLength,
	                        &theStatus__out__);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("s#",
	                     (char *)&theStatus__out__, (int)sizeof(SMStatus));
	return _res;
}

static PyObject *Snd_SndGetSysBeepState(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	short sysBeepState;
	if (!PyArg_ParseTuple(_args, ""))
		return NULL;
	SndGetSysBeepState(&sysBeepState);
	_res = Py_BuildValue("h",
	                     sysBeepState);
	return _res;
}

static PyObject *Snd_SndSetSysBeepState(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short sysBeepState;
	if (!PyArg_ParseTuple(_args, "h",
	                      &sysBeepState))
		return NULL;
	_err = SndSetSysBeepState(sysBeepState);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_GetSysBeepVolume(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long level;
	if (!PyArg_ParseTuple(_args, ""))
		return NULL;
	_err = GetSysBeepVolume(&level);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("l",
	                     level);
	return _res;
}

static PyObject *Snd_SetSysBeepVolume(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long level;
	if (!PyArg_ParseTuple(_args, "l",
	                      &level))
		return NULL;
	_err = SetSysBeepVolume(level);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_GetDefaultOutputVolume(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long level;
	if (!PyArg_ParseTuple(_args, ""))
		return NULL;
	_err = GetDefaultOutputVolume(&level);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("l",
	                     level);
	return _res;
}

static PyObject *Snd_SetDefaultOutputVolume(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long level;
	if (!PyArg_ParseTuple(_args, "l",
	                      &level))
		return NULL;
	_err = SetDefaultOutputVolume(level);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_GetSoundHeaderOffset(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SndListHandle sndHandle;
	long offset;
	if (!PyArg_ParseTuple(_args, "O&",
	                      ResObj_Convert, &sndHandle))
		return NULL;
	_err = GetSoundHeaderOffset(sndHandle,
	                            &offset);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("l",
	                     offset);
	return _res;
}

static PyObject *Snd_GetCompressionInfo(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short compressionID;
	OSType format;
	short numChannels;
	short sampleSize;
	CompressionInfo cp__out__;
	if (!PyArg_ParseTuple(_args, "hO&hh",
	                      &compressionID,
	                      PyMac_GetOSType, &format,
	                      &numChannels,
	                      &sampleSize))
		return NULL;
	_err = GetCompressionInfo(compressionID,
	                          format,
	                          numChannels,
	                          sampleSize,
	                          &cp__out__);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("s#",
	                     (char *)&cp__out__, (int)sizeof(CompressionInfo));
	return _res;
}

static PyObject *Snd_SetSoundPreference(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	OSType theType;
	Str255 name;
	Handle settings;
	if (!PyArg_ParseTuple(_args, "O&O&",
	                      PyMac_GetOSType, &theType,
	                      ResObj_Convert, &settings))
		return NULL;
	_err = SetSoundPreference(theType,
	                          name,
	                          settings);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&",
	                     PyMac_BuildStr255, name);
	return _res;
}

static PyObject *Snd_GetSoundPreference(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	OSType theType;
	Str255 name;
	Handle settings;
	if (!PyArg_ParseTuple(_args, "O&O&",
	                      PyMac_GetOSType, &theType,
	                      ResObj_Convert, &settings))
		return NULL;
	_err = GetSoundPreference(theType,
	                          name,
	                          settings);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&",
	                     PyMac_BuildStr255, name);
	return _res;
}

static PyObject *Snd_GetCompressionName(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	OSType compressionType;
	Str255 compressionName;
	if (!PyArg_ParseTuple(_args, "O&",
	                      PyMac_GetOSType, &compressionType))
		return NULL;
	_err = GetCompressionName(compressionType,
	                          compressionName);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&",
	                     PyMac_BuildStr255, compressionName);
	return _res;
}

static PyObject *Snd_SPBVersion(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	NumVersion _rv;
	if (!PyArg_ParseTuple(_args, ""))
		return NULL;
	_rv = SPBVersion();
	_res = Py_BuildValue("O&",
	                     PyMac_BuildNumVersion, _rv);
	return _res;
}

static PyObject *Snd_SndRecord(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	Point corner;
	OSType quality;
	SndListHandle sndHandle;
	if (!PyArg_ParseTuple(_args, "O&O&",
	                      PyMac_GetPoint, &corner,
	                      PyMac_GetOSType, &quality))
		return NULL;
	_err = SndRecord((ModalFilterUPP)0,
	                 corner,
	                 quality,
	                 &sndHandle);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&",
	                     ResObj_New, sndHandle);
	return _res;
}

static PyObject *Snd_SPBSignInDevice(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short deviceRefNum;
	Str255 deviceName;
	if (!PyArg_ParseTuple(_args, "hO&",
	                      &deviceRefNum,
	                      PyMac_GetStr255, deviceName))
		return NULL;
	_err = SPBSignInDevice(deviceRefNum,
	                       deviceName);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBSignOutDevice(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short deviceRefNum;
	if (!PyArg_ParseTuple(_args, "h",
	                      &deviceRefNum))
		return NULL;
	_err = SPBSignOutDevice(deviceRefNum);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBGetIndexedDevice(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	short count;
	Str255 deviceName;
	Handle deviceIconHandle;
	if (!PyArg_ParseTuple(_args, "h",
	                      &count))
		return NULL;
	_err = SPBGetIndexedDevice(count,
	                           deviceName,
	                           &deviceIconHandle);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&O&",
	                     PyMac_BuildStr255, deviceName,
	                     ResObj_New, deviceIconHandle);
	return _res;
}

static PyObject *Snd_SPBOpenDevice(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	Str255 deviceName;
	short permission;
	long inRefNum;
	if (!PyArg_ParseTuple(_args, "O&h",
	                      PyMac_GetStr255, deviceName,
	                      &permission))
		return NULL;
	_err = SPBOpenDevice(deviceName,
	                     permission,
	                     &inRefNum);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("l",
	                     inRefNum);
	return _res;
}

static PyObject *Snd_SPBCloseDevice(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBCloseDevice(inRefNum);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBRecord(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SPBPtr inParamPtr;
	Boolean asynchFlag;
	if (!PyArg_ParseTuple(_args, "O&b",
	                      SPBObj_Convert, &inParamPtr,
	                      &asynchFlag))
		return NULL;
	_err = SPBRecord(inParamPtr,
	                 asynchFlag);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBPauseRecording(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBPauseRecording(inRefNum);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBResumeRecording(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBResumeRecording(inRefNum);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBStopRecording(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBStopRecording(inRefNum);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBGetRecordingStatus(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	short recordingStatus;
	short meterLevel;
	unsigned long totalSamplesToRecord;
	unsigned long numberOfSamplesRecorded;
	unsigned long totalMsecsToRecord;
	unsigned long numberOfMsecsRecorded;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBGetRecordingStatus(inRefNum,
	                             &recordingStatus,
	                             &meterLevel,
	                             &totalSamplesToRecord,
	                             &numberOfSamplesRecorded,
	                             &totalMsecsToRecord,
	                             &numberOfMsecsRecorded);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("hhllll",
	                     recordingStatus,
	                     meterLevel,
	                     totalSamplesToRecord,
	                     numberOfSamplesRecorded,
	                     totalMsecsToRecord,
	                     numberOfMsecsRecorded);
	return _res;
}

static PyObject *Snd_SPBGetDeviceInfo(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	OSType infoType;
	void * infoData;
	if (!PyArg_ParseTuple(_args, "lO&w",
	                      &inRefNum,
	                      PyMac_GetOSType, &infoType,
	                      &infoData))
		return NULL;
	_err = SPBGetDeviceInfo(inRefNum,
	                        infoType,
	                        infoData);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBSetDeviceInfo(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	OSType infoType;
	void * infoData;
	if (!PyArg_ParseTuple(_args, "lO&w",
	                      &inRefNum,
	                      PyMac_GetOSType, &infoType,
	                      &infoData))
		return NULL;
	_err = SPBSetDeviceInfo(inRefNum,
	                        infoType,
	                        infoData);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}

static PyObject *Snd_SPBMillisecondsToBytes(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	long milliseconds;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBMillisecondsToBytes(inRefNum,
	                              &milliseconds);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("l",
	                     milliseconds);
	return _res;
}

static PyObject *Snd_SPBBytesToMilliseconds(PyObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long inRefNum;
	long byteCount;
	if (!PyArg_ParseTuple(_args, "l",
	                      &inRefNum))
		return NULL;
	_err = SPBBytesToMilliseconds(inRefNum,
	                              &byteCount);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("l",
	                     byteCount);
	return _res;
}
#endif /* __LP64__ */

static PyMethodDef Snd_methods[] = {
#ifndef __LP64__
	{"SPB", (PyCFunction)Snd_SPB, 1,
	 PyDoc_STR(NULL)},
	{"SysBeep", (PyCFunction)Snd_SysBeep, 1,
	 PyDoc_STR("(short duration) -> None")},
	{"SndNewChannel", (PyCFunction)Snd_SndNewChannel, 1,
	 PyDoc_STR("(short synth, long init, PyObject* userRoutine) -> (SndChannelPtr chan)")},
	{"SndSoundManagerVersion", (PyCFunction)Snd_SndSoundManagerVersion, 1,
	 PyDoc_STR("() -> (NumVersion _rv)")},
	{"SndManagerStatus", (PyCFunction)Snd_SndManagerStatus, 1,
	 PyDoc_STR("(short theLength) -> (SMStatus theStatus)")},
	{"SndGetSysBeepState", (PyCFunction)Snd_SndGetSysBeepState, 1,
	 PyDoc_STR("() -> (short sysBeepState)")},
	{"SndSetSysBeepState", (PyCFunction)Snd_SndSetSysBeepState, 1,
	 PyDoc_STR("(short sysBeepState) -> None")},
	{"GetSysBeepVolume", (PyCFunction)Snd_GetSysBeepVolume, 1,
	 PyDoc_STR("() -> (long level)")},
	{"SetSysBeepVolume", (PyCFunction)Snd_SetSysBeepVolume, 1,
	 PyDoc_STR("(long level) -> None")},
	{"GetDefaultOutputVolume", (PyCFunction)Snd_GetDefaultOutputVolume, 1,
	 PyDoc_STR("() -> (long level)")},
	{"SetDefaultOutputVolume", (PyCFunction)Snd_SetDefaultOutputVolume, 1,
	 PyDoc_STR("(long level) -> None")},
	{"GetSoundHeaderOffset", (PyCFunction)Snd_GetSoundHeaderOffset, 1,
	 PyDoc_STR("(SndListHandle sndHandle) -> (long offset)")},
	{"GetCompressionInfo", (PyCFunction)Snd_GetCompressionInfo, 1,
	 PyDoc_STR("(short compressionID, OSType format, short numChannels, short sampleSize) -> (CompressionInfo cp)")},
	{"SetSoundPreference", (PyCFunction)Snd_SetSoundPreference, 1,
	 PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
	{"GetSoundPreference", (PyCFunction)Snd_GetSoundPreference, 1,
	 PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
	{"GetCompressionName", (PyCFunction)Snd_GetCompressionName, 1,
	 PyDoc_STR("(OSType compressionType) -> (Str255 compressionName)")},
	{"SPBVersion", (PyCFunction)Snd_SPBVersion, 1,
	 PyDoc_STR("() -> (NumVersion _rv)")},
	{"SndRecord", (PyCFunction)Snd_SndRecord, 1,
	 PyDoc_STR("(Point corner, OSType quality) -> (SndListHandle sndHandle)")},
	{"SPBSignInDevice", (PyCFunction)Snd_SPBSignInDevice, 1,
	 PyDoc_STR("(short deviceRefNum, Str255 deviceName) -> None")},
	{"SPBSignOutDevice", (PyCFunction)Snd_SPBSignOutDevice, 1,
	 PyDoc_STR("(short deviceRefNum) -> None")},
	{"SPBGetIndexedDevice", (PyCFunction)Snd_SPBGetIndexedDevice, 1,
	 PyDoc_STR("(short count) -> (Str255 deviceName, Handle deviceIconHandle)")},
	{"SPBOpenDevice", (PyCFunction)Snd_SPBOpenDevice, 1,
	 PyDoc_STR("(Str255 deviceName, short permission) -> (long inRefNum)")},
	{"SPBCloseDevice", (PyCFunction)Snd_SPBCloseDevice, 1,
	 PyDoc_STR("(long inRefNum) -> None")},
	{"SPBRecord", (PyCFunction)Snd_SPBRecord, 1,
	 PyDoc_STR("(SPBPtr inParamPtr, Boolean asynchFlag) -> None")},
	{"SPBPauseRecording", (PyCFunction)Snd_SPBPauseRecording, 1,
	 PyDoc_STR("(long inRefNum) -> None")},
	{"SPBResumeRecording", (PyCFunction)Snd_SPBResumeRecording, 1,
	 PyDoc_STR("(long inRefNum) -> None")},
	{"SPBStopRecording", (PyCFunction)Snd_SPBStopRecording, 1,
	 PyDoc_STR("(long inRefNum) -> None")},
	{"SPBGetRecordingStatus", (PyCFunction)Snd_SPBGetRecordingStatus, 1,
	 PyDoc_STR("(long inRefNum) -> (short recordingStatus, short meterLevel, unsigned long totalSamplesToRecord, unsigned long numberOfSamplesRecorded, unsigned long totalMsecsToRecord, unsigned long numberOfMsecsRecorded)")},
	{"SPBGetDeviceInfo", (PyCFunction)Snd_SPBGetDeviceInfo, 1,
	 PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
	{"SPBSetDeviceInfo", (PyCFunction)Snd_SPBSetDeviceInfo, 1,
	 PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
	{"SPBMillisecondsToBytes", (PyCFunction)Snd_SPBMillisecondsToBytes, 1,
	 PyDoc_STR("(long inRefNum) -> (long milliseconds)")},
	{"SPBBytesToMilliseconds", (PyCFunction)Snd_SPBBytesToMilliseconds, 1,
	 PyDoc_STR("(long inRefNum) -> (long byteCount)")},
#endif /* __LP64__ */
	{NULL, NULL, 0}
};


#ifndef __LP64__

/* Routine passed to Py_AddPendingCall -- call the Python callback */
static int
SndCh_CallCallBack(void *arg)
{
        SndChannelObject *p = (SndChannelObject *)arg;
        PyObject *args;
        PyObject *res;
        args = Py_BuildValue("(O(hhl))",
                             p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
        res = PyEval_CallObject(p->ob_callback, args);
        Py_DECREF(args);
        if (res == NULL)
                return -1;
        Py_DECREF(res);
        return 0;
}

/* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
static pascal void
SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
{
        SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
        if (p->ob_callback != NULL) {
                long A5 = SetA5(p->ob_A5);
                p->ob_cmd = *cmd;
                Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
                SetA5(A5);
        }
}

/* SPB callbacks - Schedule callbacks to Python */
static int
SPB_CallCallBack(void *arg)
{
        SPBObject *p = (SPBObject *)arg;
        PyObject *args;
        PyObject *res;

        if ( p->ob_thiscallback == 0 ) return 0;
        args = Py_BuildValue("(O)", p);
        res = PyEval_CallObject(p->ob_thiscallback, args);
        p->ob_thiscallback = 0;
        Py_DECREF(args);
        if (res == NULL)
                return -1;
        Py_DECREF(res);
        return 0;
}

static pascal void
SPB_completion(SPBPtr my_spb)
{
        SPBObject *p = (SPBObject *)(my_spb->userLong);

        if (p && p->ob_completion) {
                long A5 = SetA5(p->ob_A5);
                p->ob_thiscallback = p->ob_completion;  /* Hope we cannot get two at the same time */
                Py_AddPendingCall(SPB_CallCallBack, (void *)p);
                SetA5(A5);
        }
}
#endif /* __LP64__ */



void init_Snd(void)
{
	PyObject *m;
#ifndef __LP64__
	PyObject *d;
#endif /* __LP64__ */





	m = Py_InitModule("_Snd", Snd_methods);
#ifndef __LP64__
	d = PyModule_GetDict(m);
	Snd_Error = PyMac_GetOSErrException();
	if (Snd_Error == NULL ||
	    PyDict_SetItemString(d, "Error", Snd_Error) != 0)
		return;
	SndChannel_Type.ob_type = &PyType_Type;
	if (PyType_Ready(&SndChannel_Type) < 0) return;
	Py_INCREF(&SndChannel_Type);
	PyModule_AddObject(m, "SndChannel", (PyObject *)&SndChannel_Type);
	/* Backward-compatible name */
	Py_INCREF(&SndChannel_Type);
	PyModule_AddObject(m, "SndChannelType", (PyObject *)&SndChannel_Type);
	SPB_Type.ob_type = &PyType_Type;
	if (PyType_Ready(&SPB_Type) < 0) return;
	Py_INCREF(&SPB_Type);
	PyModule_AddObject(m, "SPB", (PyObject *)&SPB_Type);
	/* Backward-compatible name */
	Py_INCREF(&SPB_Type);
	PyModule_AddObject(m, "SPBType", (PyObject *)&SPB_Type);
#endif /* __LP64__ */
}

/* ======================== End module _Snd ========================= */