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/01c4df669dc9
branches: trunk
changeset: 351358:01c4df669dc9
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 452dd47c7fd0 -r 01c4df669dc9 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 452dd47c7fd0 -r 01c4df669dc9 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