commit - 34674849fb1efe5167c457f0dc98ee7fadcc8886
commit + bbd1402d8bfd350185dcc967306c4c72094c2c21
blob - 59128b71c8a1192389220edbb0178e4a416c51b9
blob + fe6c8acb9722c865545c5a6e0950f4ae2b0905b5
--- audio_alsa.c
+++ audio_alsa.c
#include "log.h"
static snd_pcm_t *pcm;
+static size_t bpf;
int
audio_open(void (*onmove_cb)(void *, int))
int err;
snd_pcm_format_t fmt;
- if (bits == 8)
+ if (bits == 8) {
fmt = SND_PCM_FORMAT_S8;
- else if (bits == 16)
+ bpf = 1;
+ } else if (bits == 16) {
fmt = SND_PCM_FORMAT_S16;
- else if (bits == 24)
+ bpf = 2;
+ } else if (bits == 24) {
fmt = SND_PCM_FORMAT_S24;
- else if (bits == 32)
+ bpf = 4;
+ } else if (bits == 32) {
fmt = SND_PCM_FORMAT_S32;
- else {
+ bpf = 4;
+ } else {
log_warnx("can't handle %d bits", bits);
return -1;
}
+
+ bpf *= channels;
err = snd_pcm_set_params(pcm, fmt, SND_PCM_ACCESS_RW_INTERLEAVED,
channels, rate, 1, 500000 /* 0.5s */);
size_t
audio_write(const void *buf, size_t len)
{
- snd_pcm_sframes_t ret;
+ snd_pcm_sframes_t avail, ret;
+ /*
+ * snd_pcm_writei works in terms of FRAMES, not BYTES!
+ */
+ len /= bpf;
+
+ avail = snd_pcm_avail_update(pcm);
+ if (avail < 0) {
+ if (avail == -EPIPE) {
+ log_warnx("alsa xrun occurred");
+ return 0;
+ }
+ log_warnx("snd_pcm_avail_update failure: %s",
+ snd_strerror(avail));
+ return 0;
+ }
+
+ if (len > avail)
+ len = avail;
+
ret = snd_pcm_writei(pcm, buf, len);
if (ret < 0) {
log_warnx("snd_pcm_writei failed: %s", snd_strerror(ret));
return 0;
}
- return ret;
+ return ret * bpf;
}
int