summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorisaki <isaki@NetBSD.org>2017-08-05 05:53:26 +0000
committerisaki <isaki@NetBSD.org>2017-08-05 05:53:26 +0000
commite2cc1860a6237685f6db79097df85167dffa88f7 (patch)
tree40545b1d531e32162cc938f63fb0b4c004a75455 /sys/dev/ic
parent9eebcd51202645ff8cc68eaef86b2dcc69c3400c (diff)
vs(4) became to able to play audio again.
At the moment the encoding conversion using set_params() does not seem to work for me. So vs(4) uses local conversion to/from ADPCM instead of it. But this should be a temporary work. XXX The playback quality is very poor compared to before... XXX Recording is not tested.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/msm6258.c112
-rw-r--r--sys/dev/ic/msm6258var.h10
2 files changed, 119 insertions, 3 deletions
diff --git a/sys/dev/ic/msm6258.c b/sys/dev/ic/msm6258.c
index 9431b097416..2ea2dc9ad38 100644
--- a/sys/dev/ic/msm6258.c
+++ b/sys/dev/ic/msm6258.c
@@ -1,4 +1,4 @@
-/* $NetBSD: msm6258.c,v 1.22 2017/08/05 05:04:30 isaki Exp $ */
+/* $NetBSD: msm6258.c,v 1.23 2017/08/05 05:53:26 isaki Exp $ */
/*
* Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msm6258.c,v 1.22 2017/08/05 05:04:30 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msm6258.c,v 1.23 2017/08/05 05:53:26 isaki Exp $");
#include <sys/systm.h>
#include <sys/device.h>
@@ -412,3 +412,111 @@ DEFINE_FILTER(msm6258_adpcm_to_linear8)
this->src->outp = s;
return 0;
}
+
+
+/*
+ * XXX MI audio(4) layer does not seem to support non SLINEAR devices.
+ * XXX So vs(4) converts SLINEAR <-> ADPCM itself.
+ * XXX This is temporary way, of course.
+ */
+
+void *
+vs_alloc_msm6258codec(void)
+{
+ return (void *)msm6258_factory(NULL, NULL);
+}
+
+void
+vs_free_msm6258codec(void *arg)
+{
+ stream_filter_t *filter = (stream_filter_t *)arg;
+ if (filter != NULL) {
+ filter->dtor(filter);
+ }
+}
+
+void
+vs_slinear16be_to_adpcm(void *arg, void *dst, const void *src, int srclen)
+{
+ struct msm6258_codecvar *mc = (struct msm6258_codecvar *)arg;
+ const int16_t *s, *end;
+ uint8_t *d;
+
+ s = (const int16_t *)src;
+ d = (uint8_t *)dst;
+ end = (const int16_t *)((const int8_t *)src + srclen);
+ while (s < end) {
+ uint8_t f;
+ int16_t ss;
+ ss = be16toh(*s++);
+ f = pcm2adpcm_step(mc, ss);
+ ss = be16toh(*s++);
+ f |= pcm2adpcm_step(mc, ss) << 4;
+ *d++ = f;
+ }
+}
+
+void
+vs_slinear8_to_adpcm(void *arg, void *dst, const void *src, int srclen)
+{
+ struct msm6258_codecvar *mc = (struct msm6258_codecvar *)arg;
+ const int8_t *s, *end;
+ uint8_t *d;
+
+ s = (const int8_t *)src;
+ d = (uint8_t *)dst;
+ end = (const int8_t *)src + srclen;
+ while (s < end) {
+ uint8_t f;
+ int16_t ss;
+ ss = ((int16_t)*s) * 256;
+ s++;
+ f = pcm2adpcm_step(mc, ss);
+ ss = ((int16_t)*s) * 256;
+ s++;
+ f |= pcm2adpcm_step(mc, ss) << 4;
+ *d++ = f;
+ }
+}
+
+void
+vs_adpcm_to_slinear16be(void *arg, void *dst, int dstlen, const void *src)
+{
+ struct msm6258_codecvar *mc = (struct msm6258_codecvar *)arg;
+ const uint8_t *s, *end;
+ int16_t *d;
+
+ s = (const int8_t *)src;
+ d = (int16_t *)dst;
+ end = s + (dstlen / 4);
+ while (s < end) {
+ uint8_t a;
+ int16_t s1, s2;
+ a = *s++;
+ s1 = adpcm2pcm_step(mc, a & 0x0f);
+ s2 = adpcm2pcm_step(mc, a >> 4);
+ *d++ = s1;
+ *d++ = s2;
+ }
+}
+
+void
+vs_adpcm_to_slinear8(void *arg, void *dst, int dstlen, const void *src)
+{
+ struct msm6258_codecvar *mc = (struct msm6258_codecvar *)arg;
+ const uint8_t *s, *end;
+ int8_t *d;
+
+ s = (const int8_t *)src;
+ d = (int8_t *)dst;
+ end = s + (dstlen / 2);
+ while (s < end) {
+ uint8_t a;
+ int16_t s1, s2;
+ a = *s++;
+ s1 = adpcm2pcm_step(mc, a & 0x0f);
+ s2 = adpcm2pcm_step(mc, a >> 4);
+ *d++ = s1 / 256;
+ *d++ = s2 / 256;
+ }
+}
diff --git a/sys/dev/ic/msm6258var.h b/sys/dev/ic/msm6258var.h
index e030170b8fc..7b7c51e0623 100644
--- a/sys/dev/ic/msm6258var.h
+++ b/sys/dev/ic/msm6258var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: msm6258var.h,v 1.8 2011/10/16 03:10:18 isaki Exp $ */
+/* $NetBSD: msm6258var.h,v 1.9 2017/08/05 05:53:26 isaki Exp $ */
/*
* Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
@@ -32,3 +32,11 @@ extern stream_filter_factory_t msm6258_slinear16_to_adpcm;
extern stream_filter_factory_t msm6258_linear8_to_adpcm;
extern stream_filter_factory_t msm6258_adpcm_to_slinear16;
extern stream_filter_factory_t msm6258_adpcm_to_linear8;
+
+/* XXX */
+extern void *vs_alloc_msm6258codec(void);
+extern void vs_free_msm6258codec(void *);
+extern void vs_slinear16be_to_adpcm(void *, void *, const void *, int);
+extern void vs_slinear8_to_adpcm(void *, void *, const void *, int);
+extern void vs_adpcm_to_slinear16be(void *, void *, int, const void *);
+extern void vs_adpcm_to_slinear8(void *, void *, int, const void *);