Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add support for playback- or capture-only devices by adding
details: https://anonhg.NetBSD.org/src/rev/c045f232f016
branches: trunk
changeset: 747726:c045f232f016
user: sborrill <sborrill%NetBSD.org@localhost>
date: Tue Sep 29 15:58:54 2009 +0000
description:
Add support for playback- or capture-only devices by adding
AUDIO_PROP_PLAYBACK and AUDIO_PROP_CAPTURE properties.
>From jmcneill@.
Fixes PR#42050
diffstat:
share/man/man4/audio.4 | 8 +-
sys/dev/audio.c | 230 +++++++++++++++++++++++++------------
sys/dev/audio_if.h | 8 +-
sys/dev/pci/hdaudio/hdaudio_afg.c | 25 ++-
sys/sys/audioio.h | 4 +-
5 files changed, 185 insertions(+), 90 deletions(-)
diffs (truncated from 496 to 300 lines):
diff -r 0edfcedd8e18 -r c045f232f016 share/man/man4/audio.4
--- a/share/man/man4/audio.4 Tue Sep 29 13:30:17 2009 +0000
+++ b/share/man/man4/audio.4 Tue Sep 29 15:58:54 2009 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: audio.4,v 1.69 2009/01/03 17:44:20 christos Exp $
+.\" $NetBSD: audio.4,v 1.70 2009/09/29 15:58:54 sborrill Exp $
.\"
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd January 3, 2009
+.Dd September 29, 2009
.Dt AUDIO 4
.Os
.Sh NAME
@@ -243,6 +243,10 @@
.It Dv AUDIO_PROP_INDEPENDENT
the device can set the playing and recording encoding parameters
independently.
+.It Dv AUDIO_PROP_PLAYBACK
+the device is capable of audio playback.
+.It Dv AUDIO_PROP_CAPTURE
+the device is capable of audio capture.
.El
.It Dv AUDIO_GETIOFFS (audio_offset_t)
.It Dv AUDIO_GETOOFFS (audio_offset_t)
diff -r 0edfcedd8e18 -r c045f232f016 sys/dev/audio.c
--- a/sys/dev/audio.c Tue Sep 29 13:30:17 2009 +0000
+++ b/sys/dev/audio.c Tue Sep 29 15:58:54 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.247 2009/09/24 16:03:11 sborrill Exp $ */
+/* $NetBSD: audio.c,v 1.248 2009/09/29 15:58:54 sborrill Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.247 2009/09/24 16:03:11 sborrill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.248 2009/09/29 15:58:54 sborrill Exp $");
#include "audio.h"
#if NAUDIO > 0
@@ -192,6 +192,10 @@
static void audio_mixer_capture(struct audio_softc *);
static void audio_mixer_restore(struct audio_softc *);
+static int audio_get_props(struct audio_softc *);
+static bool audio_can_playback(struct audio_softc *);
+static bool audio_can_capture(struct audio_softc *);
+
static void audio_softintr_rd(void *);
static void audio_softintr_wr(void *);
@@ -315,22 +319,6 @@
}
#endif
- props = hwp->get_props(hdlp);
-
- aprint_naive("\n");
-
- if (props & AUDIO_PROP_FULLDUPLEX)
- aprint_normal(": full duplex");
- else
- aprint_normal(": half duplex");
-
- if (props & AUDIO_PROP_MMAP)
- aprint_normal(", mmap");
- if (props & AUDIO_PROP_INDEPENDENT)
- aprint_normal(", independent");
-
- aprint_normal("\n");
-
sc->hw_if = hwp;
sc->hw_hdl = hdlp;
sc->sc_dev = parent;
@@ -338,18 +326,44 @@
sc->sc_writing = sc->sc_waitcomp = 0;
sc->sc_lastinfovalid = false;
- error = audio_alloc_ring(sc, &sc->sc_pr, AUMODE_PLAY, AU_RING_SIZE);
- if (error) {
- sc->hw_if = NULL;
- aprint_error("audio: could not allocate play buffer\n");
- return;
+ props = audio_get_props(sc);
+
+ if (props & AUDIO_PROP_FULLDUPLEX)
+ aprint_normal(": full duplex");
+ else
+ aprint_normal(": half duplex");
+
+ if (props & AUDIO_PROP_PLAYBACK)
+ aprint_normal(", playback");
+ if (props & AUDIO_PROP_CAPTURE)
+ aprint_normal(", capture");
+ if (props & AUDIO_PROP_MMAP)
+ aprint_normal(", mmap");
+ if (props & AUDIO_PROP_INDEPENDENT)
+ aprint_normal(", independent");
+
+ aprint_naive("\n");
+ aprint_normal("\n");
+
+ if (audio_can_playback(sc)) {
+ error = audio_alloc_ring(sc, &sc->sc_pr,
+ AUMODE_PLAY, AU_RING_SIZE);
+ if (error) {
+ sc->hw_if = NULL;
+ aprint_error("audio: could not allocate play buffer\n");
+ return;
+ }
}
- error = audio_alloc_ring(sc, &sc->sc_rr, AUMODE_RECORD, AU_RING_SIZE);
- if (error) {
- audio_free_ring(sc, &sc->sc_pr);
- sc->hw_if = NULL;
- aprint_error("audio: could not allocate record buffer\n");
- return;
+ if (audio_can_capture(sc)) {
+ error = audio_alloc_ring(sc, &sc->sc_rr,
+ AUMODE_RECORD, AU_RING_SIZE);
+ if (error) {
+ if (sc->sc_pr.s.start != 0)
+ audio_free_ring(sc, &sc->sc_pr);
+ sc->hw_if = NULL;
+ aprint_error("audio: could not allocate record buffer\n");
+ return;
+ }
}
sc->sc_lastgain = 128;
@@ -742,6 +756,8 @@
void
audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r)
{
+ if (r->s.start == 0)
+ return;
if (sc->hw_if->freem)
sc->hw_if->freem(sc->hw_hdl, r->s.start, M_DEVBUF);
@@ -1301,41 +1317,49 @@
DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
hw = sc->hw_if;
- audio_init_ringbuffer(sc, &sc->sc_rr, AUMODE_RECORD);
- if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
- error = hw->init_input(sc->hw_hdl, sc->sc_rr.s.start,
+ if (audio_can_capture(sc)) {
+ audio_init_ringbuffer(sc, &sc->sc_rr, AUMODE_RECORD);
+ if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
+ error = hw->init_input(sc->hw_hdl, sc->sc_rr.s.start,
sc->sc_rr.s.end - sc->sc_rr.s.start);
- if (error)
- return error;
+ if (error)
+ return error;
+ }
}
- audio_init_ringbuffer(sc, &sc->sc_pr, AUMODE_PLAY);
- sc->sc_sil_count = 0;
- if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
- error = hw->init_output(sc->hw_hdl, sc->sc_pr.s.start,
+ if (audio_can_playback(sc)) {
+ audio_init_ringbuffer(sc, &sc->sc_pr, AUMODE_PLAY);
+ sc->sc_sil_count = 0;
+ if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
+ error = hw->init_output(sc->hw_hdl, sc->sc_pr.s.start,
sc->sc_pr.s.end - sc->sc_pr.s.start);
- if (error)
- return error;
+ if (error)
+ return error;
+ }
}
#ifdef AUDIO_INTR_TIME
#define double u_long
- sc->sc_pnintr = 0;
- sc->sc_pblktime = (u_long)(
- (double)sc->sc_pr.blksize * 100000 /
- (double)(sc->sc_pparams.precision / NBBY *
- sc->sc_pparams.channels *
- sc->sc_pparams.sample_rate)) * 10;
- DPRINTF(("audio: play blktime = %lu for %d\n",
- sc->sc_pblktime, sc->sc_pr.blksize));
- sc->sc_rnintr = 0;
- sc->sc_rblktime = (u_long)(
- (double)sc->sc_rr.blksize * 100000 /
- (double)(sc->sc_rparams.precision / NBBY *
- sc->sc_rparams.channels *
- sc->sc_rparams.sample_rate)) * 10;
- DPRINTF(("audio: record blktime = %lu for %d\n",
- sc->sc_rblktime, sc->sc_rr.blksize));
+ if (audio_can_playback(sc)) {
+ sc->sc_pnintr = 0;
+ sc->sc_pblktime = (u_long)(
+ (double)sc->sc_pr.blksize * 100000 /
+ (double)(sc->sc_pparams.precision / NBBY *
+ sc->sc_pparams.channels *
+ sc->sc_pparams.sample_rate)) * 10;
+ DPRINTF(("audio: play blktime = %lu for %d\n",
+ sc->sc_pblktime, sc->sc_pr.blksize));
+ }
+ if (audio_can_capture(sc)) {
+ sc->sc_rnintr = 0;
+ sc->sc_rblktime = (u_long)(
+ (double)sc->sc_rr.blksize * 100000 /
+ (double)(sc->sc_rparams.precision / NBBY *
+ sc->sc_rparams.channels *
+ sc->sc_rparams.sample_rate)) * 10;
+ DPRINTF(("audio: record blktime = %lu for %d\n",
+ sc->sc_rblktime, sc->sc_rr.blksize));
+ }
#undef double
#endif
@@ -1347,18 +1371,24 @@
{
/* set high at 100% */
- sc->sc_pr.usedhigh = sc->sc_pustream->end - sc->sc_pustream->start;
- /* set low at 75% of usedhigh */
- sc->sc_pr.usedlow = sc->sc_pr.usedhigh * 3 / 4;
- if (sc->sc_pr.usedlow == sc->sc_pr.usedhigh)
- sc->sc_pr.usedlow -= sc->sc_pr.blksize;
-
- sc->sc_rr.usedhigh = sc->sc_rustream->end - sc->sc_rustream->start
- - sc->sc_rr.blksize;
- sc->sc_rr.usedlow = 0;
- DPRINTF(("%s: plow=%d phigh=%d rlow=%d rhigh=%d\n", __func__,
- sc->sc_pr.usedlow, sc->sc_pr.usedhigh,
- sc->sc_rr.usedlow, sc->sc_rr.usedhigh));
+ if (audio_can_playback(sc)) {
+ sc->sc_pr.usedhigh =
+ sc->sc_pustream->end - sc->sc_pustream->start;
+ /* set low at 75% of usedhigh */
+ sc->sc_pr.usedlow = sc->sc_pr.usedhigh * 3 / 4;
+ if (sc->sc_pr.usedlow == sc->sc_pr.usedhigh)
+ sc->sc_pr.usedlow -= sc->sc_pr.blksize;
+ }
+
+ if (audio_can_capture(sc)) {
+ sc->sc_rr.usedhigh =
+ sc->sc_rustream->end - sc->sc_rustream->start -
+ sc->sc_rr.blksize;
+ sc->sc_rr.usedlow = 0;
+ DPRINTF(("%s: plow=%d phigh=%d rlow=%d rhigh=%d\n", __func__,
+ sc->sc_pr.usedlow, sc->sc_pr.usedhigh,
+ sc->sc_rr.usedlow, sc->sc_rr.usedhigh));
+ }
}
static inline int
@@ -1436,7 +1466,7 @@
sc->sc_full_duplex =
(flags & (FWRITE|FREAD)) == (FWRITE|FREAD) &&
- (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX);
+ (audio_get_props(sc) & AUDIO_PROP_FULLDUPLEX);
mode = 0;
if (flags & FREAD) {
@@ -2251,7 +2281,7 @@
case AUDIO_SETFD:
DPRINTF(("AUDIO_SETFD\n"));
fd = *(int *)addr;
- if (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) {
+ if (audio_get_props(sc) & AUDIO_PROP_FULLDUPLEX) {
if (hw->setfd)
error = hw->setfd(sc->hw_hdl, fd);
else
@@ -2268,7 +2298,7 @@
case AUDIO_GETPROPS:
DPRINTF(("AUDIO_GETPROPS\n"));
- *(int *)addr = hw->get_props(sc->hw_hdl);
+ *(int *)addr = audio_get_props(sc);
break;
default:
@@ -2439,7 +2469,7 @@
DPRINTF(("audio_mmap: off=%lld, prot=%d\n", (long long)off, prot));
hw = sc->hw_if;
- if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
+ if (!(audio_get_props(sc) & AUDIO_PROP_MMAP) || !hw->mappage)
return -1;
#if 0
/* XXX
@@ -2498,6 +2528,9 @@
sc->sc_rr.s.start, audio_stream_get_used(&sc->sc_rr.s),
sc->sc_rr.usedhigh, sc->sc_rr.mmapped));
Home |
Main Index |
Thread Index |
Old Index