Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Audio now uses fdclone, there is no longer a limitation of o...



details:   https://anonhg.NetBSD.org/src/rev/b174f1676328
branches:  trunk
changeset: 821609:b174f1676328
user:      nat <nat%NetBSD.org@localhost>
date:      Fri Feb 10 19:31:42 2017 +0000

description:
Audio now uses fdclone, there is no longer a limitation of one audio
instance per process.  Virtual channels are placed in a queue, so there is
no longer a compile time limit of VAUDIOCHANS.

A new sysctl has been added to control multiple user access.
Mixer labels on virtual channels are now prefixed by vchan.

audiobell.c and audioctl have been updated to reflect these changes.

Use of fdclone was posted to tech-kern@ and improvements made.
Multiuser access control changes and the use of a queue were suggessted by
pgoyette@

diffstat:

 share/man/man4/audio.4       |    43 +-
 sys/dev/audio.c              |  1320 +++++++++++++++++++++++++----------------
 sys/dev/audiobell.c          |    36 +-
 sys/dev/audiovar.h           |    26 +-
 sys/sys/audioio.h            |    12 +-
 sys/sys/file.h               |     4 +-
 usr.bin/audio/ctl/audioctl.1 |    15 +-
 usr.bin/audio/ctl/ctl.c      |    36 +-
 8 files changed, 888 insertions(+), 604 deletions(-)

diffs (truncated from 3426 to 300 lines):

diff -r 6c1ae022f2e0 -r b174f1676328 share/man/man4/audio.4
--- a/share/man/man4/audio.4    Fri Feb 10 18:12:52 2017 +0000
+++ b/share/man/man4/audio.4    Fri Feb 10 19:31:42 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: audio.4,v 1.73 2016/12/12 11:49:27 nat Exp $
+.\"    $NetBSD: audio.4,v 1.74 2017/02/10 19:31:42 nat Exp $
 .\"
 .\" Copyright (c) 1996 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -99,11 +99,8 @@
 are identical.
 .Sh VIRTUAL CHANNELS
 Any process may open a sampling device at a given time.
-There is a constraint of
-.Em one
-device per process and file descriptors may
-.Em not
-be shared between processes.
+Any number of devices per process and file descriptors may be shared between
+processes.
 .Pp
 Virtual channels are converted to a common format, signed linear encoding,
 frequency channels and precision.
@@ -116,6 +113,7 @@
 .It hw.driverN.frequency
 .It hw.driverN.channels
 .It hw.driverN.saturate
+.It hw.driverN.multiuser
 .El
 .Pp
 Where
@@ -141,14 +139,28 @@
 .Em divided
 evenly in volume with respect to the master volume.
 .Pp
+An additional
+.Xr sysctl 8
+variable determines if multiple users are allowed to access the sampling
+device, hw.driverN.multiuser.
+.Pp
+By default it is set to false.
+This means that the sampling device may be only used by
+.Em one
+user at a time.
+Other users (except root) attempting to open the sampling device will be
+denied.
+.Pp
+If set to true, all users may access the sampling device at any time.
+.Pp
 Each virtual channel has a corresponding mixer:
 .Bl -tag -width -compact
-.It outputs.dacN  Output volume
-.It inputs.micN   Recording volume
+.It vchan.dacN  Output volume
+.It vchan.micN  Recording volume
 .El
 .Pp
 Where N is the virtual channel number.
-e.g ouputs.dac0 controlling playback volume and outputs.mic0 controlling
+e.g vchan.dac0 controlling playback volume and vchan.mic0 controlling
 recording volume for the first virtual channel.
 .Pp
 On a half-duplex device, writes while recording is in progress will be
@@ -233,17 +245,8 @@
 commands are supported on the sample devices:
 .Pp
 .Bl -tag -width indent
-.It Dv AUDIO_SETPROC (struct audio_pid)
-This command will select the audio device opened by pid.
-.Bd -literal
-struct audio_pid {
-        pid_t   pid;
-        lwpid_t lwpid;
-};
-.Ed
-.Pp
-Currently the lpwid value is
-.Em ignored .
+.It Dv AUDIO_SETPROC (int)
+This command will select the audio channel for subsequent ioctl calls.
 .It Dv AUDIO_FLUSH
 This command stops all playback and recording, clears all queued
 buffers, resets error counters, and restarts recording and playback as
diff -r 6c1ae022f2e0 -r b174f1676328 sys/dev/audio.c
--- a/sys/dev/audio.c   Fri Feb 10 18:12:52 2017 +0000
+++ b/sys/dev/audio.c   Fri Feb 10 19:31:42 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audio.c,v 1.301 2017/02/07 02:05:26 nat Exp $  */
+/*     $NetBSD: audio.c,v 1.302 2017/02/10 19:31:42 nat Exp $  */
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsloss%yahoo.com.au@localhost>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.301 2017/02/07 02:05:26 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.302 2017/02/10 19:31:42 nat Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -157,12 +157,17 @@
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
 #include <sys/vnode.h>
 #include <sys/select.h>
 #include <sys/poll.h>
+#include <sys/kauth.h>
 #include <sys/kmem.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
 #include <sys/systm.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
@@ -203,88 +208,103 @@
 
 int    audio_blk_ms = AUDIO_BLK_MS;
 
-int    audiosetinfo(struct audio_softc *, struct audio_info *, bool, int);
-int    audiogetinfo(struct audio_softc *, struct audio_info *, int, int);
-
-int    audio_open(dev_t, struct audio_softc *, int, int, struct lwp *);
-int    audio_close(struct audio_softc *, int, int, struct lwp *, int);
-int    audio_read(struct audio_softc *, struct uio *, int);
-int    audio_write(struct audio_softc *, struct uio *, int);
+int    audiosetinfo(struct audio_softc *, struct audio_info *, bool,
+                    struct virtual_channel *);
+int    audiogetinfo(struct audio_softc *, struct audio_info *, int,
+                    struct virtual_channel *);
+
+int    audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
+                  struct file **);
+int    audio_close(struct audio_softc *, int, struct audio_chan *);
+int    audio_read(struct audio_softc *, struct uio *, int,
+                  struct virtual_channel *);
+int    audio_write(struct audio_softc *, struct uio *, int,
+                   struct virtual_channel *);
 int    audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
-                   struct lwp *);
-int    audio_poll(struct audio_softc *, int, struct lwp *);
-int    audio_kqfilter(struct audio_softc *, struct knote *);
-paddr_t        audio_mmap(struct audio_softc *, off_t, int);
-
-int    mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
-int    mixer_close(struct audio_softc *, int, int, struct lwp *);
+                   struct lwp *, struct audio_chan *);
+int    audio_poll(struct audio_softc *, int, struct lwp *,
+                  struct virtual_channel *);
+int    audio_kqfilter(struct audio_chan *, struct knote *);
+paddr_t audiommap(dev_t, off_t, int, struct virtual_channel *);
+paddr_t audio_mmap(struct audio_softc *, off_t, int, struct virtual_channel *);
+int    audio_fop_mmap(struct file *, off_t *, size_t, int, int *, int *,
+                            struct uvm_object **, int *);
+
+int    mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *,
+                  struct file **);
+int    mixer_close(struct audio_softc *, int, struct audio_chan *);
 int    mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
 static void mixer_remove(struct audio_softc *);
 static void mixer_signal(struct audio_softc *);
-
-void   audio_init_record(struct audio_softc *, int);
-void   audio_init_play(struct audio_softc *, int);
-int    audiostartr(struct audio_softc *, int);
-int    audiostartp(struct audio_softc *, int);
+static void grow_mixer_states(struct audio_softc *, int);
+static void shrink_mixer_states(struct audio_softc *, int);
+
+void   audio_init_record(struct audio_softc *, struct virtual_channel *);
+void   audio_init_play(struct audio_softc *, struct virtual_channel *);
+int    audiostartr(struct audio_softc *, struct virtual_channel *);
+int    audiostartp(struct audio_softc *, struct virtual_channel *);
 void   audio_rint(void *);
 void   audio_pint(void *);
 void   audio_mix(void *);
 void   audio_upmix(void *);
 void   audio_play_thread(void *);
 void   audio_rec_thread(void *);
-void   recswvol_func(struct audio_softc *, struct audio_ringbuffer *, int,
-                     size_t);
-void   recswvol_func8(struct audio_softc *, struct audio_ringbuffer *, int,
-                      size_t);
-void   recswvol_func16(struct audio_softc *, struct audio_ringbuffer *, int,
-                       size_t);
-void   recswvol_func32(struct audio_softc *, struct audio_ringbuffer *, int,
-                       size_t);
+void   recswvol_func(struct audio_softc *, struct audio_ringbuffer *,
+                     size_t, struct virtual_channel *);
+void   recswvol_func8(struct audio_softc *, struct audio_ringbuffer *,
+                      size_t, struct virtual_channel *);
+void   recswvol_func16(struct audio_softc *, struct audio_ringbuffer *,
+                       size_t, struct virtual_channel *);
+void   recswvol_func32(struct audio_softc *, struct audio_ringbuffer *,
+                       size_t, struct virtual_channel *);
 void   saturate_func(struct audio_softc *);
 void   saturate_func8(struct audio_softc *);
 void   saturate_func16(struct audio_softc *);
 void   saturate_func32(struct audio_softc *);
-void   mix_func(struct audio_softc *, struct audio_ringbuffer *, int);
-void   mix_func8(struct audio_softc *, struct audio_ringbuffer *, int);
-void   mix_func16(struct audio_softc *, struct audio_ringbuffer *, int);
-void   mix_func32(struct audio_softc *, struct audio_ringbuffer *, int);
+void   mix_func(struct audio_softc *, struct audio_ringbuffer *,
+                struct virtual_channel *);
+void   mix_func8(struct audio_softc *, struct audio_ringbuffer *,
+                struct virtual_channel *);
+void   mix_func16(struct audio_softc *, struct audio_ringbuffer *,
+                struct virtual_channel *);
+void   mix_func32(struct audio_softc *, struct audio_ringbuffer *,
+                struct virtual_channel *);
 void   mix_write(void *);
 void   mix_read(void *);
 int    audio_check_params(struct audio_params *);
 
-void   audio_calc_blksize(struct audio_softc *, int, int);
+void   audio_calc_blksize(struct audio_softc *, int, struct virtual_channel *);
 void   audio_fill_silence(struct audio_params *, uint8_t *, int);
 int    audio_silence_copyout(struct audio_softc *, int, struct uio *);
 
 void   audio_init_ringbuffer(struct audio_softc *,
                              struct audio_ringbuffer *, int);
-int    audio_initbufs(struct audio_softc *, int);
-void   audio_calcwater(struct audio_softc *, int);
-int    audio_drain(struct audio_softc *, int);
-void   audio_clear(struct audio_softc *, int);
-void   audio_clear_intr_unlocked(struct audio_softc *sc, int);
+int    audio_initbufs(struct audio_softc *, struct virtual_channel *);
+void   audio_calcwater(struct audio_softc *, struct virtual_channel *);
+int    audio_drain(struct audio_softc *, struct audio_chan *);
+void   audio_clear(struct audio_softc *, struct virtual_channel *);
+void   audio_clear_intr_unlocked(struct audio_softc *sc,
+                                 struct virtual_channel *);
 static inline void
        audio_pint_silence(struct audio_softc *, struct audio_ringbuffer *,
-                          uint8_t *, int, int);
+                          uint8_t *, int, struct virtual_channel *);
 int    audio_alloc_ring(struct audio_softc *, struct audio_ringbuffer *, int,
                         size_t);
 void   audio_free_ring(struct audio_softc *, struct audio_ringbuffer *);
 static int audio_setup_pfilters(struct audio_softc *, const audio_params_t *,
-                               stream_filter_list_t *, int);
+                             stream_filter_list_t *, struct virtual_channel *);
 static int audio_setup_rfilters(struct audio_softc *, const audio_params_t *,
-                               stream_filter_list_t *, int);
+                             stream_filter_list_t *, struct virtual_channel *);
 static void audio_stream_dtor(audio_stream_t *);
 static int audio_stream_ctor(audio_stream_t *, const audio_params_t *, int);
-static void stream_filter_list_append
-       (stream_filter_list_t *, stream_filter_factory_t,
-        const audio_params_t *);
-static void stream_filter_list_prepend
-       (stream_filter_list_t *, stream_filter_factory_t,
-        const audio_params_t *);
-static void stream_filter_list_set
-       (stream_filter_list_t *, int, stream_filter_factory_t,
-        const audio_params_t *);
-int    audio_set_defaults(struct audio_softc *, u_int, int);
+static void stream_filter_list_append(stream_filter_list_t *,
+               stream_filter_factory_t, const audio_params_t *);
+static void stream_filter_list_prepend(stream_filter_list_t *,
+               stream_filter_factory_t, const audio_params_t *);
+static void stream_filter_list_set(stream_filter_list_t *, int,
+               stream_filter_factory_t, const audio_params_t *);
+int    audio_set_defaults(struct audio_softc *, u_int,
+                                               struct virtual_channel *);
 static int audio_sysctl_frequency(SYSCTLFN_PROTO);
 static int audio_sysctl_precision(SYSCTLFN_PROTO);
 static int audio_sysctl_channels(SYSCTLFN_PROTO);
@@ -321,8 +341,14 @@
 static void    audio_exit(struct audio_softc *);
 static int     audio_waitio(struct audio_softc *, kcondvar_t *);
 
-#define AUDIO_OUTPUT_CLASS 0
-#define AUDIO_INPUT_CLASS 1
+int audioclose(struct file *);
+int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+int audioioctl(struct file *, u_long, void *);
+int audiopoll(struct file *, int);
+int audiofcntl(struct file *, u_int, void *);
+int audiokqfilter(struct file *, struct knote *);
+int audiostat(struct file *, struct stat *);
 
 struct portname {
        const char *name;
@@ -355,13 +381,14 @@
        audio_set_port(struct audio_softc *, mixer_ctrl_t *);
 static int
        audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
-static int audio_set_params
-       (struct audio_softc *, int, int, audio_params_t *, audio_params_t *,
-        stream_filter_list_t *, stream_filter_list_t *, int);
+static int audio_set_params (struct audio_softc *, int, int,
+                audio_params_t *, audio_params_t *,
+                stream_filter_list_t *, stream_filter_list_t *,



Home | Main Index | Thread Index | Old Index