mirror of
https://github.com/larsimmisch/pyalsaaudio.git
synced 2026-04-22 10:24:49 +00:00
make period count configurable
the period count is just as important for playback latency as the period size, so it makes no sense to have only one of them configurable. as a drive-by, fix up the handling of periods in info() & dumpinfo().
This commit is contained in:
20
alsaaudio.c
20
alsaaudio.c
@@ -110,6 +110,7 @@ typedef struct {
|
|||||||
unsigned int channels;
|
unsigned int channels;
|
||||||
unsigned int rate;
|
unsigned int rate;
|
||||||
snd_pcm_format_t format;
|
snd_pcm_format_t format;
|
||||||
|
unsigned int periods;
|
||||||
snd_pcm_uframes_t periodsize;
|
snd_pcm_uframes_t periodsize;
|
||||||
int framesize;
|
int framesize;
|
||||||
|
|
||||||
@@ -384,11 +385,10 @@ static int alsapcm_setup(alsapcm_t *self)
|
|||||||
self->channels);
|
self->channels);
|
||||||
|
|
||||||
dir = 0;
|
dir = 0;
|
||||||
unsigned int periods = 4;
|
|
||||||
snd_pcm_hw_params_set_rate_near(self->handle, hwparams, &self->rate, &dir);
|
snd_pcm_hw_params_set_rate_near(self->handle, hwparams, &self->rate, &dir);
|
||||||
snd_pcm_hw_params_set_period_size_near(self->handle, hwparams,
|
snd_pcm_hw_params_set_period_size_near(self->handle, hwparams,
|
||||||
&self->periodsize, &dir);
|
&self->periodsize, &dir);
|
||||||
snd_pcm_hw_params_set_periods_near(self->handle, hwparams, &periods, &dir);
|
snd_pcm_hw_params_set_periods_near(self->handle, hwparams, &self->periods, &dir);
|
||||||
|
|
||||||
/* Write it to the device */
|
/* Write it to the device */
|
||||||
res = snd_pcm_hw_params(self->handle, hwparams);
|
res = snd_pcm_hw_params(self->handle, hwparams);
|
||||||
@@ -401,6 +401,7 @@ static int alsapcm_setup(alsapcm_t *self)
|
|||||||
snd_pcm_hw_params_get_channels(hwparams, &self->channels);
|
snd_pcm_hw_params_get_channels(hwparams, &self->channels);
|
||||||
snd_pcm_hw_params_get_rate(hwparams, &self->rate, &dir);
|
snd_pcm_hw_params_get_rate(hwparams, &self->rate, &dir);
|
||||||
snd_pcm_hw_params_get_period_size(hwparams, &self->periodsize, &dir);
|
snd_pcm_hw_params_get_period_size(hwparams, &self->periodsize, &dir);
|
||||||
|
snd_pcm_hw_params_get_periods(hwparams, &self->periods, &dir);
|
||||||
|
|
||||||
self->framesize = self->channels * snd_pcm_hw_params_get_sbits(hwparams)/8;
|
self->framesize = self->channels * snd_pcm_hw_params_get_sbits(hwparams)/8;
|
||||||
|
|
||||||
@@ -422,13 +423,15 @@ alsapcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
int rate = 44100;
|
int rate = 44100;
|
||||||
int channels = 2;
|
int channels = 2;
|
||||||
int format = SND_PCM_FORMAT_S16_LE;
|
int format = SND_PCM_FORMAT_S16_LE;
|
||||||
|
int periods = 4;
|
||||||
int periodsize = 32;
|
int periodsize = 32;
|
||||||
|
|
||||||
char *kw[] = { "type", "mode", "device", "cardindex", "card", "rate", "channels", "format", "periodsize", NULL };
|
char *kw[] = { "type", "mode", "device", "cardindex", "card",
|
||||||
|
"rate", "channels", "format", "periodsize", "periods", NULL };
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oisiziiii", kw,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oisiziiiii", kw,
|
||||||
&pcmtypeobj, &pcmmode, &device,
|
&pcmtypeobj, &pcmmode, &device, &cardidx, &card,
|
||||||
&cardidx, &card, &rate, &channels, &format, &periodsize))
|
&rate, &channels, &format, &periodsize, &periods))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (cardidx >= 0) {
|
if (cardidx >= 0) {
|
||||||
@@ -475,6 +478,7 @@ alsapcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
self->channels = channels;
|
self->channels = channels;
|
||||||
self->rate = rate;
|
self->rate = rate;
|
||||||
self->format = format;
|
self->format = format;
|
||||||
|
self->periods = periods;
|
||||||
self->periodsize = periodsize;
|
self->periodsize = periodsize;
|
||||||
|
|
||||||
res = snd_pcm_open(&(self->handle), device, self->pcmtype,
|
res = snd_pcm_open(&(self->handle), device, self->pcmtype,
|
||||||
@@ -586,7 +590,7 @@ alsapcm_dumpinfo(alsapcm_t *self, PyObject *args)
|
|||||||
printf("buffer size = %d frames\n", (int)frames);
|
printf("buffer size = %d frames\n", (int)frames);
|
||||||
|
|
||||||
snd_pcm_hw_params_get_periods(hwparams, &val, &dir);
|
snd_pcm_hw_params_get_periods(hwparams, &val, &dir);
|
||||||
printf("periods per buffer = %d frames\n", val);
|
printf("periods per buffer = %d\n", val);
|
||||||
|
|
||||||
snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2);
|
snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2);
|
||||||
printf("exact rate = %d/%d bps\n", val, val2);
|
printf("exact rate = %d/%d bps\n", val, val2);
|
||||||
@@ -760,7 +764,7 @@ alsapcm_info(alsapcm_t *self, PyObject *args)
|
|||||||
|
|
||||||
snd_pcm_hw_params_get_periods(hwparams, &val, &dir);
|
snd_pcm_hw_params_get_periods(hwparams, &val, &dir);
|
||||||
value=PyLong_FromUnsignedLong((unsigned long) val);
|
value=PyLong_FromUnsignedLong((unsigned long) val);
|
||||||
PyDict_SetItemString(info,"get_periods", value);
|
PyDict_SetItemString(info,"periods", value);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
|
|
||||||
snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2);
|
snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ PCM objects in :mod:`alsaaudio` can play or capture (record) PCM
|
|||||||
sound through speakers or a microphone. The PCM constructor takes the
|
sound through speakers or a microphone. The PCM constructor takes the
|
||||||
following arguments:
|
following arguments:
|
||||||
|
|
||||||
.. class:: PCM(type=PCM_PLAYBACK, mode=PCM_NORMAL, rate=44100, channels=2, format=PCM_FORMAT_S16_LE, periodsize=32, device='default', cardindex=-1)
|
.. class:: PCM(type=PCM_PLAYBACK, mode=PCM_NORMAL, rate=44100, channels=2, format=PCM_FORMAT_S16_LE, periodsize=32, periods=4, device='default', cardindex=-1)
|
||||||
|
|
||||||
This class is used to represent a PCM device (either for playback and
|
This class is used to represent a PCM device (either for playback and
|
||||||
recording). The arguments are:
|
recording). The arguments are:
|
||||||
@@ -146,6 +146,7 @@ following arguments:
|
|||||||
Make sure you understand :ref:`the meaning of periods <term-period>`.
|
Make sure you understand :ref:`the meaning of periods <term-period>`.
|
||||||
The default value is 32, which is below the actual minimum of most devices,
|
The default value is 32, which is below the actual minimum of most devices,
|
||||||
and will therefore likely be larger in practice.
|
and will therefore likely be larger in practice.
|
||||||
|
* *periods* - the number of periods in the buffer. The default value is 4.
|
||||||
* *device* - the name of the PCM device that should be used (for example
|
* *device* - the name of the PCM device that should be used (for example
|
||||||
a value from the output of :func:`pcms`). The default value is
|
a value from the output of :func:`pcms`). The default value is
|
||||||
``'default'``.
|
``'default'``.
|
||||||
@@ -158,6 +159,10 @@ following arguments:
|
|||||||
|
|
||||||
This will construct a PCM object with the given settings.
|
This will construct a PCM object with the given settings.
|
||||||
|
|
||||||
|
*Changed in 0.10:*
|
||||||
|
|
||||||
|
- Added the optional named parameter `periods`.
|
||||||
|
|
||||||
*Changed in 0.9:*
|
*Changed in 0.9:*
|
||||||
|
|
||||||
- Added the optional named parameters `rate`, `channels`, `format` and `periodsize`.
|
- Added the optional named parameters `rate`, `channels`, `format` and `periodsize`.
|
||||||
|
|||||||
Reference in New Issue
Block a user