Module Name: src Committed By: isaki Date: Wed Apr 20 07:11:14 UTC 2022
Modified Files: src/sys/dev/audio: audio.c audiodef.h Log Message: audio(4): Rework AUDIO_GETOOFFS. - Count .samples/.deltablks in blocks. It makes .deltablks integer wrap around safe. - Remove suspicious one block offset from .offset. I added the offset because it was observed so on NetBSD7. But according to manpage, it should not be. And it looks fine without the offset. - Related to that, remove a comment in AUDIO_WSEEK. Limit the user-visible buffer to usrbuf only. To generate a diff of this commit: cvs rdiff -u -r1.126 -r1.127 src/sys/dev/audio/audio.c cvs rdiff -u -r1.17 -r1.18 src/sys/dev/audio/audiodef.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/audio/audio.c diff -u src/sys/dev/audio/audio.c:1.126 src/sys/dev/audio/audio.c:1.127 --- src/sys/dev/audio/audio.c:1.126 Wed Apr 20 06:05:22 2022 +++ src/sys/dev/audio/audio.c Wed Apr 20 07:11:13 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.126 2022/04/20 06:05:22 isaki Exp $ */ +/* $NetBSD: audio.c,v 1.127 2022/04/20 07:11:13 isaki Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -181,7 +181,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.126 2022/04/20 06:05:22 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.127 2022/04/20 07:11:13 isaki Exp $"); #ifdef _KERNEL_OPT #include "audio.h" @@ -2985,7 +2985,7 @@ audio_ioctl(dev_t dev, struct audio_soft audio_encoding_t *ae; audio_format_query_t *query; u_int stamp; - u_int offs; + u_int offset; int val; int index; int error; @@ -3104,28 +3104,23 @@ audio_ioctl(dev_t dev, struct audio_soft } mutex_enter(sc->sc_lock); mutex_enter(sc->sc_intr_lock); - /* figure out where next DMA will start */ - stamp = track->usrbuf_stamp; - offs = track->usrbuf.head; + /* figure out where next transfer will start */ + stamp = track->stamp; + offset = track->usrbuf.head; mutex_exit(sc->sc_intr_lock); mutex_exit(sc->sc_lock); - ao->samples = stamp; - ao->deltablks = (stamp / track->usrbuf_blksize) - - (track->usrbuf_stamp_last / track->usrbuf_blksize); - track->usrbuf_stamp_last = stamp; - offs = rounddown(offs, track->usrbuf_blksize) - + track->usrbuf_blksize; - if (offs >= track->usrbuf.capacity) - offs -= track->usrbuf.capacity; - ao->offset = offs; - + /* samples will overflow soon but is as per spec. */ + ao->samples = stamp * track->usrbuf_blksize; + ao->deltablks = stamp - track->last_stamp; + ao->offset = offset; TRACET(2, track, "%s samples=%u deltablks=%u offset=%u", pre, ao->samples, ao->deltablks, ao->offset); + + track->last_stamp = stamp; break; case AUDIO_WSEEK: - /* XXX return value does not include outbuf one. */ track = file->ptrack; if (track) { val = track->usrbuf.used; @@ -4964,8 +4959,6 @@ audio_track_play(audio_track_t *track) count = uimin(usrbuf->used, track->usrbuf_blksize) / framesize; bytes = count * framesize; - track->usrbuf_stamp += bytes; - if (usrbuf->head + bytes < usrbuf->capacity) { memcpy((uint8_t *)input->mem + auring_tail(input) * framesize, (uint8_t *)usrbuf->mem + usrbuf->head, @@ -5060,6 +5053,8 @@ audio_track_play(audio_track_t *track) track->outputcounter += track->outbuf.used - track_count_0; } + track->stamp++; + #if defined(AUDIO_DEBUG) if (audiodebug >= 3) { struct audio_track_debugbuf m; @@ -6311,6 +6306,8 @@ audio_track_clear(struct audio_softc *sc track->outbuf.used = 0; /* Clear counters. */ + track->stamp = 0; + track->last_stamp = 0; track->dropframes = 0; audio_track_lock_exit(track); @@ -7773,7 +7770,7 @@ audiogetinfo(struct audio_softc *sc, str if (ptrack) { pi->seek = ptrack->usrbuf.used; - pi->samples = ptrack->usrbuf_stamp; + pi->samples = ptrack->stamp * ptrack->usrbuf_blksize; pi->eof = ptrack->eofcounter; pi->error = (ptrack->dropframes != 0) ? 1 : 0; pi->open = 1; @@ -7784,7 +7781,7 @@ audiogetinfo(struct audio_softc *sc, str if (rtrack) { ri->seek = audio_track_readablebytes(rtrack); - ri->samples = rtrack->usrbuf_stamp; + ri->samples = rtrack->stamp * rtrack->usrbuf_blksize; ri->eof = 0; ri->error = (rtrack->dropframes != 0) ? 1 : 0; ri->open = 1; Index: src/sys/dev/audio/audiodef.h diff -u src/sys/dev/audio/audiodef.h:1.17 src/sys/dev/audio/audiodef.h:1.18 --- src/sys/dev/audio/audiodef.h:1.17 Wed Apr 20 06:05:22 2022 +++ src/sys/dev/audio/audiodef.h Wed Apr 20 07:11:13 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: audiodef.h,v 1.17 2022/04/20 06:05:22 isaki Exp $ */ +/* $NetBSD: audiodef.h,v 1.18 2022/04/20 07:11:13 isaki Exp $ */ /* * Copyright (C) 2017 Tetsuya Isaki. All rights reserved. @@ -121,8 +121,6 @@ struct audio_track { u_int usrbuf_blksize; /* usrbuf block size in bytes */ struct uvm_object *uobj; bool mmapped; /* device is mmap()-ed */ - u_int usrbuf_stamp; /* transferred bytes from/to stage */ - u_int usrbuf_stamp_last; /* last stamp */ u_int usrbuf_usedhigh;/* high water mark in bytes */ u_int usrbuf_usedlow; /* low water mark in bytes */ @@ -162,6 +160,13 @@ struct audio_track { u_int volume; #endif + /* + * For AUDIO_GET[IO]OFFS. + * No locks are required for these. + */ + u_int stamp; /* number of transferred blocks */ + u_int last_stamp; + audio_trackmixer_t *mixer; /* connected track mixer */ /* Sequence number picked up by track mixer. */