From c8e7261e94165db01fbfed752690949382b02507 Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Tue, 27 Oct 2020 12:41:59 +0100 Subject: [PATCH 1/5] Add an PCM.info function returning the information now printed by dumpinfo as a dictionary. Removed double entry from dumpinfo. --- alsaaudio.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/alsaaudio.c b/alsaaudio.c index 75e628b..2394506 100644 --- a/alsaaudio.c +++ b/alsaaudio.c @@ -602,9 +602,6 @@ alsapcm_dumpinfo(alsapcm_t *self, PyObject *args) val = snd_pcm_hw_params_get_sbits(hwparams); printf("significant bits = %d\n", val); - snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); - printf("period time = %d us\n", val); - val = snd_pcm_hw_params_is_batch(hwparams); printf("is batch = %d\n", val); @@ -639,6 +636,164 @@ alsapcm_dumpinfo(alsapcm_t *self, PyObject *args) return Py_None; } + +static PyObject * +alsapcm_info(alsapcm_t *self, PyObject *args) +{ + PyObject *info = PyDict_New(); + PyObject *pname; + PyObject *value; + + unsigned int val,val2; + snd_pcm_format_t fmt; + int dir; + snd_pcm_uframes_t frames; + snd_pcm_hw_params_t *hwparams; + snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_hw_params_current(self->handle,hwparams); + + if (!PyArg_ParseTuple(args,":dumpinfo")) + return NULL; + + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } + + printf("PCM handle name = '%s'\n", snd_pcm_name(self->handle)); + + + pname=PyUnicode_FromString("name"); + value=PyUnicode_FromString(snd_pcm_name(self->handle)); + PyDict_SetItem(info,pname,value); + + pname=PyUnicode_FromString("state"); + value=PyUnicode_FromString(snd_pcm_state_name(snd_pcm_state(self->handle))); + PyDict_SetItem(info,pname,value); + + pname=PyUnicode_FromString("access_type"); + snd_pcm_hw_params_get_access(hwparams, (snd_pcm_access_t *) &val); + value=PyUnicode_FromString(snd_pcm_access_name((snd_pcm_access_t)val)); + PyDict_SetItem(info,pname,value); + + snd_pcm_hw_params_get_format(hwparams, &fmt); + pname=PyUnicode_FromString("format_name"); + value=PyUnicode_FromString(snd_pcm_format_name(fmt)); + PyDict_SetItem(info,pname,value); + pname=PyUnicode_FromString("format_description"); + value=PyUnicode_FromString(snd_pcm_format_description(fmt)); + PyDict_SetItem(info,pname,value); + + + snd_pcm_hw_params_get_subformat(hwparams, (snd_pcm_subformat_t *)&val); + pname=PyUnicode_FromString("subformat_name"); + value=PyUnicode_FromString(snd_pcm_subformat_name((snd_pcm_subformat_t)val)); + PyDict_SetItem(info,pname,value); + pname=PyUnicode_FromString("subformat_description"); + value=PyUnicode_FromString(snd_pcm_subformat_description((snd_pcm_subformat_t)val)); + PyDict_SetItem(info,pname,value); + + pname=PyUnicode_FromString("channels"); + snd_pcm_hw_params_get_channels(hwparams, &val); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("rate"); + snd_pcm_hw_params_get_rate(hwparams, &val, &dir); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("period_time"); + snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("period_size"); + snd_pcm_hw_params_get_period_size(hwparams, &frames, &dir); + value=PyLong_FromUnsignedLong((unsigned long) frames); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("buffer_time"); + snd_pcm_hw_params_get_buffer_time(hwparams, &val, &dir); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("buffer_size"); + snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t *) &val); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("get_periods"); + snd_pcm_hw_params_get_periods(hwparams, &val, &dir); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("rate_numden"); + snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2); + + value=PyTuple_Pack(2,PyLong_FromUnsignedLong((unsigned long) val) \ + ,PyLong_FromUnsignedLong((unsigned long) val2)); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("significant_bits"); + val = snd_pcm_hw_params_get_sbits(hwparams); + value=PyLong_FromUnsignedLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("is_batch"); + val = snd_pcm_hw_params_is_batch(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("is_block_transfer"); + val = snd_pcm_hw_params_is_block_transfer(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("is_double"); + val = snd_pcm_hw_params_is_double(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("is_half_duplex"); + val = snd_pcm_hw_params_is_half_duplex(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("is_joint_duplex"); + val = snd_pcm_hw_params_is_joint_duplex(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("can_overrange"); + val = snd_pcm_hw_params_can_overrange(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("can_mmap_sample_resolution"); + val = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + pname=PyUnicode_FromString("can_pause"); + val = snd_pcm_hw_params_can_pause(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + + pname=PyUnicode_FromString("can_resume"); + val = snd_pcm_hw_params_can_resume(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + + pname=PyUnicode_FromString("can_sync_start"); + val = snd_pcm_hw_params_can_sync_start(hwparams); + value=PyBool_FromLong((unsigned long) val); + PyDict_SetItem(info,pname, value); + + return info; +} // auxiliary function @@ -1371,6 +1526,7 @@ static PyMethodDef alsapcm_methods[] = { {"setperiodsize", (PyCFunction)alsapcm_setperiodsize, METH_VARARGS, setperiodsize_doc}, {"dumpinfo", (PyCFunction)alsapcm_dumpinfo, METH_VARARGS}, + {"info", (PyCFunction)alsapcm_info, METH_VARARGS}, {"getformats", (PyCFunction)alsapcm_getformats, METH_VARARGS, getformats_doc}, {"getratebounds", (PyCFunction)alsapcm_getratemaxmin, METH_VARARGS, getratebounds_doc}, {"getrates", (PyCFunction)alsapcm_getrates, METH_VARARGS, getrates_doc}, From e48b294b846bf353b07a51169fbb30fd5a06d074 Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Wed, 28 Oct 2020 22:01:04 +0100 Subject: [PATCH 2/5] PCM.info function: added format, mode and type fields. Also added a doc string describing the info function. --- alsaaudio.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/alsaaudio.c b/alsaaudio.c index 2394506..bc15ba4 100644 --- a/alsaaudio.c +++ b/alsaaudio.c @@ -676,7 +676,35 @@ alsapcm_info(alsapcm_t *self, PyObject *args) value=PyUnicode_FromString(snd_pcm_access_name((snd_pcm_access_t)val)); PyDict_SetItem(info,pname,value); + pname=PyUnicode_FromString(" (call value) type"); + value = PyLong_FromUnsignedLong((unsigned long) self->pcmtype); + PyDict_SetItem(info,pname,value); + pname=PyUnicode_FromString(" (call value) type_name"); + value=PyUnicode_FromString(snd_pcm_stream_name((snd_pcm_stream_t) self->pcmtype)); + PyDict_SetItem(info,pname,value); + + + pname=PyUnicode_FromString(" (call value) mode"); + value = PyLong_FromUnsignedLong((unsigned long) self->pcmmode); + PyDict_SetItem(info,pname,value); + pname=PyUnicode_FromString(" (call value) mode_name"); + switch(self->pcmmode){ + case 0: + value = PyUnicode_FromString("PCM_NORMAL"); + break; + case SND_PCM_NONBLOCK: + value = PyUnicode_FromString("PCM_NONBLOCK"); + break; + case SND_PCM_ASYNC: + value = PyUnicode_FromString("PCM_ASYNC"); + break; + } + PyDict_SetItem(info,pname,value); + snd_pcm_hw_params_get_format(hwparams, &fmt); + pname=PyUnicode_FromString("format"); + value=PyLong_FromUnsignedLong((unsigned long)fmt); + PyDict_SetItem(info,pname,value); pname=PyUnicode_FromString("format_name"); value=PyUnicode_FromString(snd_pcm_format_name(fmt)); PyDict_SetItem(info,pname,value); @@ -730,7 +758,6 @@ alsapcm_info(alsapcm_t *self, PyObject *args) pname=PyUnicode_FromString("rate_numden"); snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2); - value=PyTuple_Pack(2,PyLong_FromUnsignedLong((unsigned long) val) \ ,PyLong_FromUnsignedLong((unsigned long) val2)); PyDict_SetItem(info,pname, value); @@ -794,6 +821,16 @@ alsapcm_info(alsapcm_t *self, PyObject *args) return info; } + + +PyDoc_STRVAR(pcm_info_doc, +"info() -> dict\n\ +\n\ +Returns a dictionary with the alsa device parameters as it is realized. \n\ +Keys are retrieved from the alsa library if they can be accessed, if not \n\ +they represent values stored by pyalsaaudio and they are prefixed with ' (call value) '. \n\ +"); + // auxiliary function @@ -1526,7 +1563,7 @@ static PyMethodDef alsapcm_methods[] = { {"setperiodsize", (PyCFunction)alsapcm_setperiodsize, METH_VARARGS, setperiodsize_doc}, {"dumpinfo", (PyCFunction)alsapcm_dumpinfo, METH_VARARGS}, - {"info", (PyCFunction)alsapcm_info, METH_VARARGS}, + {"info", (PyCFunction)alsapcm_info, METH_VARARGS, pcm_info_doc}, {"getformats", (PyCFunction)alsapcm_getformats, METH_VARARGS, getformats_doc}, {"getratebounds", (PyCFunction)alsapcm_getratemaxmin, METH_VARARGS, getratebounds_doc}, {"getrates", (PyCFunction)alsapcm_getrates, METH_VARARGS, getrates_doc}, From a53ffd0d4f726cab9f4ada04694a6750f0feb612 Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Fri, 2 Apr 2021 13:00:44 +0200 Subject: [PATCH 3/5] Fix potential memory leaks on new info function. (cherry picked from commit ade9dd5923edd65c1fcdf2298e8ad024daf66e2a) --- alsaaudio.c | 131 +++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 68 deletions(-) diff --git a/alsaaudio.c b/alsaaudio.c index bc15ba4..2f79af0 100644 --- a/alsaaudio.c +++ b/alsaaudio.c @@ -641,7 +641,6 @@ static PyObject * alsapcm_info(alsapcm_t *self, PyObject *args) { PyObject *info = PyDict_New(); - PyObject *pname; PyObject *value; unsigned int val,val2; @@ -661,33 +660,30 @@ alsapcm_info(alsapcm_t *self, PyObject *args) } printf("PCM handle name = '%s'\n", snd_pcm_name(self->handle)); - - - pname=PyUnicode_FromString("name"); + value=PyUnicode_FromString(snd_pcm_name(self->handle)); - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info,"name",value); + Py_DECREF(value); - pname=PyUnicode_FromString("state"); value=PyUnicode_FromString(snd_pcm_state_name(snd_pcm_state(self->handle))); - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info,"state",value); + Py_DECREF(value); - pname=PyUnicode_FromString("access_type"); snd_pcm_hw_params_get_access(hwparams, (snd_pcm_access_t *) &val); value=PyUnicode_FromString(snd_pcm_access_name((snd_pcm_access_t)val)); - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info,"access_type",value); + Py_DECREF(value); - pname=PyUnicode_FromString(" (call value) type"); value = PyLong_FromUnsignedLong((unsigned long) self->pcmtype); - PyDict_SetItem(info,pname,value); - pname=PyUnicode_FromString(" (call value) type_name"); + PyDict_SetItemString(info," (call value) type",value); + Py_DECREF(value); value=PyUnicode_FromString(snd_pcm_stream_name((snd_pcm_stream_t) self->pcmtype)); - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info," (call value) type_name",value); + Py_DECREF(value); - - pname=PyUnicode_FromString(" (call value) mode"); value = PyLong_FromUnsignedLong((unsigned long) self->pcmmode); - PyDict_SetItem(info,pname,value); - pname=PyUnicode_FromString(" (call value) mode_name"); + PyDict_SetItemString(info," (call value) mode",value); + Py_DECREF(value); switch(self->pcmmode){ case 0: value = PyUnicode_FromString("PCM_NORMAL"); @@ -699,125 +695,124 @@ alsapcm_info(alsapcm_t *self, PyObject *args) value = PyUnicode_FromString("PCM_ASYNC"); break; } - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info," (call value) mode_name",value); + Py_DECREF(value); snd_pcm_hw_params_get_format(hwparams, &fmt); - pname=PyUnicode_FromString("format"); value=PyLong_FromUnsignedLong((unsigned long)fmt); - PyDict_SetItem(info,pname,value); - pname=PyUnicode_FromString("format_name"); + PyDict_SetItemString(info,"format",value); + Py_DECREF(value); value=PyUnicode_FromString(snd_pcm_format_name(fmt)); - PyDict_SetItem(info,pname,value); - pname=PyUnicode_FromString("format_description"); + PyDict_SetItemString(info,"format_name",value); + Py_DECREF(value); value=PyUnicode_FromString(snd_pcm_format_description(fmt)); - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info,"format_description",value); + Py_DECREF(value); snd_pcm_hw_params_get_subformat(hwparams, (snd_pcm_subformat_t *)&val); - pname=PyUnicode_FromString("subformat_name"); value=PyUnicode_FromString(snd_pcm_subformat_name((snd_pcm_subformat_t)val)); - PyDict_SetItem(info,pname,value); - pname=PyUnicode_FromString("subformat_description"); + PyDict_SetItemString(info,"subformat_name",value); + Py_DECREF(value); value=PyUnicode_FromString(snd_pcm_subformat_description((snd_pcm_subformat_t)val)); - PyDict_SetItem(info,pname,value); + PyDict_SetItemString(info,"subformat_description",value); + Py_DECREF(value); - pname=PyUnicode_FromString("channels"); snd_pcm_hw_params_get_channels(hwparams, &val); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"channels", value); + Py_DECREF(value); - pname=PyUnicode_FromString("rate"); snd_pcm_hw_params_get_rate(hwparams, &val, &dir); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"rate", value); + Py_DECREF(value); - pname=PyUnicode_FromString("period_time"); snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"period_time", value); + Py_DECREF(value); - pname=PyUnicode_FromString("period_size"); snd_pcm_hw_params_get_period_size(hwparams, &frames, &dir); value=PyLong_FromUnsignedLong((unsigned long) frames); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"period_size", value); + Py_DECREF(value); - pname=PyUnicode_FromString("buffer_time"); snd_pcm_hw_params_get_buffer_time(hwparams, &val, &dir); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"buffer_time", value); + Py_DECREF(value); - pname=PyUnicode_FromString("buffer_size"); snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t *) &val); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"buffer_size", value); + Py_DECREF(value); - pname=PyUnicode_FromString("get_periods"); snd_pcm_hw_params_get_periods(hwparams, &val, &dir); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"get_periods", value); + Py_DECREF(value); - pname=PyUnicode_FromString("rate_numden"); snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2); value=PyTuple_Pack(2,PyLong_FromUnsignedLong((unsigned long) val) \ ,PyLong_FromUnsignedLong((unsigned long) val2)); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"rate_numden", value); + Py_DECREF(value); - pname=PyUnicode_FromString("significant_bits"); val = snd_pcm_hw_params_get_sbits(hwparams); value=PyLong_FromUnsignedLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"significant_bits", value); + Py_DECREF(value); - pname=PyUnicode_FromString("is_batch"); val = snd_pcm_hw_params_is_batch(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"is_batch", value); + Py_DECREF(value); - pname=PyUnicode_FromString("is_block_transfer"); val = snd_pcm_hw_params_is_block_transfer(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"is_block_transfer", value); + Py_DECREF(value); - pname=PyUnicode_FromString("is_double"); val = snd_pcm_hw_params_is_double(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"is_double", value); + Py_DECREF(value); - pname=PyUnicode_FromString("is_half_duplex"); val = snd_pcm_hw_params_is_half_duplex(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"is_half_duplex", value); + Py_DECREF(value); - pname=PyUnicode_FromString("is_joint_duplex"); val = snd_pcm_hw_params_is_joint_duplex(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"is_joint_duplex", value); + Py_DECREF(value); - pname=PyUnicode_FromString("can_overrange"); val = snd_pcm_hw_params_can_overrange(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"can_overrange", value); + Py_DECREF(value); - pname=PyUnicode_FromString("can_mmap_sample_resolution"); val = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"can_mmap_sample_resolution", value); + Py_DECREF(value); - pname=PyUnicode_FromString("can_pause"); val = snd_pcm_hw_params_can_pause(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"can_pause", value); + Py_DECREF(value); - - pname=PyUnicode_FromString("can_resume"); val = snd_pcm_hw_params_can_resume(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"can_resume", value); + Py_DECREF(value); - - pname=PyUnicode_FromString("can_sync_start"); val = snd_pcm_hw_params_can_sync_start(hwparams); value=PyBool_FromLong((unsigned long) val); - PyDict_SetItem(info,pname, value); + PyDict_SetItemString(info,"can_sync_start", value); + Py_DECREF(value); return info; } From 97f2abcb30404b31e8c882440d6481260530149a Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Fri, 2 Apr 2021 13:02:45 +0200 Subject: [PATCH 4/5] Remove debugging print statement. (cherry picked from commit dcc43f3da7bf4d083cc6cab18ae464261fadc53f) --- alsaaudio.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/alsaaudio.c b/alsaaudio.c index 2f79af0..82f4651 100644 --- a/alsaaudio.c +++ b/alsaaudio.c @@ -659,8 +659,6 @@ alsapcm_info(alsapcm_t *self, PyObject *args) return NULL; } - printf("PCM handle name = '%s'\n", snd_pcm_name(self->handle)); - value=PyUnicode_FromString(snd_pcm_name(self->handle)); PyDict_SetItemString(info,"name",value); Py_DECREF(value); From e6a64453757f613685289a8b20dc34cf946bfb03 Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Fri, 2 Apr 2021 13:15:56 +0200 Subject: [PATCH 5/5] Move creation of dictionary to a point after error handling, when it is relatively certain that the function will succeed. (cherry picked from commit 1820716a4bc018bb903b95bcf5d7cf83a5ebda9c) --- alsaaudio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/alsaaudio.c b/alsaaudio.c index 82f4651..18dd8f8 100644 --- a/alsaaudio.c +++ b/alsaaudio.c @@ -640,7 +640,7 @@ alsapcm_dumpinfo(alsapcm_t *self, PyObject *args) static PyObject * alsapcm_info(alsapcm_t *self, PyObject *args) { - PyObject *info = PyDict_New(); + PyObject *info; PyObject *value; unsigned int val,val2; @@ -659,6 +659,8 @@ alsapcm_info(alsapcm_t *self, PyObject *args) return NULL; } + info = PyDict_New(); + value=PyUnicode_FromString(snd_pcm_name(self->handle)); PyDict_SetItemString(info,"name",value); Py_DECREF(value);