forked from auracaster/pyalsaaudio
Merge pull request #100 from soundappraisal/feature_timestamp_mode_and_type
Feature timestamp mode and type
This commit is contained in:
+4
-1
@@ -8,4 +8,7 @@ doc/_build/
|
||||
gh-pages/
|
||||
build/
|
||||
dist/
|
||||
.vscode/
|
||||
.vscode/
|
||||
/__pycache__/
|
||||
/pyalsaaudio.egg-info/
|
||||
*.raw
|
||||
|
||||
+193
-4
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user