summaryrefslogtreecommitdiff
path: root/sys/dev/audio.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2013-11-28 00:38:51 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2013-11-28 00:38:51 +0000
commit12c7a721922238cd7d03281d05dec1cf50d3f75f (patch)
treeac2ac64abe44f457222450b6603691125dd9c74d /sys/dev/audio.c
parentfdc53973487e278c0c9df5e394c5b0044245ce63 (diff)
the stuff in audiovar.h is only used in audio.c, so move it in there to
take the temptation of using it elsewhere and fumbling with audio internals away from the rest of the kernel. ok mpi@ ratchov@ "if it is worth doing, just do it." deraadt@
Diffstat (limited to 'sys/dev/audio.c')
-rw-r--r--sys/dev/audio.c123
1 files changed, 121 insertions, 2 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c
index 7c41df8cdaa..7f9aa09383f 100644
--- a/sys/dev/audio.c
+++ b/sys/dev/audio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: audio.c,v 1.117 2013/11/04 11:57:26 mpi Exp $ */
+/* $OpenBSD: audio.c,v 1.118 2013/11/28 00:38:50 dlg Exp $ */
/* $NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss Exp $ */
/*
@@ -52,7 +52,6 @@
#include <sys/task.h>
#include <dev/audio_if.h>
-#include <dev/audiovar.h>
#include <dev/rndvar.h>
@@ -71,6 +70,126 @@ int audiodebug = 0;
#define ROUNDSIZE(x) x &= -16 /* round to nice boundary */
+/*
+ * Initial/default block duration is both configurable and patchable.
+ */
+#ifndef AUDIO_BLK_MS
+#define AUDIO_BLK_MS 50 /* 50 ms */
+#endif
+
+#ifndef AU_RING_SIZE
+#define AU_RING_SIZE 65536
+#endif
+
+#define AUMINBUF 512
+#define AUMINBLK 32
+#define AUMINNOBLK 2
+struct audio_ringbuffer {
+ int bufsize; /* allocated memory */
+ int blksize; /* I/O block size */
+ int maxblks; /* no of blocks in ring */
+ u_char *start; /* start of buffer area */
+ u_char *end; /* end of buffer area */
+ u_char *inp; /* input pointer (to buffer) */
+ u_char *outp; /* output pointer (from buffer) */
+ int used; /* no of used bytes */
+ int usedlow; /* start writer when used falls below this */
+ int usedhigh; /* stop writer when used goes above this */
+ u_long stamp; /* bytes transferred */
+ u_long stamp_last; /* old value of bytes transferred */
+ u_long drops; /* missed samples from over/underrun */
+ u_long pdrops; /* paused samples */
+ char pause; /* transfer is paused */
+ char mmapped; /* device is mmap()-ed */
+ u_char blkset; /* blksize has been set, for stickiness */
+};
+
+#define AUDIO_N_PORTS 4
+
+struct au_mixer_ports {
+ int index;
+ int master;
+ int nports;
+ u_char isenum;
+ u_int allports;
+ u_int aumask[AUDIO_N_PORTS];
+ u_int misel [AUDIO_N_PORTS];
+ u_int miport[AUDIO_N_PORTS];
+};
+
+/*
+ * Software state, per audio device.
+ */
+struct audio_softc {
+ struct device dev;
+ void *hw_hdl; /* Hardware driver handle */
+ struct audio_hw_if *hw_if; /* Hardware interface */
+ struct device *sc_dev; /* Hardware device struct */
+ u_char sc_open; /* single use device */
+#define AUOPEN_READ 0x01
+#define AUOPEN_WRITE 0x02
+ u_char sc_mode; /* bitmask for RECORD/PLAY */
+
+ struct selinfo sc_wsel; /* write selector */
+ struct selinfo sc_rsel; /* read selector */
+ struct proc *sc_async_audio; /* process who wants audio SIGIO */
+ struct mixer_asyncs {
+ struct mixer_asyncs *next;
+ struct proc *proc;
+ } *sc_async_mixer; /* processes who want mixer SIGIO */
+
+ /* Sleep channels for reading and writing. */
+ int sc_rchan;
+ int sc_wchan;
+
+ /* Ring buffers, separate for record and play. */
+ struct audio_ringbuffer sc_rr; /* Record ring */
+ struct audio_ringbuffer sc_pr; /* Play ring */
+
+ u_char *sc_sil_start; /* start of silence in buffer */
+ int sc_sil_count; /* # of silence bytes */
+
+ u_char sc_rbus; /* input dma in progress */
+ u_char sc_pbus; /* output dma in progress */
+
+ u_char sc_rqui; /* input dma quiesced */
+ u_char sc_pqui; /* output dma quiesced */
+
+ struct audio_params sc_pparams; /* play encoding parameters */
+ struct audio_params sc_rparams; /* record encoding parameters */
+
+ int sc_eof; /* EOF, i.e. zero sized write, counter */
+ u_long sc_wstamp;
+ u_long sc_playdrop;
+
+ int sc_full_duplex; /* device in full duplex mode */
+
+ struct au_mixer_ports sc_inports, sc_outports;
+ int sc_monitor_port;
+
+ int sc_refcnt;
+ int sc_dying;
+
+ int sc_quiesce;
+#define AUDIO_QUIESCE_START 1
+#define AUDIO_QUIESCE_SILENT 2
+ struct timeout sc_resume_to;
+ struct task sc_resume_task;
+ struct task sc_mixer_task;
+ u_char sc_mute;
+
+#ifdef AUDIO_INTR_TIME
+ u_long sc_pfirstintr; /* first time we saw a play interrupt */
+ int sc_pnintr; /* number of interrupts */
+ u_long sc_plastintr; /* last time we saw a play interrupt */
+ long sc_pblktime; /* nominal time between interrupts */
+ u_long sc_rfirstintr; /* first time we saw a rec interrupt */
+ int sc_rnintr; /* number of interrupts */
+ u_long sc_rlastintr; /* last time we saw a rec interrupt */
+ long sc_rblktime; /* nominal time between interrupts */
+#endif
+};
+
int audio_blk_ms = AUDIO_BLK_MS;
int audiosetinfo(struct audio_softc *, struct audio_info *);