Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-10]: src/sys/dev/pad Pull up following revision(s) (requested by ...
details: https://anonhg.NetBSD.org/src/rev/27eae7c59d33
branches: netbsd-10
changeset: 374550:27eae7c59d33
user: martin <martin%NetBSD.org@localhost>
date: Tue May 02 17:39:54 2023 +0000
description:
Pull up following revision(s) (requested by mlelstv in ticket #153):
sys/dev/pad/pad.c: revision 1.80
sys/dev/pad/pad.c: revision 1.81
sys/dev/pad/pad.c: revision 1.82
sys/dev/pad/pad.c: revision 1.79
sys/dev/pad/padvar.h: revision 1.17
Pace I/O timing to match the audio interface.
Enable interrupts while copying buffers.
Write slinear_le 16bit samples, independent from platform and
AUDIO_INTERNAL_BITS.
No longer use AUDIO_INTERNAL_BITS but rely on passed audio format.
Don't overflow when scaling 32bit samples.
diffstat:
sys/dev/pad/pad.c | 111 +++++++++++++++++++++++++++++++++++++++++---------
sys/dev/pad/padvar.h | 4 +-
2 files changed, 93 insertions(+), 22 deletions(-)
diffs (233 lines):
diff -r 32d0ab8b2d9c -r 27eae7c59d33 sys/dev/pad/pad.c
--- a/sys/dev/pad/pad.c Tue May 02 17:23:32 2023 +0000
+++ b/sys/dev/pad/pad.c Tue May 02 17:39:54 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pad.c,v 1.78 2022/03/31 19:30:16 pgoyette Exp $ */
+/* $NetBSD: pad.c,v 1.78.4.1 2023/05/02 17:39:54 martin Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.78 2022/03/31 19:30:16 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.78.4.1 2023/05/02 17:39:54 martin Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -148,7 +148,7 @@ static const struct audio_format pad_for
extern void padattach(int);
static int pad_add_block(struct pad_softc *, uint8_t *, int);
-static int pad_get_block(struct pad_softc *, pad_block_t *, int);
+static int pad_get_block(struct pad_softc *, pad_block_t *, int, int);
static dev_type_open(pad_open);
@@ -280,7 +280,7 @@ pad_childdet(device_t self, device_t chi
static int
pad_add_block(struct pad_softc *sc, uint8_t *blk, int blksize)
{
- int l;
+ int foff, flen, tlen;
KASSERT(blksize >= 0);
KASSERT(mutex_owned(&sc->sc_intr_lock));
@@ -289,18 +289,27 @@ pad_add_block(struct pad_softc *sc, uint
sc->sc_buflen > PAD_BUFSIZE - (unsigned)blksize)
return ENOBUFS;
- if (sc->sc_wpos + blksize <= PAD_BUFSIZE)
- memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, blksize);
- else {
- l = PAD_BUFSIZE - sc->sc_wpos;
- memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, l);
- memcpy(sc->sc_audiobuf, blk + l, blksize - l);
+ foff = sc->sc_wpos;
+ if (sc->sc_wpos + blksize <= PAD_BUFSIZE) {
+ flen = blksize;
+ tlen = 0;
+ } else {
+ flen = PAD_BUFSIZE - sc->sc_wpos;
+ tlen = blksize - flen;
}
- sc->sc_wpos += blksize;
+ sc->sc_wpos = foff + blksize;
if (sc->sc_wpos >= PAD_BUFSIZE)
sc->sc_wpos -= PAD_BUFSIZE;
+ /*
+ * release interrupt lock for bulk copy to audio buffer
+ */
+ mutex_exit(&sc->sc_intr_lock);
+ memcpy(sc->sc_audiobuf + foff, blk, flen);
+ memcpy(sc->sc_audiobuf, blk + flen, tlen);
+ mutex_enter(&sc->sc_intr_lock);
+
sc->sc_buflen += blksize;
cv_broadcast(&sc->sc_condvar);
@@ -308,13 +317,16 @@ pad_add_block(struct pad_softc *sc, uint
}
static int
-pad_get_block(struct pad_softc *sc, pad_block_t *pb, int maxblksize)
+pad_get_block(struct pad_softc *sc, pad_block_t *pb, int maxblksize, int dowait)
{
int l, blksize, error;
KASSERT(maxblksize > 0);
KASSERT(mutex_owned(&sc->sc_intr_lock));
+ if (sc->sc_buflen == 0 && !dowait)
+ return EAGAIN;
+
while (sc->sc_buflen == 0) {
DPRINTF("%s: wait\n", __func__);
error = cv_wait_sig(&sc->sc_condvar, &sc->sc_intr_lock);
@@ -500,14 +512,20 @@ pad_read(struct pad_softc *sc, off_t *of
int ioflag)
{
pad_block_t pb;
- int err;
+ int err, first;
err = 0;
+ first = 1;
DPRINTF("%s: resid=%zu\n", __func__, uio->uio_resid);
while (uio->uio_resid > 0) {
mutex_enter(&sc->sc_intr_lock);
- err = pad_get_block(sc, &pb, MIN(uio->uio_resid, INT_MAX));
+ err = pad_get_block(sc, &pb, MIN(uio->uio_resid, INT_MAX), first);
mutex_exit(&sc->sc_intr_lock);
+ first = 0;
+ if (err == EAGAIN) {
+ err = 0;
+ break;
+ }
if (err)
break;
@@ -557,7 +575,8 @@ pad_start_output(void *opaque, void *blo
{
struct pad_softc *sc = opaque;
int err;
- int ms;
+ u_int framesize;
+ int ticks;
KASSERT(mutex_owned(&sc->sc_intr_lock));
@@ -566,10 +585,20 @@ pad_start_output(void *opaque, void *blo
DPRINTF("%s: blksize=%d\n", __func__, blksize);
err = pad_add_block(sc, block, blksize);
+ if (err) {
+ DPRINTF("%s: failed: %d\n", __func__, err);
+ /* "Silently" drop overflows, but keep pace */
+ err = 0;
+ }
- ms = blksize * 1000 / PADCHAN / (PADPREC / NBBY) / PADFREQ;
+ framesize = PADCHAN * (PADPREC / NBBY) * PADFREQ;
+
+ sc->sc_resid += blksize;
+ ticks = mstohz(sc->sc_resid * 1000 / framesize);
+ sc->sc_resid -= hztoms(ticks) * framesize / 1000;
+
DPRINTF("%s: callout ms=%d\n", __func__, ms);
- callout_schedule(&sc->sc_pcallout, mstohz(ms));
+ callout_schedule(&sc->sc_pcallout, ticks);
return err;
}
@@ -587,6 +616,7 @@ pad_halt_output(void *opaque)
sc->sc_intr = NULL;
sc->sc_intrarg = NULL;
sc->sc_buflen = 0;
+ sc->sc_resid = 0;
sc->sc_rpos = sc->sc_wpos = 0;
return 0;
@@ -714,18 +744,57 @@ static void
pad_swvol_codec(audio_filter_arg_t *arg)
{
struct pad_softc *sc = arg->context;
- const aint_t *src;
- aint_t *dst;
+ const uint8_t *src;
+ uint8_t *dst;
u_int sample_count;
u_int i;
+ u_int bits;
src = arg->src;
dst = arg->dst;
sample_count = arg->count * arg->srcfmt->channels;
+ bits = arg->srcfmt->precision;
+
for (i = 0; i < sample_count; i++) {
- aint2_t v = (aint2_t)(*src++);
+ int64_t v;
+
+ switch (howmany(bits, NBBY)) {
+ case 2: /* AUDIO_INTERNAL_BITS == 16 */
+ v = *(const int16_t *)src;
+ src += sizeof(int16_t);
+ break;
+ case 4: /* AUDIO_INTERNAL_BITS == 32 */
+ v = *(const int32_t *)src;
+ src += sizeof(int32_t);
+ break;
+ default:
+ v = 0;
+ break;
+ }
+
v = v * sc->sc_swvol / 255;
- *dst++ = (aint_t)v;
+
+ if (PADPREC > bits)
+ v = v << (PADPREC - bits);
+ else if (PADPREC < bits)
+ v = v >> (bits - PADPREC);
+
+ /* AUDIO_ENCODING_SLINEAR_LE */
+#if PADPREC > 0
+ *dst++ = v;
+#endif
+#if PADPREC > 8
+ v >>= 8;
+ *dst++ = v;
+#endif
+#if PADPREC > 16
+ v >>= 8;
+ *dst++ = v;
+#endif
+#if PADPREC > 24
+ v >>= 8;
+ *dst++ = v;
+#endif
}
}
diff -r 32d0ab8b2d9c -r 27eae7c59d33 sys/dev/pad/padvar.h
--- a/sys/dev/pad/padvar.h Tue May 02 17:23:32 2023 +0000
+++ b/sys/dev/pad/padvar.h Tue May 02 17:39:54 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: padvar.h,v 1.16 2021/06/14 18:44:45 riastradh Exp $ */
+/* $NetBSD: padvar.h,v 1.16.10.1 2023/05/02 17:39:54 martin Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -57,6 +57,8 @@ struct pad_softc {
u_int sc_wpos;
uint8_t sc_swvol;
+
+ u_int sc_resid;
};
#endif /* !_SYS_DEV_PAD_PADVAR_H */
Home |
Main Index |
Thread Index |
Old Index