aboutsummaryrefslogtreecommitdiff
path: root/alsa.c
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2014-09-12 23:09:43 +0000
committerDimitri Sokolyuk <demon@dim13.org>2014-09-12 23:09:43 +0000
commit11de1f857ce719a9daca77f59382f4e65fee5546 (patch)
treeb67600894a045e2f9819f0646a81d0ae7ad7552d /alsa.c
parent78b27c6c0394d84e71c5ecc22f3c6fec9d731694 (diff)
sync with HEAD
Diffstat (limited to 'alsa.c')
-rw-r--r--alsa.c92
1 files changed, 47 insertions, 45 deletions
diff --git a/alsa.c b/alsa.c
index e1f0208..cf99349 100644
--- a/alsa.c
+++ b/alsa.c
@@ -26,86 +26,88 @@
#define RATE 48000
#define FPS 25
-struct sio {
- snd_pcm_t *handle;
- snd_pcm_hw_params_t *params;
- int16_t *buffer;
- unsigned int samples;
+static snd_pcm_t *hdl;
+static snd_pcm_hw_params_t *par;
+static int16_t *buffer;
+static unsigned int samples;
+
+struct data {
+ int16_t left;
+ int16_t right;
};
-struct sio *
+int
init_sio(void)
{
- struct sio *sio;
snd_pcm_uframes_t round;
unsigned int rate;
int rc;
- sio = malloc(sizeof(struct sio));
- assert(sio);
-
- rc = snd_pcm_open(&sio->handle, "default", SND_PCM_STREAM_CAPTURE, 0);
+ rc = snd_pcm_open(&hdl, "default", SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0)
errx(1, "unable to open pcm device: %s", snd_strerror(rc));
- snd_pcm_hw_params_malloc(&sio->params);
- snd_pcm_hw_params_any(sio->handle, sio->params);
- snd_pcm_hw_params_set_access(sio->handle, sio->params,
+ snd_pcm_hw_params_malloc(&par);
+ snd_pcm_hw_params_any(hdl, par);
+ snd_pcm_hw_params_set_access(hdl, par,
SND_PCM_ACCESS_RW_INTERLEAVED);
- snd_pcm_hw_params_set_format(sio->handle, sio->params,
+ snd_pcm_hw_params_set_format(hdl, par,
SND_PCM_FORMAT_S16_LE);
- snd_pcm_hw_params_set_channels(sio->handle, sio->params, STEREO);
- snd_pcm_hw_params_set_rate(sio->handle, sio->params, RATE, 0);
+ snd_pcm_hw_params_set_channels(hdl, par, STEREO);
+ snd_pcm_hw_params_set_rate(hdl, par, RATE, 0);
- rc = snd_pcm_hw_params(sio->handle, sio->params);
+ rc = snd_pcm_hw_params(hdl, par);
if (rc < 0)
errx(1, "unable to set hw parameters: %s", snd_strerror(rc));
- snd_pcm_hw_params_get_period_size(sio->params, &round, NULL);
- snd_pcm_hw_params_get_rate(sio->params, &rate, 0);
- snd_pcm_hw_params_free(sio->params);
- snd_pcm_prepare(sio->handle);
-
- sio->samples = rate / FPS;
- warnx("min samples: %d", sio->samples);
- sio->samples -= sio->samples % round - round;
- warnx("max samples: %d", sio->samples);
- sio->buffer = calloc(sio->samples * STEREO, sizeof(int16_t));
- assert(sio->buffer);
+ snd_pcm_hw_params_get_period_size(par, &round, NULL);
+ snd_pcm_hw_params_get_rate(par, &rate, 0);
+ snd_pcm_hw_params_free(par);
+ snd_pcm_prepare(hdl);
+ samples = rate / FPS;
+ samples -= samples % round - round;
+ buffer = calloc(samples * STEREO, sizeof(int16_t));
+ assert(buffer);
- return sio;
+ return 0;
}
unsigned int
-max_samples_sio(struct sio *sio)
+max_samples_sio(void)
{
- return sio->samples;
+ return samples;
}
-int16_t *
-read_sio(struct sio *sio, unsigned int n)
+void
+read_sio(double *left, double *right, size_t n)
{
snd_pcm_sframes_t rc;
+ struct data *data;
+ int i;
- if (n > sio->samples)
- n = sio->samples;
+ if (n > samples)
+ n = samples;
- rc = snd_pcm_readi(sio->handle, sio->buffer, sio->samples);
- if (rc != sio->samples) {
+ rc = snd_pcm_readi(hdl, buffer, samples);
+ if (rc != samples) {
warnx("audio read error: %s", snd_strerror(rc));
if (rc == -EPIPE)
- snd_pcm_prepare(sio->handle);
+ snd_pcm_prepare(hdl);
}
- return sio->buffer + sio->samples - n;
+ data = (struct data *)&buffer[samples - n];
+
+ for (i = 0; i < n; i++) {
+ left[i] = data[i].left;
+ right[i] = data[i].right;
+ }
}
void
-free_sio(struct sio *sio)
+free_sio(void)
{
- snd_pcm_drain(sio->handle);
- snd_pcm_close(sio->handle);
- free(sio->buffer);
- free(sio);
+ snd_pcm_drain(hdl);
+ snd_pcm_close(hdl);
+ free(buffer);
}