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