summaryrefslogtreecommitdiff
path: root/modules/alsa/alsa_src.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/alsa/alsa_src.c')
-rw-r--r--modules/alsa/alsa_src.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/modules/alsa/alsa_src.c b/modules/alsa/alsa_src.c
index 0f611ea..6688f9d 100644
--- a/modules/alsa/alsa_src.c
+++ b/modules/alsa/alsa_src.c
@@ -22,11 +22,13 @@ struct ausrc_st {
bool run;
snd_pcm_t *read;
int16_t *sampv;
+ void *xsampv;
size_t sampc;
ausrc_read_h *rh;
void *arg;
struct ausrc_prm prm;
char *device;
+ enum aufmt aufmt;
};
@@ -45,6 +47,7 @@ static void ausrc_destructor(void *arg)
snd_pcm_close(st->read);
mem_deref(st->sampv);
+ mem_deref(st->xsampv);
mem_deref(st->device);
}
@@ -66,7 +69,15 @@ static void *read_thread(void *arg)
}
while (st->run) {
- err = snd_pcm_readi(st->read, st->sampv, num_frames);
+ size_t sampc;
+ void *sampv;
+
+ if (st->aufmt == AUFMT_S16LE)
+ sampv = st->sampv;
+ else
+ sampv = st->xsampv;
+
+ err = snd_pcm_readi(st->read, sampv, num_frames);
if (err == -EPIPE) {
snd_pcm_prepare(st->read);
continue;
@@ -75,7 +86,14 @@ static void *read_thread(void *arg)
continue;
}
- st->rh(st->sampv, err * st->prm.ch, st->arg);
+ sampc = err * st->prm.ch;
+
+ if (st->aufmt != AUFMT_S16LE) {
+ auconv_to_s16(st->sampv, st->aufmt,
+ st->xsampv, sampc);
+ }
+
+ st->rh(st->sampv, sampc, st->arg);
}
out:
@@ -89,6 +107,7 @@ int alsa_src_alloc(struct ausrc_st **stp, const struct ausrc *as,
ausrc_read_h *rh, ausrc_error_h *errh, void *arg)
{
struct ausrc_st *st;
+ snd_pcm_format_t pcmfmt;
int num_frames;
int err;
(void)ctx;
@@ -112,6 +131,7 @@ int alsa_src_alloc(struct ausrc_st **stp, const struct ausrc *as,
st->as = as;
st->rh = rh;
st->arg = arg;
+ st->aufmt = alsa_sample_format;
st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
num_frames = st->prm.srate * st->prm.ptime / 1000;
@@ -122,6 +142,15 @@ int alsa_src_alloc(struct ausrc_st **stp, const struct ausrc *as,
goto out;
}
+ if (st->aufmt != AUFMT_S16LE) {
+ size_t sz = aufmt_sample_size(st->aufmt) * st->sampc;
+ st->xsampv = mem_alloc(sz, NULL);
+ if (!st->xsampv) {
+ err = ENOMEM;
+ goto out;
+ }
+ }
+
err = snd_pcm_open(&st->read, st->device, SND_PCM_STREAM_CAPTURE, 0);
if (err < 0) {
warning("alsa: could not open ausrc device '%s' (%s)\n",
@@ -129,7 +158,16 @@ int alsa_src_alloc(struct ausrc_st **stp, const struct ausrc *as,
goto out;
}
- err = alsa_reset(st->read, st->prm.srate, st->prm.ch, num_frames);
+ pcmfmt = aufmt_to_alsaformat(st->aufmt);
+ if (pcmfmt == SND_PCM_FORMAT_UNKNOWN) {
+ warning("alsa: unknown sample format '%s'\n",
+ aufmt_name(st->aufmt));
+ err = EINVAL;
+ goto out;
+ }
+
+ err = alsa_reset(st->read, st->prm.srate, st->prm.ch, num_frames,
+ pcmfmt);
if (err) {
warning("alsa: could not reset source '%s' (%s)\n",
st->device, snd_strerror(err));