commit e26da60a20d19b69c0bafd3005985d2c9965c4f3 from: Omar Polo date: Thu Mar 23 14:10:48 2023 UTC add an audio implementation for ALSA it still doesn't work correctly, audio is very distorted, but at least there's some sound. commit - 06ceb3767eb7e480de05cd50f4fbaf75fb3322a2 commit + e26da60a20d19b69c0bafd3005985d2c9965c4f3 blob - ed6eac93eeae2b298b126764266afb1ebaf7ca0e blob + dd7865dd031072630bde52cdb3f06d625ba85dea --- Makefile +++ Makefile @@ -94,6 +94,7 @@ ${DISTNAME}.tar.gz: ${DISTFILES} # supports it. -include amused.d +-include audio_alsa.d -include audio_sndio.d -include compats.d -include control.d blob - /dev/null blob + 59128b71c8a1192389220edbb0178e4a416c51b9 (mode 644) --- /dev/null +++ audio_alsa.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2023 Omar Polo + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" + +#include + +#include + +#include "amused.h" +#include "log.h" + +static snd_pcm_t *pcm; + +int +audio_open(void (*onmove_cb)(void *, int)) +{ + const char *device = "default"; + int err; + + err = snd_pcm_open(&pcm, device, SND_PCM_STREAM_PLAYBACK, + SND_PCM_NONBLOCK); + if (err < 0) { + log_warnx("playback open error: %s", snd_strerror(err)); + return -1; + } + + /* TODO: set up onmove callback? */ + return 0; +} + +int +audio_setup(unsigned int bits, unsigned int rate, unsigned int channels, + struct pollfd *pfds) +{ + int err; + snd_pcm_format_t fmt; + + if (bits == 8) + fmt = SND_PCM_FORMAT_S8; + else if (bits == 16) + fmt = SND_PCM_FORMAT_S16; + else if (bits == 24) + fmt = SND_PCM_FORMAT_S24; + else if (bits == 32) + fmt = SND_PCM_FORMAT_S32; + else { + log_warnx("can't handle %d bits", bits); + return -1; + } + + err = snd_pcm_set_params(pcm, fmt, SND_PCM_ACCESS_RW_INTERLEAVED, + channels, rate, 1, 500000 /* 0.5s */); + if (err < 0) { + log_warnx("invalid params: %s", snd_strerror(err)); + return -1; + } + + err = snd_pcm_prepare(pcm); + if (err < 0) { + log_warnx("snd_pcm_prepare failed: %s", snd_strerror(err)); + return -1; + } + + return 0; +} + +int +audio_nfds(void) +{ + return snd_pcm_poll_descriptors_count(pcm); +} + +int +audio_pollfd(struct pollfd *pfds, int events) +{ + return snd_pcm_poll_descriptors(pcm, pfds, audio_nfds()); +} + +int +audio_revents(struct pollfd *pfds) +{ + int err; + unsigned short revents; + + err = snd_pcm_poll_descriptors_revents(pcm, pfds, audio_nfds(), + &revents); + if (err < 0) { + log_warnx("snd revents failure: %s", snd_strerror(err)); + return 0; + } + + return revents; +} + +size_t +audio_write(const void *buf, size_t len) +{ + snd_pcm_sframes_t ret; + + ret = snd_pcm_writei(pcm, buf, len); + if (ret < 0) { + log_warnx("snd_pcm_writei failed: %s", snd_strerror(ret)); + return 0; + } + return ret; +} + +int +audio_flush(void) +{ + int err; + + err = snd_pcm_drop(pcm); + if (err < 0) { + log_warnx("snd_pcm_drop: %s", snd_strerror(err)); + return -1; + } + + return 0; +} + +int +audio_stop(void) +{ + int err; + + err = snd_pcm_drain(pcm); + if (err < 0) { + log_warnx("snd_pcm_drain: %s", snd_strerror(err)); + return -1; + } + + return 0; +}