Merge pull request #100 from soundappraisal/feature_timestamp_mode_and_type

Feature timestamp mode and type
This commit is contained in:
Lars Immisch
2021-04-12 12:30:23 +02:00
committed by GitHub
4 changed files with 251 additions and 6 deletions
+4 -1
View File
@@ -8,4 +8,7 @@ doc/_build/
gh-pages/
build/
dist/
.vscode/
.vscode/
/__pycache__/
/pyalsaaudio.egg-info/
*.raw
+193 -4
View File
@@ -651,7 +651,7 @@ alsapcm_info(alsapcm_t *self, PyObject *args)
snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_hw_params_current(self->handle,hwparams);
if (!PyArg_ParseTuple(args,":dumpinfo"))
if (!PyArg_ParseTuple(args,":info"))
return NULL;
if (!self->handle) {
@@ -827,6 +827,21 @@ they represent values stored by pyalsaaudio and they are prefixed with ' (call v
");
static PyObject *
alsa_asoundlib_version(PyObject * module, PyObject *args)
{
if (!PyArg_ParseTuple(args,":asoundlib_version"))
return NULL;
return PyUnicode_FromString(snd_asoundlib_version());
}
PyDoc_STRVAR(asoundlib_version_doc,
"asoundlib_version() -> string\n\
\n\
Returns ALSA version string. \n\
");
static PyObject *
alsapcm_htimestamp(alsapcm_t *self, PyObject *args)
{
@@ -845,13 +860,167 @@ alsapcm_htimestamp(alsapcm_t *self, PyObject *args)
}
PyDoc_STRVAR(pcm_htimestamp_doc,
PyDoc_STRVAR(htimestamp_doc,
"htimestamp() -> tuple\n\
\n\
Returns a tuple containing the seconds since epoch in the first element \n\
, nanoseconds in the second element, and number of frames available in \n\
the buffer at the time of the time stamp. \n");
static PyObject *
alsapcm_set_tstamp_mode(alsapcm_t *self, PyObject *args)
{
snd_pcm_tstamp_t mode = SND_PCM_TSTAMP_ENABLE;
int err;
if (!PyArg_ParseTuple(args,"|i:set_tstamp_mode", &mode))
return NULL;
if (!self->handle)
{
PyErr_SetString(ALSAAudioError, "PCM device is closed");
return NULL;
}
snd_pcm_sw_params_t* swParams;
snd_pcm_sw_params_alloca( &swParams);
snd_pcm_sw_params_current(self->handle, swParams);
snd_pcm_sw_params_set_tstamp_mode(self->handle, swParams, mode);
err = snd_pcm_sw_params(self->handle, swParams);
if (err < 0) {
PyErr_SetString(PyExc_RuntimeError, "Unable to set pcm tstamp mode!");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
PyDoc_STRVAR(set_tstamp_mode_doc,
"set_tstamp_mode() -> None\n\
\n\
Set the timestamp mode of the device. \n");
static PyObject *
alsapcm_get_tstamp_mode(alsapcm_t *self, PyObject *args)
{
snd_pcm_tstamp_t mode;
int err;
if (!PyArg_ParseTuple(args,":get_tstamp_mode"))
return NULL;
if (!self->handle)
{
PyErr_SetString(ALSAAudioError, "PCM device is closed");
return NULL;
}
snd_pcm_sw_params_t* swParams;
snd_pcm_sw_params_alloca( &swParams);
snd_pcm_sw_params_current(self->handle, swParams);
err = snd_pcm_sw_params_get_tstamp_mode(swParams, &mode);
if (err < 0) {
PyErr_SetString(PyExc_RuntimeError, "Unable to get pcm tstamp mode!");
return NULL;
}
return PyLong_FromUnsignedLong((unsigned long) mode);
}
PyDoc_STRVAR(get_tstamp_mode_doc,
"get_tstamp_mode() -> integer \n\
\n\
Get the timestamp mode of the device. \n");
static PyObject *
alsapcm_set_tstamp_type(alsapcm_t *self, PyObject *args)
{
snd_pcm_tstamp_type_t type = SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
int err;
if (!PyArg_ParseTuple(args,"|i:set_tstamp_type", &type))
return NULL;
if (!self->handle)
{
PyErr_SetString(ALSAAudioError, "PCM device is closed");
return NULL;
}
snd_pcm_sw_params_t* swParams;
snd_pcm_sw_params_alloca( &swParams);
snd_pcm_sw_params_current(self->handle, swParams);
snd_pcm_sw_params_set_tstamp_type(self->handle, swParams, type);
err = snd_pcm_sw_params(self->handle, swParams);
if (err < 0) {
PyErr_SetString(PyExc_RuntimeError, "Unable to set pcm tstamp type!");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
PyDoc_STRVAR(set_tstamp_type_doc,
"set_tstamp_type() -> None\n\
\n\
Set the timestamp type of the device. \n");
static PyObject *
alsapcm_get_tstamp_type(alsapcm_t *self, PyObject *args)
{
snd_pcm_tstamp_type_t type;
int err;
if (!PyArg_ParseTuple(args,":get_tstamp_type"))
return NULL;
if (!self->handle)
{
PyErr_SetString(ALSAAudioError, "PCM device is closed");
return NULL;
}
snd_pcm_sw_params_t* swParams;
snd_pcm_sw_params_alloca( &swParams);
snd_pcm_sw_params_current(self->handle, swParams);
err = snd_pcm_sw_params_get_tstamp_type(swParams, &type);
if (err < 0) {
PyErr_SetString(PyExc_RuntimeError, "Unable to get pcm tstamp type!");
return NULL;
}
return PyLong_FromUnsignedLong((unsigned long) type);
}
PyDoc_STRVAR(get_tstamp_type_doc,
"get_tstamp_type() -> int \n\
\n\
Get the timestamp type of the device. \n");
// auxiliary function
@@ -1588,8 +1757,11 @@ static PyMethodDef alsapcm_methods[] = {
{"setformat", (PyCFunction)alsapcm_setformat, METH_VARARGS, setformat_doc},
{"setperiodsize", (PyCFunction)alsapcm_setperiodsize, METH_VARARGS,
setperiodsize_doc},
{"htimestamp", (PyCFunction) alsapcm_htimestamp, METH_VARARGS,
pcm_htimestamp_doc},
{"htimestamp", (PyCFunction) alsapcm_htimestamp, METH_VARARGS, htimestamp_doc},
{"set_tstamp_type", (PyCFunction) alsapcm_set_tstamp_type, METH_VARARGS, set_tstamp_type_doc},
{"set_tstamp_mode", (PyCFunction) alsapcm_set_tstamp_mode, METH_VARARGS, set_tstamp_mode_doc},
{"get_tstamp_type", (PyCFunction) alsapcm_get_tstamp_type, METH_VARARGS, get_tstamp_type_doc},
{"get_tstamp_mode", (PyCFunction) alsapcm_get_tstamp_mode, METH_VARARGS, get_tstamp_mode_doc},
{"dumpinfo", (PyCFunction)alsapcm_dumpinfo, METH_VARARGS},
{"info", (PyCFunction)alsapcm_info, METH_VARARGS, pcm_info_doc},
{"getformats", (PyCFunction)alsapcm_getformats, METH_VARARGS, getformats_doc},
@@ -1606,6 +1778,12 @@ static PyMethodDef alsapcm_methods[] = {
{NULL, NULL}
};
static PyMethodDef alsa_methods[] = {
{"asoundlib_version", (PyCFunction) alsa_asoundlib_version, METH_VARARGS, asoundlib_version_doc},
{NULL, NULL}
};
#if PY_VERSION_HEX < 0x02020000
static PyObject *
alsapcm_getattr(alsapcm_t *self, char *name) {
@@ -3033,6 +3211,8 @@ PyObject *PyInit_alsaaudio(void)
Py_INCREF(ALSAAudioError);
PyModule_AddObject(m, "ALSAAudioError", ALSAAudioError);
PyModule_AddFunctions(m, alsa_methods);
_EXPORT_INT(m, "PCM_PLAYBACK",SND_PCM_STREAM_PLAYBACK);
_EXPORT_INT(m, "PCM_CAPTURE",SND_PCM_STREAM_CAPTURE);
@@ -3069,6 +3249,15 @@ PyObject *PyInit_alsaaudio(void)
_EXPORT_INT(m, "PCM_FORMAT_U24_3LE",SND_PCM_FORMAT_U24_3LE);
_EXPORT_INT(m, "PCM_FORMAT_U24_3BE",SND_PCM_FORMAT_U24_3BE);
/* PCM tstamp modes */
_EXPORT_INT(m, "PCM_TSTAMP_NONE",SND_PCM_TSTAMP_NONE);
_EXPORT_INT(m, "PCM_TSTAMP_ENABLE",SND_PCM_TSTAMP_ENABLE);
/* PCM tstamp types */
_EXPORT_INT(m, "PCM_TSTAMP_TYPE_GETTIMEOFDAY",SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY);
_EXPORT_INT(m, "PCM_TSTAMP_TYPE_MONOTONIC",SND_PCM_TSTAMP_TYPE_MONOTONIC);
_EXPORT_INT(m, "PCM_TSTAMP_TYPE_MONOTONIC_RAW",SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW);
/* DSD sample formats are included in ALSA 1.0.29 and higher
* define OVERRIDE_DSD_COMPILE to include DSD sample support
* if you use a patched ALSA lib version
+53
View File
@@ -97,6 +97,9 @@ The :mod:`alsaaudio` module defines functions and classes for using ALSA.
changed. Since 0.8, this functions returns the mixers for the default
device, not the mixers for the first card.
.. function:: asoundlib_version()
Return a Python string containing the ALSA version found.
.. _pcm-objects:
@@ -260,6 +263,56 @@ PCM objects have the following methods:
The *eventmask* value is compatible with `poll.register`__ in the Python
:const:`select` module.
.. method:: PCM.set_tstamp_mode([mode=PCM_TSTAMP_ENABLE])
Set the ALSA timestamp mode on the device. The mode argument can be set to
either :const:`PCM_TSTAMP_NONE` or :const:`PCM_TSTAMP_ENABLE`.
.. method:: PCM.get_tstamp_mode()
Return the integer value corresponding to the ALSA timestamp mode. The
return value can be either :const:`PCM_TSTAMP_NONE` or :const:`PCM_TSTAMP_ENABLE`.
.. method:: PCM.set_tstamp_type([type=PCM_TSTAMP_TYPE_GETTIMEOFDAY])
Set the ALSA timestamp mode on the device. The type argument
can be set to either :const:`PCM_TSTAMP_TYPE_GETTIMEOFDAY`,
:const:`PCM_TSTAMP_TYPE_MONOTONIC` or :const:`PCM_TSTAMP_TYPE_MONOTONIC_RAW`.
.. method:: PCM.get_tstamp_type()
Return the integer value corresponding to the ALSA timestamp type. The
return value can be either :const:`PCM_TSTAMP_TYPE_GETTIMEOFDAY`,
:const:`PCM_TSTAMP_TYPE_MONOTONIC` or :const:`PCM_TSTAMP_TYPE_MONOTONIC_RAW`.
.. method:: PCM.htimestamp()
Return a Python tuple *(seconds, nanoseconds, frames_available_in_buffer)*.
The type of output is controlled by the tstamp_type, as described in the table below.
================================= ===========================================
Timestamp Type Description
================================= ===========================================
``PCM_TSTAMP_TYPE_GETTIMEOFDAY`` System-wide realtime clock with seconds
since epoch.
``PCM_TSTAMP_TYPE_MONOTONIC`` Monotonic time from an unspecified starting
time. Progress is NTP synchronized.
``PCM_TSTAMP_TYPE_MONOTONIC_RAW`` Monotonic time from an unspecified starting
time using only the system clock.
================================= ===========================================
The timestamp mode is controlled by the tstamp_mode, as described in the table below.
================================= ===========================================
Timestamp Mode Description
================================= ===========================================
``PCM_TSTAMP_NONE`` No timestamp.
``PCM_TSTAMP_ENABLE`` Update timestamp at every hardware position
update.
================================= ===========================================
__ poll_objects_
**A few hints on using PCM devices for playback**
+1 -1
View File
@@ -58,7 +58,7 @@ if __name__ == '__main__':
loops -= 1
# Read data from device
l, data = inp.read()
if l:
f.write(data)
time.sleep(.001)