From c05907ad793435ab088999d020c4f00178ea7793 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 22 Feb 2007 21:14:13 +0100 Subject: [PATCH] added alsacard python module to cover card management and device name hints --- pyalsa/alsacard.c | 239 ++++++++++++++++++++++++++++++++++++++++++++ pyalsa/cardtest1.py | 13 +++ setup.py | 13 ++- 3 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 pyalsa/alsacard.c create mode 100755 pyalsa/cardtest1.py diff --git a/pyalsa/alsacard.c b/pyalsa/alsacard.c new file mode 100644 index 0000000..040c4be --- /dev/null +++ b/pyalsa/alsacard.c @@ -0,0 +1,239 @@ +/* + * Python binding for the ALSA library - card management + * Copyright (c) 2007 by Jaroslav Kysela + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "Python.h" +#include "structmember.h" +#include "frameobject.h" +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#include "sys/poll.h" +#include "stdlib.h" +#include "alsa/asoundlib.h" + +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif +#ifndef Py_RETURN_TRUE +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#endif +#ifndef Py_RETURN_FALSE +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#endif + +static PyObject *module; + +/* + * + */ + +PyDoc_STRVAR(asoundlib_version__doc__, +"asoundlib_version() -- Return asoundlib version string."); + +static PyObject * +asoundlib_version(PyObject *self, PyObject *args) +{ + return Py_BuildValue("s", snd_asoundlib_version()); +} + +PyDoc_STRVAR(card_load__doc__, +"cardLoad([card]) -- Load driver for given card."); + +static PyObject * +card_load(PyObject *self, PyObject *args, PyObject *kwds) +{ + int card = 0; + static char * kwlist[] = { "card", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &card)) + Py_RETURN_NONE; + + return Py_BuildValue("i", snd_card_load(card)); +} + +PyDoc_STRVAR(card_list__doc__, +"cardList() -- Get a card number list in tuple."); + +static PyObject * +card_list(PyObject *self, PyObject *args) +{ + PyObject *t; + int size = 0, i = -1, res; + + t = PyTuple_New(0); + if (!t) + return NULL; + while (1) { + res = snd_card_next(&i); + if (res) { + Py_DECREF(t); + return PyErr_Format(PyExc_IOError, "Cannot get next card: %s", snd_strerror(res)); + } + if (i < 0) + break; + size++; + if (_PyTuple_Resize(&t, size)) + return NULL; + PyTuple_SET_ITEM(t, size - 1, PyInt_FromLong(i)); + } + return t; +} + +PyDoc_STRVAR(card_get_index__doc__, +"cardGetIndex(name) -- Get card index using ID string."); + +static PyObject * +card_get_index(PyObject *self, PyObject *args, PyObject *kwds) +{ + char *card; + static char * kwlist[] = { "name", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &card)) + Py_RETURN_NONE; + + return Py_BuildValue("i", snd_card_get_index(card)); +} + +PyDoc_STRVAR(card_get_name__doc__, +"cardGetName(card) -- Get card name string using card index."); + +static PyObject * +card_get_name(PyObject *self, PyObject *args, PyObject *kwds) +{ + int card, res; + char *str; + static char * kwlist[] = { "card", NULL }; + PyObject *t; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &card)) + Py_RETURN_NONE; + + res = snd_card_get_name(card, &str); + if (res) + return PyErr_Format(PyExc_IOError, "Cannot get card name: %s", snd_strerror(res)); + t = Py_BuildValue("s", str); + free(str); + return t; +} + +PyDoc_STRVAR(card_get_longname__doc__, +"cardGetLongname(card) -- Get long card name string using card index."); + +static PyObject * +card_get_longname(PyObject *self, PyObject *args, PyObject *kwds) +{ + int card, res; + char *str; + static char * kwlist[] = { "card", NULL }; + PyObject *t; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &card)) + Py_RETURN_NONE; + + res = snd_card_get_longname(card, &str); + if (res) + return PyErr_Format(PyExc_IOError, "Cannot get card longname: %s", snd_strerror(res)); + t = Py_BuildValue("s", str); + free(str); + return t; +} + +PyDoc_STRVAR(device_name_hint__doc__, +"deviceNameHint(card, interface) -- Get device name hints."); + +static PyObject * +device_name_hint(PyObject *self, PyObject *args, PyObject *kwds) +{ + int card, res; + char *iface, **hint; + void **hints; + static char * kwlist[] = { "card", "interface", NULL }; + static char * ids[] = { "NAME", "DESC", "IOID", NULL }; + PyObject *l, *d, *v; + char **id, *str; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "is", kwlist, &card, &iface)) + Py_RETURN_NONE; + + res = snd_device_name_hint(card, iface, &hints); + if (res) + return PyErr_Format(PyExc_IOError, "Cannot get card longname: %s", snd_strerror(res)); + + l = PyList_New(0); + + hint = (char **)hints; + while (*hint) { + d = PyDict_New(); + if (d == NULL) + goto err1; + id = ids; + while (*id) { + str = snd_device_name_get_hint(*hint, *id); + if (str == NULL) + break; + v = PyString_FromString(str); + free(str); + if (v == NULL) + goto err1; + if (PyDict_SetItemString(d, *id, v)) + goto err1; + id++; + } + if (PyList_Append(l, d)) + goto err1; + hint++; + } + + snd_device_name_free_hint(hints); + return l; + + err1: + Py_XDECREF(d); + Py_XDECREF(l); + snd_device_name_free_hint(hints); + return NULL; +} + +/* + * + */ + +static PyMethodDef pyalsacardparse_methods[] = { + {"asoundlibVersion", (PyCFunction)asoundlib_version, METH_NOARGS, asoundlib_version__doc__}, + {"cardLoad", (PyCFunction)card_load, METH_VARARGS|METH_KEYWORDS, card_load__doc__}, + {"cardList", (PyCFunction)card_list, METH_NOARGS, card_list__doc__}, + {"cardGetIndex", (PyCFunction)card_get_index, METH_VARARGS|METH_KEYWORDS, card_get_index__doc__}, + {"cardGetName", (PyCFunction)card_get_name, METH_VARARGS|METH_KEYWORDS, card_get_name__doc__}, + {"cardGetLongname", (PyCFunction)card_get_longname, METH_VARARGS|METH_KEYWORDS, card_get_longname__doc__}, + {"deviceNameHint", (PyCFunction)device_name_hint, METH_VARARGS|METH_KEYWORDS, device_name_hint__doc__}, + {NULL} +}; + +PyMODINIT_FUNC +initalsacard(void) +{ + module = Py_InitModule3("alsacard", pyalsacardparse_methods, "libasound alsacard wrapper"); + if (module == NULL) + return; + + if (PyErr_Occurred()) + Py_FatalError("Cannot initialize module alsacard"); +} diff --git a/pyalsa/cardtest1.py b/pyalsa/cardtest1.py new file mode 100755 index 0000000..9b19290 --- /dev/null +++ b/pyalsa/cardtest1.py @@ -0,0 +1,13 @@ +#! /usr/bin/python +# -*- Python -*- + +import alsacard + +print 'asoundlibVersion:', alsacard.asoundlibVersion() +print 'cardLoad:', alsacard.cardLoad(0) +print 'cardList:', alsacard.cardList() +print 'deviceNameHint for all cards:' +print alsacard.deviceNameHint(-1, "pcm") +for card in alsacard.cardList(): + print 'deviceNameHint for card #%i:' % card + print alsacard.deviceNameHint(card, "pcm") diff --git a/setup.py b/setup.py index ac8ce9d..7f07942 100755 --- a/setup.py +++ b/setup.py @@ -11,17 +11,24 @@ setup( author="The ALSA Team", author_email='alsa-devel@alsa-project.org', ext_modules=[ - Extension('pyalsa.alsamixer', ['pyalsa/alsamixer.c'], + Extension('pyalsa.alsacard', + ['pyalsa/alsacard.c'], include_dirs=[], library_dirs=[], - libraries=['asound'])], + libraries=['asound']), + Extension('pyalsa.alsamixer', + ['pyalsa/alsamixer.c'], + include_dirs=[], + library_dirs=[], + libraries=['asound']), + ], packages=['pyalsa'], scripts=[] ) uname = os.uname() a = 'build/lib.%s-%s-%s' % (uname[0].lower(), uname[4], sys.version[:3]) -for f in ['alsamixer.so']: +for f in ['alsacard.so', 'alsamixer.so']: if not os.path.exists('pyalsa/%s' % f): a = '../build/lib.%s-%s-%s/pyalsa/%s' % (uname[0].lower(), uname[4], sys.version[:3], f) -- 2.47.1