cinap_lenrekadd hg and python4bb9e2215 years agoHistory
796 lines · 18.8 KB · C
RawDownload
/* CD module -- interface to Mark Callow's and Roger Chickering's */ /* CD Audio Library (CD). */ #include <sys/types.h>#include <cdaudio.h>#include "Python.h" #define NCALLBACKS	8 typedef struct {	PyObject_HEAD	CDPLAYER *ob_cdplayer;} cdplayerobject; static PyObject *CdError;		/* exception cd.error */ static PyObject *CD_allowremoval(cdplayerobject *self, PyObject *args){	if (!PyArg_ParseTuple(args, ":allowremoval"))		return NULL; 	CDallowremoval(self->ob_cdplayer); 	Py_INCREF(Py_None);	return Py_None;} static PyObject *CD_preventremoval(cdplayerobject *self, PyObject *args){	if (!PyArg_ParseTuple(args, ":preventremoval"))		return NULL; 	CDpreventremoval(self->ob_cdplayer); 	Py_INCREF(Py_None);	return Py_None;} static PyObject *CD_bestreadsize(cdplayerobject *self, PyObject *args){	if (!PyArg_ParseTuple(args, ":bestreadsize"))		return NULL; 	return PyInt_FromLong((long) CDbestreadsize(self->ob_cdplayer));} static PyObject *CD_close(cdplayerobject *self, PyObject *args){	if (!PyArg_ParseTuple(args, ":close"))		return NULL; 	if (!CDclose(self->ob_cdplayer)) {		PyErr_SetFromErrno(CdError); /* XXX - ??? */		return NULL;	}	self->ob_cdplayer = NULL; 	Py_INCREF(Py_None);	return Py_None;} static PyObject *CD_eject(cdplayerobject *self, PyObject *args){	CDSTATUS status; 	if (!PyArg_ParseTuple(args, ":eject"))		return NULL; 	if (!CDeject(self->ob_cdplayer)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "eject failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyObject *CD_getstatus(cdplayerobject *self, PyObject *args){	CDSTATUS status; 	if (!PyArg_ParseTuple(args, ":getstatus"))		return NULL; 	if (!CDgetstatus(self->ob_cdplayer, &status)) {		PyErr_SetFromErrno(CdError); /* XXX - ??? */		return NULL;	} 	return Py_BuildValue("(ii(iii)(iii)(iii)iiii)", status.state,		       status.track, status.min, status.sec, status.frame,		       status.abs_min, status.abs_sec, status.abs_frame,		       status.total_min, status.total_sec, status.total_frame,		       status.first, status.last, status.scsi_audio,		       status.cur_block);}	static PyObject *CD_gettrackinfo(cdplayerobject *self, PyObject *args){	int track;	CDTRACKINFO info;	CDSTATUS status; 	if (!PyArg_ParseTuple(args, "i:gettrackinfo", &track))		return NULL; 	if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "gettrackinfo failed");		return NULL;	} 	return Py_BuildValue("((iii)(iii))",		       info.start_min, info.start_sec, info.start_frame,		       info.total_min, info.total_sec, info.total_frame);}	static PyObject *CD_msftoblock(cdplayerobject *self, PyObject *args){	int min, sec, frame; 	if (!PyArg_ParseTuple(args, "iii:msftoblock", &min, &sec, &frame))		return NULL; 	return PyInt_FromLong((long) CDmsftoblock(self->ob_cdplayer,						min, sec, frame));}	static PyObject *CD_play(cdplayerobject *self, PyObject *args){	int start, play;	CDSTATUS status; 	if (!PyArg_ParseTuple(args, "ii:play", &start, &play))		return NULL; 	if (!CDplay(self->ob_cdplayer, start, play)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "play failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyObject *CD_playabs(cdplayerobject *self, PyObject *args){	int min, sec, frame, play;	CDSTATUS status; 	if (!PyArg_ParseTuple(args, "iiii:playabs", &min, &sec, &frame, &play))		return NULL; 	if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "playabs failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyObject *CD_playtrack(cdplayerobject *self, PyObject *args){	int start, play;	CDSTATUS status; 	if (!PyArg_ParseTuple(args, "ii:playtrack", &start, &play))		return NULL; 	if (!CDplaytrack(self->ob_cdplayer, start, play)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "playtrack failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyObject *CD_playtrackabs(cdplayerobject *self, PyObject *args){	int track, min, sec, frame, play;	CDSTATUS status; 	if (!PyArg_ParseTuple(args, "iiiii:playtrackabs", &track, &min, &sec,			      &frame, &play))		return NULL; 	if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "playtrackabs failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyObject *CD_readda(cdplayerobject *self, PyObject *args){	int numframes, n;	PyObject *result; 	if (!PyArg_ParseTuple(args, "i:readda", &numframes))		return NULL; 	result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME));	if (result == NULL)		return NULL; 	n = CDreadda(self->ob_cdplayer,		       (CDFRAME *) PyString_AsString(result), numframes);	if (n == -1) {		Py_DECREF(result);		PyErr_SetFromErrno(CdError);		return NULL;	}	if (n < numframes)		_PyString_Resize(&result, n * sizeof(CDFRAME)); 	return result;} static PyObject *CD_seek(cdplayerobject *self, PyObject *args){	int min, sec, frame;	long PyTryBlock; 	if (!PyArg_ParseTuple(args, "iii:seek", &min, &sec, &frame))		return NULL; 	PyTryBlock = CDseek(self->ob_cdplayer, min, sec, frame);	if (PyTryBlock == -1) {		PyErr_SetFromErrno(CdError);		return NULL;	} 	return PyInt_FromLong(PyTryBlock);}	static PyObject *CD_seektrack(cdplayerobject *self, PyObject *args){	int track;	long PyTryBlock; 	if (!PyArg_ParseTuple(args, "i:seektrack", &track))		return NULL; 	PyTryBlock = CDseektrack(self->ob_cdplayer, track);	if (PyTryBlock == -1) {		PyErr_SetFromErrno(CdError);		return NULL;	} 	return PyInt_FromLong(PyTryBlock);}	static PyObject *CD_seekblock(cdplayerobject *self, PyObject *args){	unsigned long PyTryBlock; 	if (!PyArg_ParseTuple(args, "l:seekblock", &PyTryBlock))		return NULL; 	PyTryBlock = CDseekblock(self->ob_cdplayer, PyTryBlock);	if (PyTryBlock == (unsigned long) -1) {		PyErr_SetFromErrno(CdError);		return NULL;	} 	return PyInt_FromLong(PyTryBlock);}	static PyObject *CD_stop(cdplayerobject *self, PyObject *args){	CDSTATUS status; 	if (!PyArg_ParseTuple(args, ":stop"))		return NULL; 	if (!CDstop(self->ob_cdplayer)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "stop failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyObject *CD_togglepause(cdplayerobject *self, PyObject *args){	CDSTATUS status; 	if (!PyArg_ParseTuple(args, ":togglepause"))		return NULL; 	if (!CDtogglepause(self->ob_cdplayer)) {		if (CDgetstatus(self->ob_cdplayer, &status) &&		    status.state == CD_NODISC)			PyErr_SetString(CdError, "no disc in player");		else			PyErr_SetString(CdError, "togglepause failed");		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;}	static PyMethodDef cdplayer_methods[] = {	{"allowremoval",	(PyCFunction)CD_allowremoval,	METH_VARARGS},	{"bestreadsize",	(PyCFunction)CD_bestreadsize,	METH_VARARGS},	{"close",		(PyCFunction)CD_close,		METH_VARARGS},	{"eject",		(PyCFunction)CD_eject,		METH_VARARGS},	{"getstatus",		(PyCFunction)CD_getstatus,		METH_VARARGS},	{"gettrackinfo",	(PyCFunction)CD_gettrackinfo,	METH_VARARGS},	{"msftoblock",		(PyCFunction)CD_msftoblock,		METH_VARARGS},	{"play",		(PyCFunction)CD_play,		METH_VARARGS},	{"playabs",		(PyCFunction)CD_playabs,		METH_VARARGS},	{"playtrack",		(PyCFunction)CD_playtrack,		METH_VARARGS},	{"playtrackabs",	(PyCFunction)CD_playtrackabs,	METH_VARARGS},	{"preventremoval",	(PyCFunction)CD_preventremoval,	METH_VARARGS},	{"readda",		(PyCFunction)CD_readda,		METH_VARARGS},	{"seek",		(PyCFunction)CD_seek,		METH_VARARGS},	{"seekblock",		(PyCFunction)CD_seekblock,		METH_VARARGS},	{"seektrack",		(PyCFunction)CD_seektrack,		METH_VARARGS},	{"stop",		(PyCFunction)CD_stop,		METH_VARARGS},	{"togglepause",		(PyCFunction)CD_togglepause,   	METH_VARARGS},	{NULL,			NULL} 		/* sentinel */}; static voidcdplayer_dealloc(cdplayerobject *self){	if (self->ob_cdplayer != NULL)		CDclose(self->ob_cdplayer);	PyObject_Del(self);} static PyObject *cdplayer_getattr(cdplayerobject *self, char *name){	if (self->ob_cdplayer == NULL) {		PyErr_SetString(PyExc_RuntimeError, "no player active");		return NULL;	}	return Py_FindMethod(cdplayer_methods, (PyObject *)self, name);} PyTypeObject CdPlayertype = {	PyObject_HEAD_INIT(&PyType_Type)	0,			/*ob_size*/	"cd.cdplayer",	/*tp_name*/	sizeof(cdplayerobject),	/*tp_size*/	0,			/*tp_itemsize*/	/* methods */	(destructor)cdplayer_dealloc, /*tp_dealloc*/	0,			/*tp_print*/	(getattrfunc)cdplayer_getattr, /*tp_getattr*/	0,			/*tp_setattr*/	0,			/*tp_compare*/	0,			/*tp_repr*/}; static PyObject *newcdplayerobject(CDPLAYER *cdp){	cdplayerobject *p; 	p = PyObject_New(cdplayerobject, &CdPlayertype);	if (p == NULL)		return NULL;	p->ob_cdplayer = cdp;	return (PyObject *) p;} static PyObject *CD_open(PyObject *self, PyObject *args){	char *dev, *direction;	CDPLAYER *cdp; 	/*	 * Variable number of args.	 * First defaults to "None", second defaults to "r".	 */	dev = NULL;	direction = "r";	if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction))		return NULL; 	cdp = CDopen(dev, direction);	if (cdp == NULL) {		PyErr_SetFromErrno(CdError);		return NULL;	} 	return newcdplayerobject(cdp);} typedef struct {	PyObject_HEAD	CDPARSER *ob_cdparser;	struct {		PyObject *ob_cdcallback;		PyObject *ob_cdcallbackarg;	} ob_cdcallbacks[NCALLBACKS];} cdparserobject; static voidCD_callback(void *arg, CDDATATYPES type, void *data){	PyObject *result, *args, *v = NULL;	char *p;	int i;	cdparserobject *self; 	self = (cdparserobject *) arg;	args = PyTuple_New(3);	if (args == NULL)		return;	Py_INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);	PyTuple_SetItem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);	PyTuple_SetItem(args, 1, PyInt_FromLong((long) type));	switch (type) {	case cd_audio:		v = PyString_FromStringAndSize(data, CDDA_DATASIZE);		break;	case cd_pnum:	case cd_index:		v = PyInt_FromLong(((CDPROGNUM *) data)->value);		break;	case cd_ptime:	case cd_atime:#define ptr ((struct cdtimecode *) data)		v = Py_BuildValue("(iii)",			    ptr->mhi * 10 + ptr->mlo,			    ptr->shi * 10 + ptr->slo,			    ptr->fhi * 10 + ptr->flo);#undef ptr		break;	case cd_catalog:		v = PyString_FromStringAndSize(NULL, 13);		p = PyString_AsString(v);		for (i = 0; i < 13; i++)			*p++ = ((char *) data)[i] + '0';		break;	case cd_ident:#define ptr ((struct cdident *) data)		v = PyString_FromStringAndSize(NULL, 12);		p = PyString_AsString(v);		CDsbtoa(p, ptr->country, 2);		p += 2;		CDsbtoa(p, ptr->owner, 3);		p += 3;		*p++ = ptr->year[0] + '0';

Lines 1–500 of 796.