forked from auracaster/pyalsaaudio
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8bcf03f288 |
@@ -57,8 +57,8 @@ distribution; it is also online on [http://larsimmisch.github.io/pyalsaaudio/](h
|
|||||||
|
|
||||||
There are some example programs included with the source:
|
There are some example programs included with the source:
|
||||||
|
|
||||||
* [playwav.py](https://github.com/larsimmisch/pyalsaaudio/blob/master/playwav.py) plays back a wav file
|
* [playwav.py](./examples/playwav.py) plays back a wav file
|
||||||
* [playbacktest.py](https://github.com/larsimmisch/pyalsaaudio/blob/master/playbacktest.py) plays back raw sound data read from stdin
|
* [playbacktest.py](./examples/playbacktest.py) plays back raw sound data read from stdin
|
||||||
* [recordtest.py](https://github.com/larsimmisch/pyalsaaudio/blob/master/recordtest.py) captures sound from the microphone and writes
|
* [recordtest.py](./examples/recordtest.py) captures sound from the microphone and writes
|
||||||
it raw to stdout.
|
it raw to stdout.
|
||||||
* [mixertest.py](https://github.com/larsimmisch/pyalsaaudio/blob/master/mixertest.py) can be used to manipulate the mixers.
|
* [mixertest.py](./examples/mixertest.py) can be used to manipulate the mixers.
|
||||||
|
|||||||
-109
@@ -1448,114 +1448,6 @@ alsapcm_read(alsapcm_t *self, PyObject *args)
|
|||||||
return tuple_obj;
|
return tuple_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
alsapcm_read_sw(alsapcm_t *self, PyObject *args)
|
|
||||||
{
|
|
||||||
snd_pcm_state_t state;
|
|
||||||
int res;
|
|
||||||
int max_frames_to_read;
|
|
||||||
int size;
|
|
||||||
int sizeout = 0;
|
|
||||||
PyObject *buffer_obj, *tuple_obj, *res_obj;
|
|
||||||
char *buffer;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args,"i:read_sw", &max_frames_to_read))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!self->handle) {
|
|
||||||
PyErr_SetString(ALSAAudioError, "PCM device is closed");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->pcmtype != SND_PCM_STREAM_CAPTURE)
|
|
||||||
{
|
|
||||||
PyErr_Format(ALSAAudioError, "Cannot read from playback PCM [%s]",
|
|
||||||
self->cardname);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = self->framesize * max_frames_to_read;
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
buffer_obj = PyString_FromStringAndSize(NULL, size);
|
|
||||||
if (!buffer_obj)
|
|
||||||
return NULL;
|
|
||||||
buffer = PyString_AS_STRING(buffer_obj);
|
|
||||||
#else
|
|
||||||
buffer_obj = PyBytes_FromStringAndSize(NULL, size);
|
|
||||||
if (!buffer_obj)
|
|
||||||
return NULL;
|
|
||||||
buffer = PyBytes_AS_STRING(buffer_obj);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// After drop() and drain(), we need to prepare the stream again.
|
|
||||||
// Note that fresh streams are already prepared by snd_pcm_hw_params().
|
|
||||||
state = snd_pcm_state(self->handle);
|
|
||||||
if ((state != SND_PCM_STATE_SETUP) ||
|
|
||||||
!(res = snd_pcm_prepare(self->handle))) {
|
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
res = snd_pcm_readi(self->handle, buffer, max_frames_to_read);
|
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
|
|
||||||
if (res == -EPIPE) {
|
|
||||||
// This means buffer overrun, which we need to report.
|
|
||||||
// However, we recover the stream, so the next PCM.read() will work
|
|
||||||
// again. If recovery fails (very unlikely), report that instead.
|
|
||||||
if (!(res = snd_pcm_prepare(self->handle)))
|
|
||||||
res = -EPIPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != -EPIPE)
|
|
||||||
{
|
|
||||||
if (res == -EAGAIN)
|
|
||||||
{
|
|
||||||
res = 0;
|
|
||||||
}
|
|
||||||
else if (res < 0) {
|
|
||||||
PyErr_Format(ALSAAudioError, "%s [%s]", snd_strerror(res),
|
|
||||||
self->cardname);
|
|
||||||
|
|
||||||
Py_DECREF(buffer_obj);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sizeout = res * self->framesize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != sizeout) {
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
/* If the following fails, it will free the object */
|
|
||||||
if (_PyString_Resize(&buffer_obj, sizeout))
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
/* If the following fails, it will free the object */
|
|
||||||
if (_PyBytes_Resize(&buffer_obj, sizeout))
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
res_obj = PyLong_FromLong(res);
|
|
||||||
if (!res_obj) {
|
|
||||||
Py_DECREF(buffer_obj);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
tuple_obj = PyTuple_New(2);
|
|
||||||
if (!tuple_obj) {
|
|
||||||
Py_DECREF(buffer_obj);
|
|
||||||
Py_DECREF(res_obj);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* Steal reference counts */
|
|
||||||
PyTuple_SET_ITEM(tuple_obj, 0, res_obj);
|
|
||||||
PyTuple_SET_ITEM(tuple_obj, 1, buffer_obj);
|
|
||||||
|
|
||||||
return tuple_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *alsapcm_write(alsapcm_t *self, PyObject *args)
|
static PyObject *alsapcm_write(alsapcm_t *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int datalen;
|
int datalen;
|
||||||
@@ -1875,7 +1767,6 @@ static PyMethodDef alsapcm_methods[] = {
|
|||||||
{"getratebounds", (PyCFunction)alsapcm_getratemaxmin, METH_VARARGS},
|
{"getratebounds", (PyCFunction)alsapcm_getratemaxmin, METH_VARARGS},
|
||||||
{"getrates", (PyCFunction)alsapcm_getrates, METH_VARARGS},
|
{"getrates", (PyCFunction)alsapcm_getrates, METH_VARARGS},
|
||||||
{"read", (PyCFunction)alsapcm_read, METH_VARARGS},
|
{"read", (PyCFunction)alsapcm_read, METH_VARARGS},
|
||||||
{"read_sw", (PyCFunction)alsapcm_read_sw, METH_VARARGS},
|
|
||||||
{"write", (PyCFunction)alsapcm_write, METH_VARARGS},
|
{"write", (PyCFunction)alsapcm_write, METH_VARARGS},
|
||||||
{"avail", (PyCFunction)alsapcm_avail, METH_VARARGS},
|
{"avail", (PyCFunction)alsapcm_avail, METH_VARARGS},
|
||||||
{"pause", (PyCFunction)alsapcm_pause, METH_VARARGS},
|
{"pause", (PyCFunction)alsapcm_pause, METH_VARARGS},
|
||||||
|
|||||||
Reference in New Issue
Block a user