Compare commits

...

2 Commits

Author SHA1 Message Date
Pbopbo
b3d11582e0 Adds read_sw function to be able to read any size of frames. 2026-04-02 17:27:53 +02:00
Lars Immisch
2a2fa8f742 Update local build instructions wherever setup.py is greppable. 2025-12-10 23:05:14 +01:00
4 changed files with 120 additions and 30 deletions

View File

@@ -46,14 +46,9 @@ First, get the sources and change to the source directory:
$ cd pyalsaaudio
```
Then, build:
Then, build and install:
```
$ python setup.py build
```
And install:
```
$ sudo python setup.py install
$ pip install .
```
# Using the API

View File

@@ -1,28 +1,18 @@
# Make a new release
Update the version in setup.py
Create and push a tag naming the version (i.e. 0.11.1):
pyalsa_version = '0.9.0'
git tag 0.11.1
git push origin 0.11.1
Commit and push the update.
Create and push a tag naming the version (i.e. 0.9.0):
git tag 0.9.0
git push origin 0.9.0
Create the package:
python3 setup.py sdist
Upload the package
twine upload dist/*
Don't forget to update the documentation.
This should trigger a build via a github actions and publish pre-built binaries to pypi.org
# Publish the documentation
All commits to main should trigger a rebuild of the documentation.
## Historical background
The documentation is published through the `gh-pages` branch.
To publish the documentation, you need to clone the `gh-pages` branch of this repository into

View File

@@ -86,11 +86,7 @@ ship with ALSA kernels.
To install, execute the following: --- ::
$ python setup.py build
And then as root: --- ::
# python setup.py install
$ pip install .
*******

View File

@@ -1448,6 +1448,114 @@ alsapcm_read(alsapcm_t *self, PyObject *args)
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)
{
int datalen;
@@ -1767,6 +1875,7 @@ static PyMethodDef alsapcm_methods[] = {
{"getratebounds", (PyCFunction)alsapcm_getratemaxmin, METH_VARARGS},
{"getrates", (PyCFunction)alsapcm_getrates, METH_VARARGS},
{"read", (PyCFunction)alsapcm_read, METH_VARARGS},
{"read_sw", (PyCFunction)alsapcm_read_sw, METH_VARARGS},
{"write", (PyCFunction)alsapcm_write, METH_VARARGS},
{"avail", (PyCFunction)alsapcm_avail, METH_VARARGS},
{"pause", (PyCFunction)alsapcm_pause, METH_VARARGS},