summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/i386/isa/snd/doc/Makefile40
-rw-r--r--sys/i386/isa/snd/doc/sound.ps.gzbin45365 -> 0 bytes
-rw-r--r--sys/i386/isa/snd/doc/sound.tex917
-rw-r--r--sys/i386/isa/snd/misc/README82
-rw-r--r--sys/i386/isa/snd/misc/audio-voxware.cc435
-rw-r--r--sys/i386/isa/snd/misc/auvoxware.c1301
-rw-r--r--sys/i386/isa/snd/misc/files.i386240
-rw-r--r--sys/i386/isa/snd/misc/linux.patch41
-rw-r--r--sys/i386/isa/snd/misc/linux_a.c238
-rw-r--r--sys/i386/isa/snd/misc/mmap_test.c278
-rw-r--r--sys/i386/isa/snd/misc/pcmio.c236
-rw-r--r--sys/i386/isa/snd/misc/soundbyte.c275
-rw-r--r--sys/i386/isa/snd/misc/test.c84
13 files changed, 0 insertions, 4167 deletions
diff --git a/sys/i386/isa/snd/doc/Makefile b/sys/i386/isa/snd/doc/Makefile
deleted file mode 100644
index 355a77f..0000000
--- a/sys/i386/isa/snd/doc/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-# Makefile for the sound documentation
-
-ARTICLE=sound
-INPUTS=
-STYLES=
-.SUFFIXES: .fig .ps
-OTHERSTUFF=
-FIGURES=
-PSS=
-ALLFIG= $(FIGURES)
-COMPAT= psfigps.tex
-
-ALLPS= $(ALLFIG:.fig=.ps)
-
-ALLSRCS= $(ARTICLE).tex $(STYLES) $(ALLFIG) $(PSS) $(INPUTS) \
- $(COMPAT) $(OTHERSTUFF) Makefile
-
-.fig.ps:
- fig2dev -L ps -m 0.5 $*.fig > $*.ps
-
-all: $(ARTICLE).dvi pnp.dvi ioctl.dvi Makefile
-
-$(ARTICLE).dvi: allfig $(ARTICLE).tex $(INPUTS) $(STYLES) $(PSS)
- latex $(ARTICLE).tex
-
-pnp.dvi: allfig pnp.tex $(INPUTS) $(STYLES) $(PSS)
- latex pnp.tex
-
-ioctl.dvi: allfig pnp.tex $(INPUTS) $(STYLES) $(PSS)
- latex ioctl.tex
-
-allfig: $(ALLPS)
-
-clean:
- rm -f $(ALLPS) a c *.dvi *.aux *.log rl
-
-tgz: $(ALLSRCS)
- tar cvf - $(ALLSRCS) | gzip -9 > $(ARTICLE).tgz
-
-
diff --git a/sys/i386/isa/snd/doc/sound.ps.gz b/sys/i386/isa/snd/doc/sound.ps.gz
deleted file mode 100644
index 12beb0a..0000000
--- a/sys/i386/isa/snd/doc/sound.ps.gz
+++ /dev/null
Binary files differ
diff --git a/sys/i386/isa/snd/doc/sound.tex b/sys/i386/isa/snd/doc/sound.tex
deleted file mode 100644
index d8e7059..0000000
--- a/sys/i386/isa/snd/doc/sound.tex
+++ /dev/null
@@ -1,917 +0,0 @@
-\documentclass[11pt]{article}
-
-\textwidth 6in
-\textheight 9in
-\oddsidemargin 0in
-\evensidemargin 0in
-\topmargin 0in
-
-% \input{psfigps.tex}
-
-\begin{document}
-\author{Luigi Rizzo\\
- Dipartimento di Ingegneria dell'Informazione -- Universit\`a di Pisa\\
- via Diotisalvi 2 -- 56126 Pisa (Italy)\\
- email: {\tt l.rizzo@iet.unipi.it}}
-\title{The FreeBSD audio driver}
-\maketitle
-
-\begin{abstract}
-In this paper we describe the architecture of the new FreeBSD audio
-driver. We also give detailed information on the internal data
-structures used by the driver, and examples on how to add support
-for new devices.
-
-{\bf WARNING:} since the code is rapidly evolving, there might be some
-minor differences between this paper and the source code. In doubt,
-the source code is the ultimate reference.
-
-\end{abstract}
-
-\section{Introduction}
-
-The audio driver is the part of the kernel which handles audio-related
-peripherals. In FreeBSD, historically, there has been not much support
-for these devices. The original FreeBSD audio driver has been based on
-the Voxware 3.0 release, originally developed for Linux and ported to
-FreeBSD at 1.1 times. The driver in the source tree has been
-essentially unsupported since then.
-
-In parallel, some volunteers have been using a driver derived from
-Voxware 3.5, which had support for full-duplex audio cards which have
-become popular in more recent times.
-
-Both versions of the Voxware code are extremely complex and not very
-much in line with BSD device drivers. There are several motivations
-for that, the main one (we believe) was that the code has evolved
-through the years to support a number of boards which are sufficiently
-similar to suggest not to write a completely different driver, and
-sufficiently different to require the addition of state variables, new
-support routines, and feature enahncements, to the existing driver.
-The unfortunate result of this evolution was that the code in our hand
-was extremely difficult to configure, follow, and in many cases unable to
-support multiple devices. Furthermore, the complexity of the code,
-prevented proper support for it.
-
-The desire for a functional audio driver for FreeBSD, together with
-the lack of support for the code currently in the source tree, and
-its complexity of the original driver, were for us sufficient
-motivations to start a large rewrite of the code.
-
-From a user's point of view, we were especially concerned with the
-complexity of the configuration process, which, to be done properly,
-required a number of different devices to be compiled into the kernel,
-with (at times) subtle dependencies among the modules and the options
-to be used. So, one of our goal was to simplify the configuration
-process, a goal which we believe to have achieved.
-
-From the kernel developer's point of view, the Voxware driver was hard
-to understand for two reasons. First, its structure was not much in
-line with BSD driver. This obviously derives from the original
-development on a different system. The second reason is the evolution
-of the driver during time, which, we believe, has degraded the quality of
-the code from a carefully designed original version.
-
-We have started our work basing on Voxware 3.5. The Voxware code
-served mainly as a reference on what the features of the various
-boards were, and how problems had been dealt with. Our code
-then evolved into a fairly complete rewrite of the main modules,
-including the main configuration mechanisms, the DMA support
-routines, and, in many cases, also the board-specific drivers which
-could make use of many of the simplifications we have introduced.
-
-\section{What the audio driver does}
-
-The audio driver is intended to control all peripherals related to
-audio handling. This includes digital audio sampling and generation
-({\tt pcm}), communication with MIDI devices ({\tt midi}) and the
-synthesizers ({\tt synth}) which several audio cards provide. In
-addition to these devices, which have explicit entries in the kernel
-configuration file, audio cards generally provide a {\em mixer}
-device, which controls audio paths within the board.
-Our devices currently has only support for {\tt pcm} and mixer
-devices.
-
-\subsection{The {\tt pcm} device}
-
-The {\tt pcm} device is in charge of the audio sampling and
-generation. Such device is generally implemented by a CODEC, a piece
-of hardware containing one or two A/D and D/A converters. Depending on
-the board, the minimum and maximum sampling rate, the number of bits
-per sample, and the data format (e.g. the availability of compressed
-audio formats) varies. At a minimum, all boards seem to be capable of
-sampling mono audio with 8-bit unsigned values and 8 KHz resolutions.
-Most boards (especially the Windows-Sound-System ones, known as WSS or
-MSS) are also capable of full duplex stereo with 16-bit and 44.1KHz
-sampling rate (corresponding to CD-quality).
-
-The {\tt pcm} device implements the {\tt ioctl()} calls to select the
-desired data format, and {\tt read()} and {\tt write()} functions to
-allow a smooth exchange of data with the codec, and {\tt select()} to
-notify the application when I/O is possible.
-
-
-\subsection{The mixer}
-
-The mixer controls audio data paths, i.e. which sources are directed
-to the ADC input, which ones are directed to the audio output, and the
-attenuation on the various channels. There is a wide variety of
-features in this subsystem, as some boards do provide only on-off
-control on a limited number of sources, whereas some boards provide
-many sources and fine-grained volume controls.
-
-We believe that a sufficiently general model of the {\tt mixer}
-is one actually using {\em two} mixers, one to connect sources to the
-ADC part of the codec, and one to connect sources to the physical
-output (usually the speakers). Some early boards often implement the
-mixer leading to the ADC only as a multiplexer with one active line,
-but that can be modeled by thinking of a very coarse (1 bit) volume
-control, and a restriction on the volumes on the various sources.
-
-
-\section{Kernel Configuration}
-
-The configuration of the driver is done through the following
-statements included in the system configuration file:
-\begin{verbatim}
-device pcm0 at isa? port? tty irq N drq D flags F vector pcmintr
-\end{verbatim}
-The {\tt device pcm0} statement is in charge of bringing into the
-kernel all modules related to audio support.
-
-The main audio subsystem is configured by using the {\tt device
-pcm0} statement. This line supplies the main parameters related to the
-configuration of a single sound card, which are:
-\begin{itemize}
-\item {\bf port} the I/O address for the codec (and generally mixer)
- subsystem. If no address is supplied, the driver looks at
- different addresses for the most common boards.
-\item {\bf irq} the interrupt line used by the board.
-\item {\bf drq} the first DMA channel used by the board. Modern
- sound boards supporting full-duplex can use two DMA channels,
- so we use the {\tt flags} field to specify the second channel.
-\item {\bf flags} used to specify the second DMA channel, the device
- type (overriding the autoconfiguration mechanism), and
- other information.
- In particular, the flags have the following use:\\
- \begin{center}
- \begin{tabular}{|c|l|}
- \hline Bits & Meaning \\
- \hline \hline
- 2..0 & secondary (read) DMA channel for dual-dma boards. \\
- \hline
- 4 & Enable secondary dma channel \\
- \hline
- 15..8 & Specific device type/class. 0 means autoconfigure\\
- \hline
- \end{tabular}
- \end{center}
-\end{itemize}
-A sound board often has more than the codec, and uses more than one
-I/O address block. Since the {\tt device} line in the config file
-does not permit to
-specify more than one address (except, perhaps, by abusing the {\tt
-flags} field, which we have already used though), we will
-use two additional {\tt device} entries to specify the i/o address
-for the MIDI ({\tt midi}) and Synthesizer ({\tt synth}) devices,
-respectively. These entries do not correspond to actual devices
-recognized by the kernel (in the sense that their probe routine will
-always fail, and their attach routine will do nothing and will never
-be called); rather, the parameters specified in these lines are used
-to extend the description of the board provided by the {\tt device
-pcmX} line.
-There is no support at the moment for {\tt midi} and {\tt synth}
-devices.
-
-\subsection{Plug and Play support}
-
-As a side effect of our work on the audio driver, we have implemented
-support for Plug and Play (PnP) device configuration. This was a
-necessity since many modern audio boards are configured through
-PnP. PnP support is described in a separate document.
-
-In order to support PnP boards, one device entry is still necessary
-(i.e. {\tt pcm0}), to let the
-configure program include all the necessary parameters. The entry must
-include all fields, e.g.
-\begin{verbatim}
-device pcm0 at isa? port? tty irq 7 drq 1 vector pcmintr
-\end{verbatim}
-although
-the actual configuration of PnP devices (i.e. port addresses, IRQ,
-DMA, etc. will be auto detected, and unit numbers will be assigned
-starting from the next free one (e.g. {\tt pcm1, pcm2, ...}).
-
-\section{Code structure}
-
-The following table details the various file which make up the code.
-All files reside in the directory {\tt /sys/i386/isa/snd} .
-
-\begin{center}
-\begin{tabular}{|l|p{4in}|}
-\hline
-File Name & Description \\
-\hline \hline
-{\tt sound.c} & main device routines and autoconfiguration.\\
-\hline
-{\tt sound.h} & generic header for all kernel files.\\
-\hline
-{\tt soundcard.h} & generic header for all userland sound apps.\\
-\hline
-{\tt dmabuf.c} & DMA support. \\
-\hline
-{\tt sb\_dsp.c} & SoundBlaster driver \\
-\hline
-{\tt ad1848.c} & MSS-compatible driver \\
-\hline
-{\tt clones.c} & Miscellaneous code to enable SB/MSS emulation in
- various boards. \\
-\hline
-\end{tabular}
-\end{center}
-
-\subsection{The {\tt snddev\_info} structure}
-
-Each known board is fully described by a {\tt snddev\_info}
-structure. The structure contains information of use at initialization
-time (such as board type, name, probe and attach routines), and at
-runtime. The latter include all board-specific functions, and the
-generic status information about the board when in use.
-
-{\tt snddev\_info} is made of two parts, the first one which is
-generally initialized from a template which univoquely identifies the
-board, the second one which contains run-time parameters. The first part
-of the structure is:
-
-\begin{verbatim}
-typedef struct _snddev_info snddev_info ;
-struct _snddev_info {
- char name[64];
- int type ; /* board type/class, search key during probes */
- int (*probe)(struct isa_device * dev);
- int (*attach)(struct isa_device * dev) ;
- d_open_t *open ;
- d_close_t *close ;
- d_read_t *read ;
- d_write_t *write ;
- d_ioctl_t *ioctl ;
- d_select_t *select ;
- irq_proc_t *isr ;
- snd_callback_t *callback;
-
- int bufsize; /* DMA buffer size */
- u_long audio_fmt ; /* bitmap of supported audio formats */
-\end{verbatim}
-where the names of the fields clearly identify the functions.
-Board-specific code generally supplies, in the template, initializers
-for all the above fields. At attach time, and before calling the
-board-specific attach routines, the descriptor associated with the
-device, {\tt pcm\_info[dev->id\_unit]} is bzeroed, initialized with
-the template, then the fields in the second part of the structure
-(shown next) are initialized with default values (partly taken from
-the device config line, as in the case of i/o, irq and dma addresses),
-and the required buffers are allocated.
-
-\begin{verbatim}
- int io_base, alt_base, conf_base,
- mix_base, midi_base, synth_base;
-
- int bd_id; /* board-specific id */
- snd_dbuf dbuf_out, dbuf_in;
- int status_len, status_ptr ; /* to implement sndstat */
-
- volatile u_long flags; /* generic flags */
-
- u_long bd_flags; /* board-specific flags */
- int play_speed, rec_speed;
-
- int play_blocksize, rec_blocksize;
- u_long play_fmt, rec_fmt ;
- u_long mix_devs, mix_rec_devs, mix_recsrc;
- u_short mix_levels[32];
-
- u_long interrupts;
- void *device_data;
-\end{verbatim}
-The structure provides all generic fields for audio support, plus a
-couple of board-specific fields, {\tt bd\_id} and {\tt bd\_flags}. The
-former should be used to distinguish different versions of the same
-device (e.g. major/minor id in case of the SoundBlaster, codec type
-for MSS-compatible boards, etc.), the latter can be used to hold
-board-specific flags. Should these info not be sufficient, room is
-provided for a pointer to device-specific data so that the structure
-can be extended at will.
-
-Note that the descriptor has room for several base addresses. One of
-this ({\tt io\_base}) is derived from the the kernel config line, and
-corresponds to the base address for codec access. The others can be
-derived using various mechanisms, e.g. hardwired info (some boards are
-known to have a given subsystem at a given address), additional lines
-in the config file, or PnP autoconfiguration info. These addresses are
-used to access the subsystems, and to check for conflicts during the
-configuration process.
-
-Of particular importance is the {\tt flags} fields, which holds many
-flags used to determine the status of the device. Among them:
-\begin{verbatim}
-#define SND_F_BUSY 0x0001 /* has been opened (for write) */
-#define SND_F_BUSY_AUDIO 0x10000000
-#define SND_F_BUSY_DSP 0x20000000
-#define SND_F_BUSY_DSP16 0x40000000
-\end{verbatim}
-These flags indicate the busy status of the board. They are of
-exclusive use of the device-specific {\tt open()} and {\tt close()}
-routines. The intended purpose is to allow only one or more opens
-on the device. For the way the kernel operates, when multiple
-descriptors are open on the same device (e.g. because the process
-{\tt fork()}'ed after opening the device), only the last {\tt
-close()} will result in the invokation of the device-specific close.
-But, since in the Voxware mode, a device is accessed using three
-minor numbers (corresponding to {\tt /dev/dsp, /dev/audio, /dev/dspW}),
-we have to keep track of opens issued on the different devices and
-only call the close routines on the very last close.
-
-\begin{verbatim}
-#define SND_F_READING 0x0004 /* have a pending read */
-#define SND_F_WRITING 0x0008 /* have a pending write */
-\end{verbatim}
-Allowing a single open does not suffice to exclude the possibility
-that a process forks and then multiple calls are issued concurrently.
-These two flags are used in the generic read/write routines to
-prevent concurrent calls of the same type, and serialize calls of
-different types for half-duplex devices. These two flags are
-generally used in the generic read/write code, and there should be
-no need to use them in the device-specific code, unless the read/write
-routines are reimplemented.
-
-\begin{verbatim}
-#define SND_F_CLOSING 0x0040 /* a pending close */
-#define SND_F_ABORTING 0x1000 /* a pending abort on write */
-\end{verbatim}
-These flags mark special conditions, which should be known to the
-DMA routines to shut down the device properly. The {\tt CLOSING} flags
-are generally set by a call to {\tt close()} so that DMA transfers are
-shut down at the end of the current operation. The {\tt ABORTING}
-flags are set in response to user breaks or special {\tt ioctl}'s
-such as {\tt PAUSE}, and cause immediate suspension of the output.
-
-\begin{verbatim}
-#define SND_F_STEREO 0x0100
-#define SND_F_XLAT8 0x0400 /* u-law <--> 8-bit unsigned */
-#define SND_F_XLAT16 0x0800 /* u-law <--> 16-bit signed */
-\end{verbatim}
-These are generic flags, marking the use of stereo audio and the
-need for special translations in order to support {\tt /dev/audio}
-on boards which do not have native $\mu$LAW support. In practice,
-the latter flags are only used for the SoundBlaster; furthermore,
-conversion between $\mu$LAW and 16-bit signed is currently not
-implemented (but required to implement full-duplex through {\tt
-/dev/audio} on the SB16).
-
-\begin{verbatim}
-#define SND_F_INIT 0x4000 /* changed parameters. need init */
-\end{verbatim}
-Finally, this flag marks the need for board reinitialization at the
-next convenient time. This is because some parameters (e.g. speed,
-channels, etc.) might be changed while an I/O operation is in progress
-(e.g. a previous write is being flushed), and the board can only be
-reprogrammed at the end of a transfer. This flag helps in supporting
-the functionality. In the generic {\tt ioctl} handler, as an example,
-all calls which set a parameter update the descriptor, set the flag,
-and then invoke the callback function to apply the change. If successful,
-the flag will be cleared, otherwise it will stay set for the update to
-take place at the next convenient time.
-
-\subsection{Autoconfiguration}
-
-The main component of the driver is the file {\tt sound.c} which
-contains the autoconfiguration stuff and the main device routines.
-
-The configuration process occurs as follows (see the following
-diagram).
-
-\begin{verbatim}
-pcmprobe(dev) {
- foreach (p in supported devices)
- if (p->probe(dev) is successful) {
- snddev_last_probed = p ;
- return 1 ;
- }
- return 0 ; /* fail */
-}
-
-pcmattach(dev) {
- initialize pcm_info[dev->id_unit] with data from the template,
- from snddev_last_probed, and from dev;
- call snddev_last_probed->attach(dev);
-}
-
-xxx_probe(dev) {
- try to identify the board, possibly updating dev; can use
- pcm_info[dev->id_unit] as temporary storage (reset on exit);
- return 1 on success, 0 on failure.
-}
-
-xxx_attach(dev) {
- initialize board and do the necessary allocation, complete the
- info in pcm_info[dev->id_unit] (initialized from the template
- and dev)
-}
-\end{verbatim}
-The kernel invokes {\tt pcmprobe()} to detect a board, passing it
-the parameters from the configuration line. The routine then scans
-the set of supported devices to see if the device is compatible
-with the configured unit, and in case invokes the probe routine,
-which is passed a pointer to the {\tt isa\_device} structure
-describing the device.
-
-Compatibility is checked using the following rules. If a device
-type is specified, only that device is checked for. If the ``device
-type'' refers to a class of devices (e.g. all SoundBlaster-like
-boards, all MSS-like boards), then all known devices in that class
-are probed. Finally, if no device type is specified, then all
-devices are probed. Internally, a {\tt snddev\_info} structure is
-defined for each known board. For each board class, an array holds
-pointers to the descriptors of each board. Finally, an array holds
-pointers to the arrays describing each board class.
-
-The probe routine is not supposed to do any resource allocation,
-just to check for the presence of the board. The only allowed side
-effect of the probe routine is to modify the content of the {\tt
-isa\_device} structure, in case a generic parameter was passed, to
-instantiate it to the correct value. If the board-specific probe
-routine is successful, so is {\tt pcmprobe()}. This will result in
-the invokation of {\tt pcmattach()}, with a pointer to the same
-{\tt isa\_device} structure that was used at probe time.
-
-{\tt pcmattach()} will now copy the {\tt snddev\_info} structure
-describing the successfully-probed device into a permanent device
-descriptor, fill it up with run-time information, and call the
-board-specific attach routine. All the above is only possible
-because {\tt pcmprobe()} saves a pointer ({\tt last\_probed}) to
-the {\tt snddev\_info} corresponding to the successfully probed
-device before returning.
-
-The board-specific attach routines has the task of configuring the
-boards using the supplied parameters. The only parameter passed
-to the attach routine is the {\tt isa\_device} pointer. This
-structure includes the unit number, so the board-specific can
-identify the permanent device descriptor as {\tt pcm\_info[unit]}
-(use {\tt midi\_info}, {\tt synth\_info} for other devices).
-
-Although the return type is {\tt int}, the return value from the
-board-specific attach routine is not checked, similarly to what is
-done for the generic ISA attach routines. The only action that the
-kernel does on a successful attach is to register an interrupt for
-the device. As a consequence, a failed attach can be marked by
-setting {\tt dev->id\_irq = 0 ;} which has the consequence of not
-registering an interrupt for the device.
-
-\subsection{Main device routines}
-
-Upon a successful attach, {\tt pcmattach()} registers a {\tt cdevsw}
-entry for the audio device. All audio devices share the same routines,
-{\tt sndopen, sndclose, sndread, sndwrite, sndioctl, sndselect},
-which perform some generic actions and then invoke the board-specific
-routines, if available. The board-specific routines, as well as
-the probe and attach routines, have the same interface of a BSD
-device driver. This was a design choice meant to simplify development:
-one can, in principle, develop a driver outside the audio driver,
-and then move it under the audio driver with minimal effort.
-Additionally, this approach simplifies life to a kernel developer
-since there are no new interfaces to be learned.
-
-\subsubsection{{\tt sndopen()} and {\tt sndclose()} }
-
-The generic open and close routines do very little, they basically
-check that the unit and device number correspond to a supported
-device, and then invoke the (required) open/close routines for
-the specific board. There is little more the generic routines can
-do, since board vary widely and the open and close actions are very
-board-specific.
-
-\subsubsection{{\tt sndread()} and {\tt sndwrite()} }
-
-On the contrary, the generic read and write actions are very similar
-across all boards. In all cases, checks must be done for valid unit
-and device numbers. Then, concurrent operations of the same type
-must be denied. Finally, operations of different types on half-duplex
-devices must be properly sequenced. After these checks have been
-done, the generic read/write code requires to move data between the
-user buffer and the DMA buffer, in blocks of appropriate size.
-
-\subsection{{\tt sndioctl()}}
-
-The audio driver uses a very large number of {\tt ioctl}'s. Many
-of these simply require to read, or set, parameters in the device
-descriptor, so they can be implemented by the generic routine for
-all boards. Other ioctl calls, instead, require board-specific
-actions. We have devised a mechanism to allow board-specific ioctl
-to handle the desired set of ioctl calls, leaving the generic
-routine the task to deal with other, unhandled, calls.
-
-The generic routine, after checking device and unit numbers, passes
-control to the board-specific routine, if existing. This can do its
-own processing and return the error status. If the return value is
-{\tt ENOSYS} (error number 78, ``Function not implemented''), then
-the generic ioctl {\tt switch} statement is invoked which performs
-the generic actions.
-
-The generic routine tries to implement as much as possible of the
-sound calls, leaving little processing to the user code. In
-particular, it is assumed that all calls which just read the status
-of the device can fetch it directly from the audio descriptor.
-Updates to the parameters are done in the generic ioctl by setting
-the parameter in the descriptor (when possible, by checking that
-values are acceptable), setting the {\tt SND\_F\_INIT} flag and
-calling the device-specific {\tt callback()} function, if available.
-This in turn will try to perform the necessary action or, if not
-possible, leave the flag set for later operation.
-
-
-\subsection{{\tt sndselect()}}
-
-A properly working select routine is fundamental for a audio device,
-because often an application has to handle multiple data streams.
-While it is true that an application can determine how long
-a read or write call will take to complete, knowing buffer sizes and
-sample rates, it is certainly more convenient and efficient to have a
-working {\tt select()}. The generic select routine should cover all
-needs for devices using DMA. The body of the routine is very
-standard. The only noticeable thing is that, when the user specified a
-preferred block size through one of the available {\tt ioctl()} calls,
-then {\tt select()} will return only when at least one whole block
-can be transferred. In other cases (default) one byte will suffice to
-make {\tt select()} return (although the system will still choose a blocksize
-for DMA transfers, corresponding to 0.25~s of data).
-
-\subsection{{\tt /dev/sndstat}}
-
-In the Voxware driver, a special, readonly, status device ({\tt
-/dev/sndstat}) was defined (minor number 6) which returned information
-on the audio system, including supported devices and configured
-devices. In our code, {\tt /dev/sndstat} is supported directly in
-the generic routines (in file {\tt sound.c}) and is defined for
-every unit returning the same information. In particular, the
-status device returns data from a statically allocated 4~KB buffer
-({\tt status\_buf}) which is filled-up at the first open with the
-function {\tt init\_status()}.
-
-\section{DMA support}
-
-DMA handling routines are an important module of the audio code.
-All the DMA-related code is in file {\tt dmabuf.c} and is completely
-new for this release.
-
-At the time of this writing, DMA support does not use AUTOMODE.
-
-Using DMA mode, the sound card requests the transfer of data by
-issuing DMA requests to the ISA DMA controller, which in turn
-satisfies the request. The ISA DMA controller can be programmed with a
-count, so that a signal (TC) is generated after the required amount of data
-has been transferred. In ``AUTO'' mode, the ISA DMA controller
-reinitializes itself at the end of the transfer. Otherwise, requests
-are not served anymore until the controller is reprogrammed.
-
-In principle, the codec could just forward the TC signal to the
-appropriate interrupt line when enabled for DMA transfers. However,
-many codec usually have a DMA count register themselves, and generate
-an interrupt after the programmed number of bytes is transferred,
-in many cases without looking at the value of TC. This makes it
-possible to program the ISA DMA controller to use a large buffer,
-while letting the codec generate interrupts on smaller (and perhaps
-variable size) blocks.
-
-There are several problems to be dealt with by the DMA code in the
-audio driver. First, and most important, we need to avoid overruns
-or underruns in transferring data from/to the audio board. This is
-more important for (old) boards which do not have a properly sized
-on-board FIFO. The second problem is to minimize the latency in
-all i/o functions, something which is especially important for
-full-duplex applications.
-
-In the Voxware code, the DMA routines used a buffer partitioned into
-a number of fixed-size fragments. The programmer should use ioctls to
-select the fragment size which was best suited to his needs,
-generally in terms of latency.
-
-In our code, we use a completely different approach. The DMA buffer
-is a single memory block divided into two, variable-size, areas:
-{\em READY} and {\em FREE}. Each area is identified by an
-offset into the buffer and a length. The data structure describing a
-DMA buffer is the following:
-\begin{verbatim}
-typedef struct _snd_dbuf {
- char *buf; /* pointer to the data buffer */
- int bufsize ; /* total buffer size */
- volatile int rp, fp; /* pointers to the ready and free area */
- volatile int dl; /* transfer size */
- volatile int rl, fl; /* length of ready and free areas. */
- int int_count; /* how many interrupts on this channel */
- int chan; /* dma channel */
- int sample_size ; /* 1, 2, 4 */
- struct selinfo sel; /* support for select */
- u_long total; /* total bytes processed */
- u_long prev_total; /* copy of the above when GETxPTR called */
-} snd_dbuf ;
-\end{verbatim}
-The READY area contains
-data ready to be transferred to the codec or to the user, depending
-on the direction of the transfer. The FREE area is empty and
-available for use. Both READY and FREE can wrap through the end of
-the buffer. When the dma engine is in use, it transfers {\tt dl} bytes
-from the beginning of the READY area (play) or to the beginning of the
-FREE area (record).
-
-The status of a dma transfer can in many cases be detected from the
-value of the length components of the structures. If {\tt dl == 0},
-then the DMA engine is not active. If {\em fl == 0}, a user write will
-be blocking or a new DMA read cannot be started.
-If {\em rl == 0}, a user read will be blocking, or a new DMA write
-cannot be started. A idle dma descriptor has {\tt dl = rl = 0, fl
-= bufsize}.
-
-\subsection{Handling block sizes}
-
-The purpose of the subdivision of buffers in three areas is that we
-can have one pending DMA operation using the DMA area, some space for
-the next DMA operation (the READY area for a write, the FREE area for
-a READ), and a pending read or write on the third area.
-
-Obviously we should avoid each of these areas to become too large and
-eat all the available buffer space, or too small and make operations
-inefficient. We will analize the details in the following two
-sections.
-
-\subsection{DMA write}
-
-In write operations, the boundary between READY and FREE is advanced
-to make room for user data. When possible, a DMA operation is
-started by advancing the boundary between DMA and READY by the
-amount of data which must be transferred. At the end of the DMA
-transfer, the DMA area is shrunk to zero length by extending the
-FREE area. These actions occur in the user write routine {\tt
-dsp\_write\_body()}, and in the write interrupt service routine
-{\tt dsp\_wrintr()}.
-
-By using a straightforward implementation, the time required for the
-user write routine to make data available to the DMA engine would be
-proportional to the block size used in the write operation. This is
-mainly because of the use of the {\tt uiomove} function in the
-routine, possibly followed by a format conversion for translating
-between $\mu$-LAW and the native format supported by the codec.
-In order to minimize this latency, we do the transfer in blocks of
-increasing size, doubling it at each pass. This gives us very low
-latency, while at the same time enables the use of large blocks when
-needed, without requesting the user to specify a block size.
-
-
-\subsection{DMA read}
-
-In read operations, a DMA operation needs to be started first, by
-advancing the boundary between DMA and FREE by the amount of required
-data. When the DMA transfer is complete, the boundary between READY
-and DMA is advanced. User reads can be served by removing data from
-the READY area and advancing the boundary between FREE and READY
-accordingly. These actions occur in the user read routine {\tt
-dsp\_read\_body()} and in the read interrupt service routine {\tt
-dsp\_rdintr()}.
-
-Even for DMA read, we move data to user space in blocks of increasing
-size, so as to minimize latency in freeing space in the buffer.
-However, implementing the read poses another difficulty in deciding
-when to return data to a requesting application. Typically,
-a read request should return when the requested number of bytes is
-available. If data are already available, we can simply copy them
-and return. If no data is available and the DMA is inactive, we
-can start it with the requested amount of data, and then wait for
-the request to complete. However, we are in trouble if the read
-request arrives when a DMA operation is already scheduled (a normal
-situation) and the transfer length is (possibly much) larger than
-the requested amount of data. In this case, the interrupt will only
-arrive at the end of the operation, which might take a long time.
-This is not a problem with writes, since data are already buffered
-for the whole operation.
-
-\subsection{Why this does not always work...}
-
-Using single DMA mode avoids that, because of slow interrupt
-response, samples are played beyond the end of the buffer, or
-capture overwrites some old, still unread, data at the other end
-of the buffer.
-Single DMA mode has the problem of requiring fast interrupt
-response to ensure a smooth data transfer. If the system is not quick
-to reinitialize the DMA controller, some samples might be missed. To
-mitigate the problem, some controllers provide an internal FIFO which
-increases the allowable interrupt response time. As an example, a
-codec with 16-samples FIFO at 8~KHz gives 2~ms to reinitialize the
-codec itself, which is a reasonable time.
-This of course assumes that
-the codec makes good use of the FIFO e.g. in the play queue generates
-an interrupt when the count goes to 0 even when the FIFO is full. Some
-don't.
-
-Another problem of using single DMA is that the same count is
-programmed into the two devices. It appears that some codecs when
-working in full duplex have the bad habit of forgetting to count some
-cycles, resulting in interrupts not being generated.
-
-So, to sum up, single DMA mode works very well with well-behaved
-codecs and fast systems. When the system becomes slow, late interrupt
-response might cause ``clicks'' in the output, or missing samples in
-the input. When the codec is buggy, there might be deadlocks because
-of missing interrupts (we have only seen these in full duplex on some
-cards).
-
-\subsection{Auto-mode DMA}
-
-Auto-mode DMA refers to a special operating mode of the DMA engine
-which does not require the CPU to reinitialize the channel at the
-end of a transfer. Auto DMA can be enabled independently in the
-ISA DMA controller and in the sound card. The advantage of auto
-mode is that data can be transferred continuously and do not require
-the interrupt service routine to have a low latency (if AUTO DMA
-is used on both the ISA DMA controller and in the sound card).
-
-Enabling AUTO DMA in the ISA DMA controller only saves the small time
-needed to reinitialize the DMA controller, and can help preventing the
-deadlock with broken codecs, since the ISA DMA controller will always
-be available to serve DMA requests. A drawback of this approach is
-that the codec might try to transfer data beyond the allowed space.
-
-Enabling AUTO DMA in the codec only does not make any sense.
-
-To overcome the problem of DMA transfers going beyond the allowed
-space, the following strategy can be used. For playback, we must
-insure that the region beyond the end of valid data contains data
-which do not produce audible effects. As an example, it can be
-initialized with replicas of the last sample (1, 2 or 4 bytes
-depending on the operating mode). The amount of space to be
-initialized in this way should correspond to the expected maximum
-interrupt latency.
-
-For record, the whole buffer should not be used to acquire data, so
-that any overrun will just fill a guard region in the buffer, and not
-overwrite old data. Again the size of the guard region should be
-computed depending on the expected maximum interrupt latency.
-
-\section{Board-specific routines}
-
-All board-specific routines are contained in one or more board-specific
-source files, and possibly some include files. The board-specific
-file(s) should provide as a minimum a template {\tt snddev\_info}
-describing the board, and the various functions referenced in the
-template and not defined elsewhere. This generally includes the
-probe, attach, open, close, the callback, and the interrupt
-dispatcher.
-
-In order to make board-specific files easily readable, we suggest
-to use a standard structure for them. As a reference, one can
-look at file {\tt sb\_dsp.c} which contains the driver for the
-SoundBlaster board.
-
-The standard structure begins with the copyright. Then the body of the
-file is enclosed in the following lines:
-\begin{verbatim}
-#include <i386/isa/snd/sound.h>
-#if NPCM > 0
-... body of the file
-#endif /* NPCM > 0 */
-\end{verbatim}
-where the {\tt "sound.h"} contains all the generic include files and
-definitions for kernel audio modules. It also includes the
-config-generated file {\tt "snd.h"} which defines the number of
-statically-configured audio devices, NPCM (note that one is required
-but often suffices, since PnP devices will use additional unit numbers
-up to the maximum of {\tt NPCM\_MAX} which is currently defined as 8.
-The total number of audio devices, which can be used and should be
-incremented when PnP devices are detected, is held in the global
-variable {\tt u\_long nsnd} which is initialized with NPCM.
-
-Next come the {\tt \#include} for all board-specific include files,
-followed by the prototype declaration for all static functions which go
-into the {\tt snddev\_info}, and then prototypes for all static
-functions in this module. We encourage to make functions static if not
-used by other modules, to reduce pollution of the name space.
-
-After function prototypes, put the (initialized) descriptors for the
-board(s) supported by this file, e.g.
-\begin{verbatim}
-snddev_info sb_op_desc = {
- "SoundBlaster", SNDCARD_SB,
- sb_probe, sb_attach,
- sb_open, sb_close, NULL /* rd */, NULL /* wr */,
- sb_dsp_ioctl, sndselect, sbintr, sb_callback,
- DSP_BUFFSIZE,
- AFMT_U8,
-}
-\end{verbatim}
-
-\subsection{{\tt xxx\_probe()}}
-
-The board-specific probe routine is passed a pointer to a {\tt struct
-isa\_device} which contains all information collected from the {\tt
-device pcmX} line in the kernel configuration file. The probe code
-should do the minimum action to detect the board type and see if
-parameters are compatible with the board's features. It returns 1 in
-case of success, 0 in case of failure.
-
-The probe code is
-not supposed to do any allocation. If some temporary storage is
-necessary, the probe code can use {\tt pcm\_info[dev->id\_unit]},
-which is available, although not initialized at this stage. This
-is convenient since, often, the probe and attach routine share the
-same code for determining the board type, and can store the detected
-information right there. Note however that {\tt
-pcm\_info[dev->id\_unit]} will be reinitialized at attach time, so that
-data structure should not be regarded as persistent information, but
-only as a convenient storage area.
-
-\subsection{{\tt xxx\_attach()}}
-
-Same as the probe routine, the attach routine is passed a pointer
-to a {\tt struct isa\_device} with info from the configuration
-file. This time, however, the generic attach routine will also
-initialize {\tt pcm\_info[dev->id\_unit]} copying the template
-corresponding to the device identified by the probe routine;
-moreover, values from the kernel config line are also copied in
-the correct places (in particular, this involves the various fields
-which depend on the value of {\tt flags}.
-
-\subsection{Interrupt dispatcher}
-
-All audio devices register the same interrupt service routine ({\em
-ISR}), {\tt pcmintr}. This merely calls the ISR which is specified
-in the device descriptor, passing it the unit number for which the
-interrupt has arrived (in practice, one is not aware of the presence
-of {\tt pcmintr}, which could also disappear in the future, and
-should write the ISR routine as a standard ISR for BSD systems.
-
-The ISR mainly has to find out the interrupt reason (accessing {\tt
-pcm\_info[unit]} to collect board specific parameters) and perform
-whatever action is necessary. Usually, it is only necessary to call
-{\tt dsp\_wrintr()} or {\tt dsp\_rdintr()}, and possibly clear the
-interrupt flag in the codec.
-
-\subsection{Callback routine}
-
-The main interface between the generic audio code and the device
-specific code is the callback routine which is specified in the device
-descriptor. The callback routine is passed an {\tt int} argument which
-describes the reason of the callback. The argument is made of a mode
-(read and/or write) and a reason. Typically the callback is invoked
-from the dma code, upon user writes or interrupt routines. The code in
-the callback routine should typically perform codec-specific actions
-to start/stop a dma transfer in the desired direction.
-As an extension, the callback function can also be called by the
-generic routines at open and close times. This only happens if
-device-specific open and close are not implemented, and the
-functionalities are implemented here.
-
-Again this is done for convenience, since in many cases the open and
-close routines share a common part (e.g. to check for device busy
-conditions, etc.) which this way need not to be replicated in
-different drivers.
-
-\subsection{Mixer}
-
-Sound cards generally have a mixer device, which is in charge of
-controlling signal flow, attenuation and filtering on the various
-paths. We mutuate the Voxware scheme in this driver, both because it
-is reasonably flexible, and for compatibility with existing
-applications. In this scheme, each of the possible mixer channels is
-associated to a bit in a bitmask.
-
-Setting levels for a mixer channel generally just requires to write a
-value (associated to the level) in some location. Since the number of
-bits used by various mixer devices largely differs from board to
-board, the Voxware driver uses a description table to map channels
-into the appropriate addresses. A table is made of an array of {\tt
-mixer\_ent} entries, which are set with the {\tt PMIX\_ENT} and
-{\tt MIX\_ENT} macros (all defined in {\tt sound.h}):
-entries:
-
-\begin{verbatim}
-struct mixer_def {
- u_int regno:7;
- u_int polarity:1;
- u_int bitoffs:4;
- u_int nbits:4;
-};
-typedef struct mixer_def mixer_ent;
-typedef struct mixer_def mixer_tab[32][2];
-
-#define MIX_ENT(name, reg_l, pol_l, pos_l, len_l, reg_r, pol_r, pos_r, len_r) \
- {{reg_l, pol_l, pos_l, len_l}, {reg_r, pol_r, pos_r, len_r}}
-#define PMIX_ENT(name, reg_l, pos_l, len_l, reg_r, pos_r, len_r) \
- {{reg_l, 0, pos_l, len_l}, {reg_r, 0, pos_r, len_r}}
-
-void
-change_bits(mixer_tab *t, u_char *regval, int dev, int chn, int newval);
-\end{verbatim}
-The table is used by {\tt change\_bits()}, which accepts a pointer
-to a table, a pointer to the old value of the register, device
-(0..31), channel (left or right), and the new value to be set, in
-the range 0..100.
-
-\end{document}
diff --git a/sys/i386/isa/snd/misc/README b/sys/i386/isa/snd/misc/README
deleted file mode 100644
index e50b041..0000000
--- a/sys/i386/isa/snd/misc/README
+++ /dev/null
@@ -1,82 +0,0 @@
-Various support files for the new sound driver for FreeBSD.
-
- audio-voxware.cc
-
- this is the driver for "vat" (tested with vat 4.0b2 in the
- ports distribution) to make things work in full duplex. It
- does _not_ use non-blocking i/o, otherwise vat will happily
- eat most of your CPU time since select will often return true
- even if less than one frame is ready.
-
- The environment variable AUDIODEV will let you use different
- sound cards if you have more than one. It can contain the unit
- number (0, 1, 2, ...) or the full pathname.
-
- As an additional bonus, you can select a fourth input which is
- a ulaw file which is written to the network instead of the
- input audio data.
-
- CPU usage on my p5/133 in full duplex, local feedback and
- silence suppression (most demanding configuration I believe):
- PCM 3.5%
- DVI 4.8%
- LPC 11 %
- GSM 23 %
-
- auvoxware.c
-
- this is the driver for "nas" (tested with nas 1.2b5). Works
- fine in full duplex.
-
- linux_a.c
-
- driver for timidity, a midi-to-pcm converter. Using this program
- (and if you have spare cpu cycles) you can play midi files to
- /dev/audio without the need for a synthesis device.
-
- linux.patch
-
- this is a patch for 2.2.X users for the linux emulator. The
- files to correct are in /sys/i386/linux, and this patch
- implements a few ioctl which are used by the realvideo player
- for linux (rvplayer). In order to use these patches you have
- to recompile the linux_mod.o and install it in place as follows
-
- cd /usr/src/lkm/linux
- make
- mv linux_mod.o /lkm/linux_mod.o
-
- pcmio.c
-
- a simple program to do i/o with the audio device. You can set
- on the command line the device, the speed, data format, stereo
- or mono... And if you use a bidirectional device, you can play
- and record at the same time.
-
- E.g.
-
- pcmio -f 1 +rec,stereo,44100,s16 song
-
- will record from /dev/audio1 stereo,16-bit data to the file "song"
-
- pcmio +play,stereo,44100,s16,loop 50s:20s song
-
- will continuosly play 50s from "song" (skipping the first 20s)
- to /dev/audio
-
- pcmio +rec,ulaw - | tee tapefile > /dev/audio
-
- will record using ulaw (mono at 8KHz, default) to stdout, and
- the pipe will both dump things to "tapefile" and to /dev/audio
- to listen what you are recording (you could do the same with
- "cat...").
-
- soundbyte.c
-
- the audio module for speak_freely
-
- test.c
-
- lets you monitor the status of the device (/dev/audio1) by
- mmapping the descriptor and dumping to screen the interesting
- fields.
diff --git a/sys/i386/isa/snd/misc/audio-voxware.cc b/sys/i386/isa/snd/misc/audio-voxware.cc
deleted file mode 100644
index 16feb46..0000000
--- a/sys/i386/isa/snd/misc/audio-voxware.cc
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (c) 1991-1993 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-/*
- * Full Duplex audio module for the new sound driver and full duplex
- * cards. Luigi Rizzo, from original sources supplied by Amancio Hasty.
- *
- * This includes some enhancements:
- * - the audio device to use can be in the AUDIODEV env. variable.
- * It can be either a unit number or a full pathname;
- * - use whatever format is available from the card (included split
- * format e.g. for the sb16);
- * - limit the maximum size of the playout queue to approx 4 frames;
- * this is necessary if the write channel is slower than expected;
- * the fix is based on two new ioctls, AIOGCAP and AIONWRITE,
- * but the code should compile with the old driver as well.
- */
-
-#include <osfcn.h>
-#include <machine/soundcard.h>
-#include "audio.h"
-#include "mulaw.h"
-#include "Tcl.h"
-
-#define ULAW_ZERO 0x7f
-
-extern const u_char lintomulawX[];
-
-class VoxWare : public Audio {
- public:
- VoxWare();
- virtual int FrameReady();
- virtual u_char* Read();
- virtual void Write(u_char *);
- virtual void SetRGain(int);
- virtual void SetPGain(int);
- virtual void OutputPort(int);
- virtual void InputPort(int);
- virtual void Obtain();
- virtual void Release();
- virtual void RMute();
- virtual void RUnmute();
- virtual int HalfDuplex() const;
- protected:
- int ext_fd; /* source for external file */
-
- u_char* readbuf;
- u_short *s16_buf;
-
- int play_fmt ;
-#if defined(AIOGCAP) /* new sound driver */
- int rec_fmt ; /* the sb16 has split format... */
- snd_capabilities soundcaps;
-#endif
-};
-
-static class VoxWareMatcher : public Matcher {
-public:
- VoxWareMatcher() : Matcher("audio") {}
- TclObject* match(const char* fmt) {
- if (strcmp(fmt, "voxware") == 0)
- return (new VoxWare);
- return (0);
- }
-} linux_audio_matcher;
-
-VoxWare::VoxWare()
-{
- readbuf = new u_char[blksize];
- s16_buf = new u_short[blksize];
-
- memset(readbuf, ULAW_ZERO, blksize);
-
- ext_fd = -1 ; /* no external audio */
- iports = 4; /* number of input ports */
-}
-
-void
-VoxWare::Obtain()
-{
- char *thedev;
- char buf[64];
- int d = -1;
-
- if (HaveAudio())
- abort();
- thedev=getenv("AUDIODEV");
- if (thedev==NULL)
- thedev="/dev/audio";
- else if ( thedev[0] >= '0' && thedev[0] <= '9' ) {
- d = atoi(thedev);
- sprintf(buf,"/dev/audio%d", d);
- thedev = buf ;
- }
- fd = open(thedev, O_RDWR );
- thedev=getenv("MIXERDEV");
- if (thedev == NULL)
- if (d < 0)
- thedev = "/dev/mixer";
- else {
- sprintf(buf,"/dev/mixer%d", d);
- thedev = buf ;
- }
-
- if (fd >= 0) {
- int i = -1 ;
-#if defined(AIOGCAP) /* new sound driver */
- i = ioctl(fd, AIOGCAP, &soundcaps);
- if (i == 0) {
- snd_chan_param pa;
- struct snd_size sz;
-
- pa.play_rate = pa.rec_rate = 8000 ;
- pa.play_format = pa.rec_format = AFMT_MU_LAW ;
- switch (soundcaps.formats & (AFMT_FULLDUPLEX | AFMT_WEIRD)) {
- case AFMT_FULLDUPLEX :
- /*
- * this entry for cards with decent full duplex. Use s16
- * preferably (some are broken in ulaw) or ulaw or u8 otherwise.
- */
- if (soundcaps.formats & AFMT_S16_LE)
- pa.play_format = pa.rec_format = AFMT_S16_LE ;
- else if (soundcaps.formats & AFMT_MU_LAW)
- pa.play_format = pa.rec_format = AFMT_MU_LAW ;
- else if (soundcaps.formats & AFMT_U8)
- pa.play_format = pa.rec_format = AFMT_U8 ;
- else {
- printf("sorry, no supported formats\n");
- close(fd);
- fd = -1 ;
- return;
- }
- break ;
- case AFMT_FULLDUPLEX | AFMT_WEIRD :
- /* this is the sb16... */
- if (soundcaps.formats & AFMT_S16_LE) {
- pa.play_format = AFMT_U8 ;
- pa.rec_format = AFMT_S16_LE;
- } else {
- printf("sorry, no supported formats\n");
- close(fd);
- fd = -1 ;
- return;
- }
- break ;
- default :
- printf("sorry don't know how to deal with this card\n");
- close (fd);
- fd = -1;
- break;
- }
- ioctl(fd, AIOSFMT, &pa);
- play_fmt = pa.play_format ;
- rec_fmt = pa.rec_format ;
- sz.play_size = (play_fmt == AFMT_S16_LE) ? 2*blksize : blksize;
- sz.rec_size = (rec_fmt == AFMT_S16_LE) ? 2*blksize : blksize;
- ioctl(fd, AIOSSIZE, &sz);
- } else
-#endif
- { /* setup code for old voxware driver */
- }
- Audio::Obtain();
- }
-}
-
-/*
- * note: HalfDuplex() uses a modified function of the new driver,
- * which will return AFMT_FULLDUPLEX set in SNDCTL_DSP_GETFMTS
- * for full-duplex devices. In the old driver this was 0 so
- * the default is to use half-duplex for them. Note also that I have
- * not tested half-duplex operation.
- */
-int
-VoxWare::HalfDuplex() const
-{
- int i;
- ioctl(fd, SNDCTL_DSP_GETFMTS, &i);
-#if 0
- printf("SNDCTL_DSP_GETFMTS returns 0x%08x %s duplex\n",
- i, i & AFMT_FULLDUPLEX ? "full":"half");
-#endif
- return (i & AFMT_FULLDUPLEX) ? 0 : 1 ;
-}
-
-void VoxWare::Release()
-{
- if (HaveAudio()) {
- Audio::Release();
- }
-}
-
-void VoxWare::Write(u_char *cp)
-{
- int i = blksize, l;
- static int peak = 0;
-
- if (play_fmt == AFMT_S16_LE) {
- for (i=0; i< blksize; i++)
- s16_buf[i] = mulawtolin[cp[i]] ;
- cp = (u_char *)s16_buf;
- i = 2 *blksize ;
- }
- else if (play_fmt == AFMT_S8) {
- for (i=0; i< blksize; i++) {
- int x = mulawtolin[cp[i]] ;
- x = (x >> 8 ) & 0xff;
- cp[i] = (u_char)x ;
- }
- i = blksize ;
- } else if (play_fmt == AFMT_U8) {
- /*
- * when translating to 8-bit formats, need to implement AGC
- * to avoid loss of resolution in the conversion.
- * The peak is multiplied by 2^13
- */
- for (i=0; i< blksize; i++) {
- int x = mulawtolin[cp[i]] ;
-#if 0 /* AGC -- still not complete... */
- if (x < 0) x = -x ;
- if (x > peak) peak = ( peak*16 + x - peak ) / 16 ;
- else peak = ( peak*8192 + x - peak ) / 8192 ;
- if (peak < 128) peak = 128 ;
- /* at this point peak is in the range 128..32k
- * samples can be scaled and clipped consequently.
- */
- x = x * 32768/peak ;
- if (x > 32767) x = 32767;
- else if (x < -32768) x = -32768;
-#endif
- x = (x >> 8 ) & 0xff;
- x = (x ^ 0x80) & 0xff ;
- cp[i] = (u_char)x ;
- }
- i = blksize ;
- }
-#if 0 && defined(AIOGCAP)
- int queued;
- ioctl(fd, AIONWRITE, &queued);
- queued = soundcaps.bufsize - queued ;
- if (play_fmt == AFMT_S16_LE) {
- if (queued > 8*blksize)
- i -= 8 ;
- } else {
- if (queued > 4*blksize)
- i -= 4 ;
- }
-#endif
- for ( ; i > 0 ; i -= l) {
- l = write(fd, cp, i);
- cp += l;
- }
-}
-
-u_char* VoxWare::Read()
-{
- u_char* cp;
- int l=0, l0 = blksize, i = blksize;
- static int smean = 0 ; /* smoothed mean to remove DC */
- static int loops = 20 ;
-
- cp = readbuf;
-
- if (rec_fmt == AFMT_S16_LE) {
- cp = (u_char *)s16_buf;
- l0 = i = 2 *blksize ;
- }
- for ( ; i > 0 ; i -= l ) {
- l = read(fd, cp, i);
- cp += l ;
- }
- if (rec_fmt == AFMT_S16_LE) {
- for (i=0; i< blksize; i++) {
-#if 1 /* remove DC component... */
- int mean = smean >> 13;
- int dif = ((short) s16_buf[i]) - mean;
- smean += dif ;
- readbuf[i] = lintomulawX[ dif & 0x1ffff ] ;
-#else
- readbuf[i] = lintomulaw[ s16_buf[i] ] ;
-#endif
- }
- }
- else if (rec_fmt == AFMT_S8) {
- for (i=0; i< blksize; i++)
- readbuf[i] = lintomulaw[ readbuf[i]<<8 ] ;
- }
- else if (rec_fmt == AFMT_U8) {
- for (i=0; i< blksize; i++)
- readbuf[i] = lintomulaw[ (readbuf[i]<<8) ^ 0x8000 ] ;
- }
- if (iport == 3) {
- l = read(ext_fd, readbuf, blksize);
- if (l < blksize) {
- lseek(ext_fd, (off_t) 0, 0);
- read(ext_fd, readbuf+l, blksize - l);
- }
- }
- return readbuf;
-}
-
-/*
- * should check that I HaveAudio() before trying to set gain.
- *
- * In most mixer devices, there is only a master volume control on
- * the capture channel, so the following code does not really work
- * as expected. The only (partial) exception is the MIC line, where
- * there is generally a 20dB boost which can be enabled or not
- * depending on the type of device.
- */
-void VoxWare::SetRGain(int level)
-{
- double x = level;
- level = (int) (x/2.56);
- int foo = (level<<8) | level;
- if (!HaveAudio())
- Obtain();
- switch (iport) {
- case 2:
- case 1:
- break;
- case 0:
- if (ioctl(fd, MIXER_WRITE(SOUND_MIXER_MIC), &foo) == -1)
- printf("failed to set mic volume \n");
- break;
- }
- if (ioctl(fd, MIXER_WRITE(SOUND_MIXER_IGAIN), &foo) == -1)
- printf("failed set input line volume \n");
- rgain = level;
-}
-
-void VoxWare::SetPGain(int level)
-{
- float x = level;
- level = (int) (x/2.56);
- int foo = (level<<8) | level;
- if (ioctl(fd, MIXER_WRITE(SOUND_MIXER_PCM), &foo) == -1) {
- printf("failed to output level %d \n", level);
- }
- pgain = level;
-}
-
-void VoxWare::OutputPort(int p)
-{
- oport = p;
-}
-
-void VoxWare::InputPort(int p)
-{
- int src = 0;
-
- if (ext_fd >=0 && p != 3) {
- close(ext_fd);
- ext_fd = -1 ;
- }
-
- switch(p) {
- case 3:
- fprintf(stderr,"input from file %s\n", ext_fname);
- if (ext_fd == -1)
- ext_fd = open(ext_fname, 0);
- if (ext_fd != -1)
- lseek(ext_fd, (off_t) 0, 0);
- break;
- case 2:
- src = 1 << SOUND_MIXER_LINE;
- break;
- case 1: /* cd ... */
- src = 1 << SOUND_MIXER_CD;
- break;
- case 0 :
- src = 1 << SOUND_MIXER_MIC;
- break;
- }
- if ( ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &src) == -1 ) {
- printf("failed to select input \n");
- p = 0;
- }
- iport = p;
-}
-
-void VoxWare::RMute()
-{
- rmute |= 1;
-}
-
-void VoxWare::RUnmute()
-{
- rmute &=~ 1;
-}
-
-/*
- * FrameReady must return 0 every so often, or the system will keep
- * processing mike data and not other events.
- */
-int VoxWare::FrameReady()
-{
- int i = 0;
- int lim = blksize;
-
- ioctl(fd, FIONREAD, &i );
- if (rec_fmt == AFMT_S16_LE) lim = 2*blksize;
- return (i >= lim) ? 1 : 0 ;
-}
-/*** end of file ***/
diff --git a/sys/i386/isa/snd/misc/auvoxware.c b/sys/i386/isa/snd/misc/auvoxware.c
deleted file mode 100644
index 1ae9316..0000000
--- a/sys/i386/isa/snd/misc/auvoxware.c
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*
- SCCS: @(#) auvoxware.c 11.4 95/04/14
-*/
-/*-------------------------------------------------------------------------
-
-Copyright (C) 1995 The Santa Cruz Operation, Inc.
-All Rights Reserved.
-
-Permission to use, copy, modify and distribute this software
-for any purpose is hereby granted without fee, provided that the
-above copyright notice and this notice appear in all copies
-and that both the copyright notice and this notice appear in
-supporting documentation. SCO makes no representations about
-the suitability of this software for any purpose. It is provided
-"AS IS" without express or implied warranty.
-
-SCO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL SCO BE LIABLE FOR ANY SPECIAL, INDIRECT,
-PUNITIVE, CONSEQUENTIAL OR INCIDENTAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, LOSS OF DATA OR LOSS OF
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------------*/
-/*
- AUVoxConfig additions (sysseh@devetir.qld.gov.au)
- 96-01-15
- Put the following keywords in -
- minrate - Minimum sampling rate
- maxrate - Maximum sampling rate
- fragsize - The fragment size
- minfrags - Minimum number of frags in queue
- maxfrags - Maximum fragments in queue
- wordsize - 8 or 16 bit samples
- device - What device file to use
- numchans - Mono (1) or stereo (2)
- debug - Output messages during operation
- verbose - Be chatty about config
- inputsection - Next lot of specs are for input
- outputsection - Next specs are for output
- end - End an input or output section
-*/
-/*
- SCO Modification History:
- S005, 24-Apr-95, shawnm@sco.com
- base # of driver buffer fragments on data rate
- S004, 12-Apr-95, shawnm@sco.com
- finish integration of ausco.c, fix setitimer calls
- S003, 28-Mar-95, shawnm@sco.com, sysseh@devetir.qld.gov.au
- incorporate patch for stereo/mono mixing from Stephen Hocking
- S002, 21-Mar-95, shawnm@sco.com
- incorporate signal handling and audio block/unblock from ausco.c
- S001, 21-Mar-95, shawnm@sco.com, sysseh@devetir.qld.gov.au
- SYSSEH incorporate parts of patch from Stephen Hocking
-*/
-/*
- * Copyright 1993 Network Computing Devices, Inc. Copyright (C) Siemens
- * Nixdorf Informationssysteme AG 1993
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name Network Computing Devices, Inc. or
- * Siemens Nixdorf Informationssysteme AG not be used in advertising or
- * publicity pertaining to distribution of this software without specific,
- * written prior permission.
- *
- * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC. AND
- * SIEMENS NIXDORF INFORMATIONSSYSTEME AG DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
- * NONINFRINGEMENT. IN NO EVENT SHALL NETWORK COMPUTING DEVICES, INC. NOR
- * SIEMENS NIXDORF INFORMATIONSSYSTEME AG BE LIABLE FOR ANY DAMAGES
- * WHATSOEVER, INCLUDING SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
- * INCLUDING LOSS OF USE, DATA, OR PROFITS, EVEN IF ADVISED OF THE
- * POSSIBILITY THEREOF, AND REGARDLESS OF WHETHER IN AN ACTION IN CONTRACT,
- * TORT OR NEGLIGENCE, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * $NCDId: @(#)auvoxware.c,v 1.10 1996/04/24 17:04:19 greg Exp $
- *
- * Copyright (C) Siemens Nixdorf Informationssysteme AG 1993 All rights reserved
- */
-
-/*
- * Originally from the merge of auvoxware by Amancio Hasty (hasty@netcom.com)
- * & auvoxsvr4 by Stephen Hocking (sysseh@devetir.qld.gov.au).
- * 16bit fixes and Linux patches supplied by Christian
- * Schlichtherle (s_schli@ira.uka.de).
- *
- * BUGS:
- * - When the soundcard can do only 8 bit recording, "aurecord" records
- * twice as long as it should. Is this our fault?
- *
- * TODO:
- * - Adapt the buffer sizes to the current sampling rate,
- * so that we can record/play high quality audio samples without
- * swallows/pauses.
- * Note that setting the buffer size to a fixed maximum will not work,
- * because it causes playing at slow sample rate to pause. :-(
- * I already tried to do this, but it seems that the rest of the server
- * code doesn't recognize the changed buffer sizes. Any help in doing
- * this is welcome!
- * [chris]
- * - Support a second input channel for stereo sampling,
- * so that microphone sampling is done on the mono channel
- * while line sampling is done on the stereo channel.
- * [chris]
- *
- * CHANGELOG:
- * - 94/7/2:
- * Completely rewrote this file. Features:
- * + Makes use of two sound cards if available.
- * So you can concurrently record and play samples.
- * + Tested to work with all combinations of 8/16 bit, mono/stereo
- * sound card sampling modes.
- * + Uses a stereo input channel if hardware supports this.
- * + Can play stereo samples on mono sound cards (but who cares?).
- * + Always uses the highest possible audio quality, i.e. 8/16 bit and
- * mono/stereo parameters are fixed while only the sampling rate is
- * variable. This reduces swallows and pauses to the (currently)
- * unavoidable minimum while consuming a little bit more cpu time.
- * + Format conversion stuff is pushed back to the rest of the server code.
- * Only mono/stereo conversion is done here.
- * + Debugging output uses indentation.
- * [chris]
- */
-
-#include <stdio.h>
-#include "config.h"
-
-FILE *yyin;
-
-static char *searchpath = CONFSEARCHPATH;
-
-#if defined(DEBUGDSPOUT) || defined(DEBUGDSPIN)
-int dspin, dspout;
-#endif
-
-# define PRMSG(x, a, b) \
- if (doDebug) { \
- fprintf(stderr, "auvoxware.c: %*s", debug_msg_indentation, ""); \
- fprintf(stderr, (x), (a), (b)); \
- fflush(stderr); \
- }
-# define IDENTMSG (debug_msg_indentation += 2)
-# define UNIDENTMSG (debug_msg_indentation -= 2)
-
-static int doDebug = 0;
-int beVerbose = 0;
-static int debug_msg_indentation = 0;
-
-#include <errno.h>
-#include "dixstruct.h" /* for RESTYPE */
-#include "os.h" /* for xalloc/xfree and NULL */
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/param.h>
-#include <assert.h>
-
-#ifdef __FreeBSD__
-#include <machine/soundcard.h>
-#include <machine/pcaudioio.h>
-#else
-#include <sys/soundcard.h>
-#endif
-
-#include <audio/audio.h>
-#include <audio/Aproto.h>
-#include "au.h"
-
-#ifdef sco
-static AuBool scoAudioBlocked = AuFalse;
-#endif /* sco */
-
-static AuBool processFlowEnabled;
-
-#define SERVER_CLIENT 0
-
-#define MIN_MINIBUF_SAMPLES 256
-#define MAX_MINIBUF_SAMPLES 1024 /* Must be a power of 2 */
-
-#define auDefaultInputGain AuFixedPointFromSum(50, 0)
-#define auDefaultOutputGain AuFixedPointFromSum(50, 0)
-
-#define PhysicalOneTrackBufferSize \
- PAD4(auMinibufSamples * auNativeBytesPerSample * 1)
-#define PhysicalTwoTrackBufferSize \
- PAD4(auMinibufSamples * auNativeBytesPerSample * 2)
-
-/* VOXware sound driver mixer control variables */
-
-static int Letsplay;
-static int level[100];
-static int mixerfd; /* The mixer device */
-static int devmask = 0; /* Bitmask for supported mixer devices */
-static int recsrc = 0; /* Currently selected recording sources */
-static int recmask = 0; /* Supported recording sources */
-static int stereodevs = 0; /* Channels supporting stereo */
-
-static char *labels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
-
-/* end of VOXware driver mixer control variables */
-
-int ParseError = 0; /* Did we fail to parse conf. file? */
-
-SndStat *confStat;
-
-SndStat sndStatIn =
-{
- -1,
- 16,
- 2,
- 0,
- 4000,
- 44100,
- 256,
- 3,
- 32,
- "/dev/dsp",
- 0
-}, sndStatOut =
-{
- -1,
- 16,
- 2,
- 0,
- 4000,
- 44100,
- 256,
- 3,
- 32,
- "/dev/dsp",
- 0
-};
-
-static AuUint8 *auOutputMono,
- *auOutputStereo,
- *auInput;
-
-static ComponentPtr monoInputDevice,
- stereoInputDevice,
- monoOutputDevice,
- stereoOutputDevice;
-
-extern AuInt32 auMinibufSamples;
-
-
-#define auPhysicalOutputChangableMask AuCompDeviceGainMask
-
-#define auPhysicalOutputValueMask \
- (AuCompCommonAllMasks \
- | AuCompDeviceMinSampleRateMask \
- | AuCompDeviceMaxSampleRateMask \
- | AuCompDeviceGainMask \
- | AuCompDeviceLocationMask \
- | AuCompDeviceChildrenMask)
-
-#define auPhysicalInputChangableMask \
- (AuCompDeviceGainMask | AuCompDeviceLineModeMask)
-
-#define auPhysicalInputValueMask \
- (AuCompCommonAllMasks \
- | AuCompDeviceMinSampleRateMask \
- | AuCompDeviceMaxSampleRateMask \
- | AuCompDeviceLocationMask \
- | AuCompDeviceGainMask \
- | AuCompDeviceChildrenMask)
-
-static void setPhysicalOutputGain();
-static void setPhysicalInputGainAndLineMode();
-
-void setDebugOn ()
-{
- doDebug = 1;
-}
-
-void setVerboseOn ()
-{
- beVerbose = 1;
-}
-
-#ifdef sco
-
-AuBlock
-AuBlockAudio()
-{
- scoAudioBlocked = AuTrue;
- return 0;
-}
-
-void
-AuUnBlockAudio(AuBlock id)
-{
- scoAudioBlocked = AuFalse;
-}
-
-#endif /* sco */
-
-static int createServerComponents(auServerDeviceListSize,
- auServerBucketListSize,
- auServerRadioListSize,
- auServerMinRate,
- auServerMaxRate)
-AuUint32 *auServerDeviceListSize,
- *auServerBucketListSize,
- *auServerRadioListSize,
- *auServerMinRate,
- *auServerMaxRate;
-{
- AuDeviceID stereo, mono;
- ComponentPtr d, *p;
- int i;
- AuUint8 formatIn,
- formatOut;
- AuUint32 bytesPerSampleIn,
- bytesPerSampleOut;
- static AuBool initialized = AuFalse;
- extern RESTYPE auComponentType;
- extern ComponentPtr *auServerDevices, /* array of devices */
- *auServerBuckets, /* array of server owned buckets */
- *auServerRadios, /* array of server owned radios */
- auDevices, /* list of all devices */
- auBuckets, /* list of all buckets */
- auRadios; /* list of all radios */
- extern AuUint32 auNumServerDevices, /* number of devices */
- auNumActions, /* number of defined actions */
- auNumServerBuckets, /* number of server owned buckets */
- auNumServerRadios; /* number of server owned radios */
-
- PRMSG("createServerComponents(...);\n", 0, 0);
- IDENTMSG;
-
- *auServerMinRate = aumax(sndStatIn.minSampleRate,
- sndStatOut.minSampleRate);
- *auServerMaxRate = aumax(sndStatIn.maxSampleRate,
- sndStatOut.maxSampleRate);
-
- auNumServerDevices = *auServerDeviceListSize
- = *auServerBucketListSize
- = *auServerRadioListSize
- = 0;
-
- formatIn = (sndStatIn.wordSize == 16) ? AuFormatLinearSigned16LSB
- : AuFormatLinearUnsigned8;
- formatOut = (sndStatOut.wordSize == 16) ? AuFormatLinearSigned16LSB
- : AuFormatLinearUnsigned8;
-
- bytesPerSampleIn = sndStatIn.wordSize / 8;
- bytesPerSampleOut = sndStatOut.wordSize / 8;
-
- AU_ALLOC_DEVICE(d, 1, 0);
- d->id = FakeClientID(SERVER_CLIENT);
- d->changableMask = auPhysicalOutputChangableMask;
- d->valueMask = auPhysicalOutputValueMask;
- d->kind = AuComponentKindPhysicalOutput;
- d->use = AuComponentUseExportMask;
- d->access = AuAccessExportMask | AuAccessListMask;
- d->format = formatOut;
- d->numTracks = 1;
- d->description.type = AuStringLatin1;
- d->description.string = "Mono Channel Output";
- d->description.len = strlen(d->description.string);
- d->minSampleRate = sndStatOut.minSampleRate;
- d->maxSampleRate = sndStatOut.maxSampleRate;
- d->location = AuDeviceLocationCenterMask | AuDeviceLocationInternalMask;
- d->numChildren = 0;
- d->minibuf = auOutputMono;
- d->minibufSize = d->numTracks * bytesPerSampleOut * auMinibufSamples;
- d->physicalDeviceMask = PhysicalOutputMono;
- AU_ADD_DEVICE(d);
-
- monoOutputDevice = d;
-
- AU_ALLOC_DEVICE(d, 2, 1);
- d->id = FakeClientID(SERVER_CLIENT);
- d->changableMask = auPhysicalOutputChangableMask;
- d->valueMask = auPhysicalOutputValueMask;
- d->kind = AuComponentKindPhysicalOutput;
- d->use = AuComponentUseExportMask;
- d->access = AuAccessExportMask | AuAccessListMask;
- d->format = formatOut;
- d->numTracks = 2;
- d->description.type = AuStringLatin1;
- d->description.string = "Stereo Channel Output";
- d->description.len = strlen(d->description.string);
- d->minSampleRate = sndStatOut.minSampleRate;
- d->maxSampleRate = sndStatOut.maxSampleRate;
- d->location = AuDeviceLocationCenterMask | AuDeviceLocationInternalMask;
- d->numChildren = 1;
- d->children = (AuID *) ((AuUint8 *) d + PAD4(sizeof(ComponentRec)));
- d->childSwap = (char *) (d->children + d->numChildren);
- d->children[0] = monoOutputDevice->id;
- d->minibuf = auOutputStereo;
- d->minibufSize = d->numTracks * bytesPerSampleOut * auMinibufSamples;
- d->physicalDeviceMask = PhysicalOutputStereo;
- AU_ADD_DEVICE(d);
-
- stereoOutputDevice = d;
-
- AU_ALLOC_DEVICE(d, (sndStatIn.isStereo + 1), 0);
- d->id = FakeClientID(SERVER_CLIENT);
- d->changableMask = auPhysicalInputChangableMask;
- d->valueMask = auPhysicalInputValueMask;
- d->kind = AuComponentKindPhysicalInput;
- d->use = AuComponentUseImportMask;
- d->access = AuAccessImportMask | AuAccessListMask;
- d->format = formatIn;
- d->numTracks = sndStatIn.isStereo + 1;
- d->description.type = AuStringLatin1;
- d->description.string = (sndStatIn.isStereo) ? "Stereo Channel Input"
- : "Mono Channel Input";
- d->description.len = strlen(d->description.string);
- d->minSampleRate = sndStatOut.minSampleRate;
- d->maxSampleRate = sndStatOut.maxSampleRate;
- d->location = AuDeviceLocationRightMask | AuDeviceLocationLeftMask
- | AuDeviceLocationExternalMask;
- d->numChildren = 0;
- d->gain = auDefaultInputGain;
- d->minibuf = auInput;
- d->minibufSize = d->numTracks * bytesPerSampleIn * auMinibufSamples;
- d->physicalDeviceMask = (sndStatIn.isStereo) ? PhysicalInputStereo
- : PhysicalInputMono;
- AU_ADD_DEVICE(d);
-
- monoInputDevice = d; /* Should have two input devices - FIXME */
- stereoInputDevice = d;
-
- /* set the array of server devices */
- if (!(auServerDevices = (ComponentPtr *) aualloc(sizeof(ComponentPtr)
- * auNumServerDevices))) {
- UNIDENTMSG;
- return AuBadAlloc;
- }
-
- p = auServerDevices;
- d = auDevices;
-
- while (d) {
- *p++ = d;
- d = d->next;
- }
-
- if (!initialized) {
- initialized = AuTrue;
- setPhysicalOutputGain(auDefaultOutputGain);
- setPhysicalInputGainAndLineMode(auDefaultInputGain, 0);
- }
-
- UNIDENTMSG;
-
- return AuSuccess;
-}
-
-static AuInt32 setTimer(rate)
-AuInt32 rate;
-{
- AuInt16 timer_ms;
- AuInt32 foo;
- struct itimerval ntval, otval;
-
- PRMSG("setTimer(rate = %d);\n", rate, 0);
- IDENTMSG;
-
- /* change timer according to new sample rate */
- if (rate == 0) { /* Disable timer case */
- ntval.it_value.tv_sec = ntval.it_value.tv_usec = 0;
- ntval.it_interval.tv_sec = ntval.it_interval.tv_usec = 0;
- timer_ms = 0x7fff;
- } else {
- timer_ms = (auMinibufSamples * 500) / rate;
- ntval.it_interval.tv_sec = 0;
- ntval.it_interval.tv_usec = timer_ms * 1000;
- ntval.it_value.tv_sec = 0;
- ntval.it_value.tv_usec = timer_ms *1000 / 2 ;
- }
- foo = setitimer(ITIMER_REAL, &ntval, &otval);
-
- UNIDENTMSG;
-
- return timer_ms;
-}
-
-
-#ifdef sco
-static void
-oneMoreTick()
-{
- struct itimerval ntval, otval;
- int foo;
-
- ntval.it_interval.tv_sec = 0;
- ntval.it_interval.tv_usec = 0;
- ntval.it_value.tv_sec = 0;
- ntval.it_value.tv_usec = 10;
- foo = setitimer(ITIMER_REAL, &ntval, &otval);
-}
-#endif /* sco */
-
-
-static void
-setFragmentSize(sndStatPtr)
-SndStat *sndStatPtr;
-{
- int fragarg, i, j;
- int datarate, numfrags;
-
- datarate = sndStatPtr->curSampleRate;
- if (sndStatPtr->isStereo)
- datarate *= 2;
- if (sndStatPtr->wordSize == 16)
- datarate *= 2;
- datarate /= 2; /* half second */
- numfrags = datarate / MAX_MINIBUF_SAMPLES;
- if (numfrags < sndStatPtr->minFrags)
- numfrags = sndStatPtr->minFrags;
- else if (numfrags > sndStatPtr->maxFrags)
- numfrags = sndStatPtr->maxFrags;
-
- j = MAX_MINIBUF_SAMPLES;
- for (i = 0; j; i++) /* figure out what power of 2 MAX_MINIBUF_SAMPLES is */
- j = j >> 1;
- fragarg = (numfrags << 16) | i; /* numfrags of size MAX_MINIBUF_SAMPLES */
- ioctl(sndStatPtr->fd, SNDCTL_DSP_SETFRAGMENT, &fragarg);
-}
-
-
-static AuUint32 setSampleRate(rate)
-AuUint32 rate;
-{
- int numSamplesIn, numSamplesOut;
- AuBlock l;
-
- PRMSG("setSampleRate(rate = %d);\n", rate, 0);
- IDENTMSG;
-
- l = AuBlockAudio();
-
- if (sndStatOut.curSampleRate != rate) {
- sndStatOut.curSampleRate = rate;
-
-#if defined(SNDCTL_DSP_SETFRAGMENT)
- setFragmentSize(&sndStatOut);
-#endif
- ioctl(sndStatOut.fd, SNDCTL_DSP_SYNC, NULL);
- ioctl(sndStatOut.fd, SNDCTL_DSP_SPEED, &(sndStatOut.curSampleRate));
- }
-
- if (sndStatIn.fd == sndStatOut.fd)
- sndStatIn = sndStatOut;
- else if (sndStatIn.curSampleRate != rate) {
- sndStatIn.curSampleRate = rate;
-
-#if defined(SNDCTL_DSP_SETFRAGMENT)
- setFragmentSize(&sndStatIn);
-#endif
- ioctl(sndStatIn.fd, SNDCTL_DSP_SYNC, NULL);
- ioctl(sndStatIn.fd, SNDCTL_DSP_SPEED, &(sndStatIn.curSampleRate));
- }
-
-#if defined(AUDIO_DRAIN)
- if (sndStatOut.isPCSpeaker)
- ioctl (sndStatOut.fd, AUDIO_DRAIN, 0);
-#endif
-
- AuUnBlockAudio(l);
-
- setTimer(rate);
-
- UNIDENTMSG;
-
- return sndStatOut.curSampleRate;
-}
-
-
-static void serverReset()
-{
- PRMSG("serverReset();\n", 0, 0);
- IDENTMSG;
-
- setTimer(0);
-#ifndef sco
- signal(SIGALRM, SIG_IGN);
-#endif /* sco */
-
- PRMSG("Audio Synchronisation...", 0, 0);
-
-#if defined(AUDIO_DRAIN)
- if (sndStatOut.isPCSpeaker)
- ioctl(sndStatOut.fd,AUDIO_DRAIN,0);
- else {
-#endif
-
- ioctl(sndStatIn.fd, SNDCTL_DSP_SYNC, NULL);
- if (sndStatOut.fd != sndStatIn.fd)
- ioctl(sndStatOut.fd, SNDCTL_DSP_SYNC, NULL);
-
-#if defined(AUDIO_DRAIN)
- }
-#endif
-
- if (doDebug) {
- fputs(" done.\n", stderr);
- fflush(stderr);
- }
- UNIDENTMSG;
-}
-
-
-static void
-#ifdef sco
-intervalProc(int i)
-#else
-intervalProc()
-#endif /* sco */
-{
- extern void AuProcessData();
-
-#ifndef sco
- signal(SIGALRM, SIG_IGN);
-
- if (processFlowEnabled)
- {
- AuProcessData();
- signal(SIGALRM, intervalProc);
- }
-#else
- if (!scoAudioBlocked && processFlowEnabled)
- AuProcessData();
-#endif /* sco */
-}
-
-/**
- * Gains are mapped thusly:
- *
- * Software s 0 - 100
- * Hardware h 0 - 100
-**/
-
-static void
-setPhysicalOutputGain(gain)
- AuFixedPoint gain;
-{
- AuInt32 g = AuFixedPointIntegralAddend(gain);
- AuInt32 i, gusvolume;
-
-
- if (g > 100)
- g = 100;
- if (g < 0)
- g = 0;
- Letsplay = g;
- gusvolume = g | (g << 8);
- if (mixerfd != -1)
- i = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &gusvolume);
-}
-
-static AuFixedPoint
-getPhysicalOutputGain()
-{
- AuInt16 outputGain;
-
- outputGain = Letsplay;
-
- return AuFixedPointFromSum(outputGain, 0);
-}
-
-static void
-setPhysicalInputGainAndLineMode(gain, lineMode)
- AuFixedPoint gain;
- AuUint8 lineMode;
-{
- AuInt16 g = AuFixedPointIntegralAddend(gain);
- AuInt16 inputAttenuation;
- AuInt16 zero = 0;
- AuInt32 params[4];
-
- if (g < 100)
- inputAttenuation = g;
- else
- inputAttenuation = 100;
-
- inputAttenuation = inputAttenuation << 8 | inputAttenuation;
-
- if (lineMode == AuDeviceLineModeHigh) {
- ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_MIC), &inputAttenuation);
- ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_LINE), &zero);
- }
-
- if (lineMode == AuDeviceLineModeLow) {
- ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_LINE), &inputAttenuation);
- ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_MIC), &zero);
- }
-}
-
-static void enableProcessFlow()
-{
- AuUint8 *p;
-
- PRMSG("enableProcessFlow();\n", 0, 0);
-
-#ifdef sco
- if (!processFlowEnabled)
- {
-#endif /* sco */
-
- processFlowEnabled = AuTrue;
-
-#ifndef sco
- signal(SIGALRM, intervalProc);
-#else
- setTimer(sndStatOut.curSampleRate);
-#endif /* sco */
-
-#ifdef sco
- }
-#endif /* sco */
-}
-
-static void disableProcessFlow()
-{
-
-#ifndef sco
- signal(SIGALRM, SIG_IGN);
-#endif /* sco */
-
- PRMSG("disableProcessFlow();\n", 0, 0);
-
-#ifdef sco
- if (processFlowEnabled)
- {
-#endif /* sco */
-
- ioctl(sndStatOut.fd, SNDCTL_DSP_SYNC, NULL);
-#ifndef sco
- ioctl(sndStatOut.fd, SNDCTL_DSP_SPEED, &sndStatOut.curSampleRate);
-#endif /* sco */
-
- if (sndStatOut.fd != sndStatIn.fd)
- {
- ioctl(sndStatIn.fd, SNDCTL_DSP_SYNC, NULL);
-#ifndef sco
- ioctl(sndStatIn.fd, SNDCTL_DSP_SPEED, &sndStatIn.curSampleRate);
-#endif /* sco */
- }
-
-#ifdef sco
- oneMoreTick();
-#endif
-
- processFlowEnabled = AuFalse;
-
-#ifdef sco
- }
-#endif /* sco */
-}
-
-
-#if defined(__GNUC__) && !defined(linux)
-inline
-#endif
-static void monoToStereoLinearSigned16LSB(numSamples)
-AuUint32 numSamples;
-{
- AuInt16 *s = (AuInt16*)monoOutputDevice->minibuf;
- AuInt16 *d = (AuInt16*)stereoOutputDevice->minibuf;
-
- while (numSamples--) {
- *d++ = *s;
- *d++ = *s++;
- }
-}
-
-#if defined(__GNUC__) && !defined(linux)
-inline
-#endif
-static void monoToStereoLinearUnsigned8(numSamples)
-AuUint32 numSamples;
-{
- AuUint8 *s = (AuUint8*)monoOutputDevice->minibuf;
- AuUint8 *d = (AuUint8*)stereoOutputDevice->minibuf;
-
- while (numSamples--) {
- *d++ = *s;
- *d++ = *s++;
- }
-}
-
-static void writePhysicalOutputsMono()
-{
- AuBlock l;
- void* buf;
- int bufSize;
-
- if (sndStatOut.isStereo) {
- switch (monoOutputDevice->format) {
- case AuFormatLinearSigned16LSB:
- monoToStereoLinearSigned16LSB(monoOutputDevice->minibufSamples);
- break;
-
- case AuFormatLinearUnsigned8:
- monoToStereoLinearUnsigned8(monoOutputDevice->minibufSamples);
- break;
-
- default:
- /* check createServerComponents(...)! */
- assert(0);
- }
-
- buf = stereoOutputDevice->minibuf;
- bufSize = stereoOutputDevice->bytesPerSample
- * monoOutputDevice->minibufSamples;
- } else {
- buf = monoOutputDevice->minibuf;
- bufSize = monoOutputDevice->bytesPerSample
- * monoOutputDevice->minibufSamples;
- }
-
- l = AuBlockAudio();
- { int b, w;
- char *p = buf ;
- for (b=bufSize; b>0; b -= w) {
- w = write(sndStatOut.fd, p, b);
- p += w ;
- }
- }
-
-#ifdef DEBUGDSPOUT
- {
- char tempbuf[80];
-
- sprintf(tempbuf, "\nwriteMono buf: %d size: %d\n", buf, bufSize);
- write(dspout, tempbuf, strlen(tempbuf));
- write(dspout, buf, bufSize);
- }
-#endif /* DEBUGDSPOUT */
-
- AuUnBlockAudio(l);
-}
-
-#if defined(__GNUC__) && !defined(linux)
-inline
-#endif
-static void stereoToMonoLinearSigned16LSB(numSamples)
-AuUint32 numSamples;
-{
- AuInt16 *s = (AuInt16*)stereoOutputDevice->minibuf;
- AuInt16 *d = (AuInt16*)monoOutputDevice->minibuf;
-
- while (numSamples--) {
- *d++ = (s[0] + s[1]) / 2;
- s += 2;
- }
-}
-
-#if defined(__GNUC__) && !defined(linux)
-inline
-#endif
-static void stereoToMonoLinearUnsigned8(numSamples)
-AuUint32 numSamples;
-{
- AuUint8 *s = (AuUint8*)stereoOutputDevice->minibuf;
- AuUint8 *d = (AuUint8*)monoOutputDevice->minibuf;
-
- while (numSamples--) {
- *d++ = (s[0] + s[1]) / 2;
- s += 2;
- }
-}
-
-static void writePhysicalOutputsStereo()
-{
- AuBlock l;
- void* buf;
- int bufSize;
-
- if (sndStatOut.isStereo) {
- buf = stereoOutputDevice->minibuf;
- bufSize = stereoOutputDevice->bytesPerSample
- * stereoOutputDevice->minibufSamples;
- } else {
- switch (stereoOutputDevice->format) {
- case AuFormatLinearSigned16LSB:
- stereoToMonoLinearSigned16LSB(stereoOutputDevice->minibufSamples);
- break;
-
- case AuFormatLinearUnsigned8:
- stereoToMonoLinearUnsigned8(stereoOutputDevice->minibufSamples);
- break;
-
- default:
- /* check createServerComponents(...)! */
- assert(0);
- }
-
- buf = monoOutputDevice->minibuf;
- bufSize = monoOutputDevice->bytesPerSample
- * stereoOutputDevice->minibufSamples;
- }
-
- l = AuBlockAudio();
- { int b, w;
- char *p = buf ;
- for (b=bufSize; b>0; b -= w) {
- w = write(sndStatOut.fd, p, b);
- p += w ;
- }
- }
-
-#ifdef DEBUGDSPOUT
- {
- char tempbuf[80];
-
- sprintf(tempbuf, "\nwriteStereo buf: %d size: %d\n", buf, bufSize);
- write(dspout, tempbuf, strlen(tempbuf));
- write(dspout, buf, bufSize);
- }
-#endif /* DEBUGDSPOUT */
-
- AuUnBlockAudio(l);
-}
-
-static void writePhysicalOutputsBoth()
-{
- AuInt16 *m = (AuInt16 *) monoOutputDevice->minibuf;
- AuInt16 *p, *s;
- AuUint8 *m8 = (AuUint8 *) monoOutputDevice->minibuf;
- AuUint8 *p8, *s8;
- AuUint32 max = aumax(monoOutputDevice->minibufSamples,
- stereoOutputDevice->minibufSamples);
- AuUint32 i;
-
- switch (stereoOutputDevice->format) {
- case AuFormatLinearSigned16LSB:
- p = s = (AuInt16 *) stereoOutputDevice->minibuf;
-
- for (i = 0; i < max; i++) {
- *p++ = (*m + *s++) / 2;
- *p++ = (*m++ + *s++) / 2;
- }
- break;
-
- case AuFormatLinearUnsigned8:
- p8 = s8 = (AuUint8 *) stereoOutputDevice->minibuf;
-
- for (i = 0; i < max; i++) {
- *p8++ = (*m8 + *s8++) / 2;
- *p8++ = (*m8++ + *s8++) / 2;
- }
- break;
-
- default:
- assert(0);
- }
-
- stereoOutputDevice->minibufSamples = max;
-
- writePhysicalOutputsStereo();
-}
-
-static void readPhysicalInputs()
-{
- AuBlock l;
- char *p = stereoInputDevice->minibuf ;
- int b,r ;
-
- /* Should make use of two input devices - FIXME */
- l = AuBlockAudio();
- for (b = stereoInputDevice->bytesPerSample * auMinibufSamples;
- b > 0 ; b -= r) {
- r = read(sndStatIn.fd, p, b);
- p += r ;
- }
-
-#ifdef DEBUGDSPIN
- {
- char tempbuf[80];
- sprintf(tempbuf, "\nreadInputs buf: %d size: %d\n",
- stereoInputDevice->minibuf,
- stereoInputDevice->bytesPerSample * auMinibufSamples);
- write(dspin, tempbuf, strlen(tempbuf));
- write(dspin, stereoInputDevice->minibuf,
- stereoInputDevice->bytesPerSample * auMinibufSamples);
- }
-#endif /* DEBUGDSPIN */
-
- AuUnBlockAudio(l);
-}
-
-static void
-noop()
-{
-}
-
-static void
-setWritePhysicalOutputFunction(flow, funct)
- CompiledFlowPtr flow;
- void (**funct) ();
-{
- AuUint32 mask = flow->physicalDeviceMask;
-
- if ((mask & (PhysicalOutputMono | PhysicalOutputStereo)) ==
- (PhysicalOutputMono | PhysicalOutputStereo))
- *funct = writePhysicalOutputsBoth;
- else if (mask & PhysicalOutputMono)
- *funct = writePhysicalOutputsMono;
- else if (mask & PhysicalOutputStereo)
- *funct = writePhysicalOutputsStereo;
- else
- *funct = noop;
-}
-
-/*
- * Setup soundcard at maximum audio quality.
- */
-
-#ifdef __FreeBSD__
-#define NO_16_BIT_SAMPLING
-#endif
-
-static void setupSoundcard(sndStatPtr)
-SndStat* sndStatPtr;
-{
- int samplesize;
-
- PRMSG("setupSoundcard(...);\n", 0, 0);
- IDENTMSG;
-
- if (beVerbose)
- if (sndStatPtr == &sndStatOut)
- fprintf (stderr, "++ Setting up Output device\n");
- else
- fprintf (stderr, "++ Setting up Input device\n");
-
- if (sndStatPtr->isPCSpeaker) {
- if (beVerbose)
- fprintf(stderr, "+++ Device is a PC speaker\n");
- sndStatPtr->curSampleRate = sndStatPtr->maxSampleRate
- = sndStatPtr->minSampleRate = 8000;
- sndStatPtr->isStereo = 0;
- sndStatPtr->wordSize = 8;
- }
- else {
- if (beVerbose)
- fprintf(stderr, "+++ requesting wordsize of %d, ", sndStatPtr->wordSize);
- if (ioctl(sndStatPtr->fd, SNDCTL_DSP_SAMPLESIZE, &sndStatPtr->wordSize)
- || sndStatPtr->wordSize != 16) {
- sndStatPtr->wordSize = 8;
- ioctl(sndStatPtr->fd, SNDCTL_DSP_SAMPLESIZE, &sndStatPtr->wordSize);
- }
- if (beVerbose)
- fprintf(stderr, "got %d\n", sndStatPtr->wordSize);
-
- if (beVerbose)
- fprintf(stderr, "+++ requesting %d channel(s), ", sndStatPtr->isStereo + 1);
- if (ioctl(sndStatPtr->fd, SNDCTL_DSP_STEREO, &sndStatPtr->isStereo) == -1
- || !sndStatPtr->isStereo) {
- sndStatPtr->isStereo = 0;
- ioctl(sndStatPtr->fd, SNDCTL_DSP_STEREO, &sndStatPtr->isStereo);
- }
- if (beVerbose)
- fprintf(stderr, "got %d channel(s)\n", sndStatPtr->isStereo + 1);
-
- if (beVerbose)
- fprintf (stderr, "+++ Requesting minimum sample rate of %d, ", sndStatPtr->minSampleRate);
- ioctl(sndStatPtr->fd, SNDCTL_DSP_SPEED, &sndStatPtr->minSampleRate);
- if (beVerbose)
- fprintf (stderr, "got %d\n", sndStatPtr->minSampleRate);
-
- if (beVerbose)
- fprintf (stderr, "+++ Requesting maximum sample rate of %d, ", sndStatPtr->maxSampleRate);
- ioctl(sndStatPtr->fd, SNDCTL_DSP_SPEED, &sndStatPtr->maxSampleRate);
- if (beVerbose)
- fprintf (stderr, "got %d\n", sndStatPtr->maxSampleRate);
-
- sndStatPtr->curSampleRate = sndStatPtr->maxSampleRate;
-
- }
-
-#if defined(SNDCTL_DSP_SETFRAGMENT)
- setFragmentSize(sndStatPtr);
-#endif
-
- UNIDENTMSG;
-}
-
-
-#ifdef sco
-static AuBool
-scoInterrupts()
-{
- struct sigaction act;
-
- act.sa_handler = intervalProc;
- act.sa_flags = 0;
- sigemptyset(&act.sa_mask);
- sigaddset(&act.sa_mask, SIGALRM);
- if (sigaction(SIGALRM, &act, (struct sigaction *)NULL) == -1)
- {
- ErrorF("sigaction SIGALRM");
- return FALSE;
- }
-
- return TRUE;
-}
-#endif /* sco */
-
-/*
-* Find the config file
-*/
-
-static FILE *openConfigFile (char *path)
-{
- static char buf[1024];
- FILE *config;
-
- strcat (buf, path);
- strcat (buf, "AUVoxConfig");
- if ((config = fopen (buf, "r")) != NULL)
- return config;
- else
- return NULL;
-}
-
-
-AuBool AuInitPhysicalDevices()
-{
- static AuBool AL_initialized = AuFalse;
- static AuUint8 *physicalBuffers;
- int fd;
- AuUint32 physicalBuffersSize;
- extern AuUint8 *auPhysicalOutputBuffers;
- extern AuUint32 auPhysicalOutputBuffersSize;
- extern void AuProcessData();
-#if defined(AUDIO_GETINFO)
- audio_info_t spkrinf;
-#endif
-
- PRMSG("AuInitPhysicalDevices();\n", 0, 0);
- IDENTMSG;
-
- /*
- * create the input and output ports
- */
- if (!AL_initialized) {
- int fd;
- AuInt32 i;
-
- AL_initialized = AuTrue;
-
- if ((yyin = openConfigFile (CONFSEARCHPATH)) != NULL)
- yyparse();
-
- if ((fd = open(sndStatOut.device, O_RDWR, 0)) == -1) {
- UNIDENTMSG;
- return AuFalse;
- }
-#if defined(AUDIO_GETINFO)
- if (sndStatOut.isPCSpeaker) {
- ioctl(fd, AUDIO_GETINFO, &spkrinf);
- spkrinf.play.encoding = AUDIO_ENCODING_RAW;
- ioctl(fd, AUDIO_SETINFO, &spkrinf);
- }
-#endif
-
-#ifdef DEBUGDSPOUT
- dspout = open("/tmp/dspout", O_RDWR | O_CREAT, 00666);
-#endif
-#ifdef DEBUGDSPIN
- dspin = open("/tmp/dspin", O_RDWR | O_CREAT, 00666);
-#endif
-
- sndStatOut.fd = fd;
-
- if ((fd = open(sndStatIn.device, O_RDONLY, 0)) != -1)
- sndStatIn.fd = fd;
- else
- sndStatIn.fd = sndStatOut.fd;
-
- setupSoundcard(&sndStatOut);
- if (sndStatOut.fd != sndStatIn.fd)
- setupSoundcard(&sndStatIn);
-
- if (!sndStatOut.isPCSpeaker) {
- if ((mixerfd = open("/dev/mixer", O_RDONLY, 0)) == -1) {
- UNIDENTMSG;
- return AuFalse;
- }
-
- if (ioctl(mixerfd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
- close(mixerfd);
- mixerfd = -1;
- } else {
- if (ioctl(mixerfd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
- return AuFalse;
- }
-
- {
- /* Enable all used recording sources ( mic & line ) and
- * control which is active via level setting later. There
- * should be a better way to do this!
- */
- int mask = SOUND_MASK_MIC | SOUND_MASK_LINE; /* enable these */
- mask &= recmask; /* if supported */
- if (ioctl(mixerfd, SOUND_MIXER_WRITE_RECSRC, &mask) == -1) {
- return AuFalse;
- }
- }
-
- if (ioctl(mixerfd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
- UNIDENTMSG;
- return AuFalse;
- }
-
- if (ioctl(mixerfd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) {
- UNIDENTMSG;
- return AuFalse;
- }
-
- /* get all sound levels */
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
- if ((1 << i) & devmask) {
-
- if (ioctl(mixerfd, MIXER_READ(i), &level[i]) == -1) {
- UNIDENTMSG;
- return AuFalse;
- }
- }
- }
-
- }
- }
- }
-
- if (physicalBuffers)
- aufree(physicalBuffers);
-
- auMinibufSamples = MAX_MINIBUF_SAMPLES;
-
- /* the output buffers need to be twice as large for output range checking */
- physicalBuffersSize =
- PhysicalTwoTrackBufferSize + /* mono/stereo input */
- PhysicalOneTrackBufferSize * 2 + /* mono output */
- PhysicalTwoTrackBufferSize * 2; /* stereo output */
-
- if (!(physicalBuffers = (AuUint8 *) aualloc(physicalBuffersSize))) {
- UNIDENTMSG;
- return AuFalse;
- }
-
- auInput = physicalBuffers;
- auOutputMono = auInput + PhysicalTwoTrackBufferSize;
- auOutputStereo = auOutputMono + 2 * PhysicalOneTrackBufferSize;
-
- auPhysicalOutputBuffers = auOutputMono;
- auPhysicalOutputBuffersSize = physicalBuffersSize -
- PhysicalTwoTrackBufferSize;
-
- /*
- * Call AuProcessData() in signal handler often enough to drain the
- * input devices and keep the output devices full at the current
- * sample rate.
- */
-
- processFlowEnabled = AuFalse;
-
-#ifdef sco
- if (!scoInterrupts())
- {
- return AuFalse;
- }
-#else
- signal(SIGALRM, intervalProc);
-#endif /* sco */
-
- setTimer(0);
-
- AuRegisterCallback(AuCreateServerComponentsCB, createServerComponents);
- AuRegisterCallback(AuSetPhysicalOutputGainCB, setPhysicalOutputGain);
- AuRegisterCallback(AuGetPhysicalOutputGainCB, getPhysicalOutputGain);
- AuRegisterCallback(AuSetPhysicalInputGainAndLineModeCB,
- setPhysicalInputGainAndLineMode);
- AuRegisterCallback(AuEnableProcessFlowCB, enableProcessFlow);
- AuRegisterCallback(AuDisableProcessFlowCB, disableProcessFlow);
- AuRegisterCallback(AuReadPhysicalInputsCB, readPhysicalInputs);
- AuRegisterCallback(AuSetWritePhysicalOutputFunctionCB,
- setWritePhysicalOutputFunction);
-
- AuRegisterCallback(AuSetSampleRateCB, setSampleRate);
-
- /* bogus resource so we can have a cleanup function at server reset */
- AddResource(FakeClientID(SERVER_CLIENT),
- CreateNewResourceType(serverReset), 0);
-
- UNIDENTMSG;
-
- return AuTrue;
-}
diff --git a/sys/i386/isa/snd/misc/files.i386 b/sys/i386/isa/snd/misc/files.i386
deleted file mode 100644
index bc12938..0000000
--- a/sys/i386/isa/snd/misc/files.i386
+++ /dev/null
@@ -1,240 +0,0 @@
-# This file tells config what files go into building a kernel,
-# files marked standard are always included.
-#
-# $Id: files.i386,v 1.141.2.11 1997/04/04 04:35:46 gibbs Exp $
-#
-aic7xxx_asm optional ahc device-driver \
- dependency "$S/dev/aic7xxx/*.[chyl]" \
- compile-with "cd $S/dev/aic7xxx; make obj; make BINDIR=${.CURDIR} all install" \
- no-obj no-implicit-rule \
- clean "aic7xxx_asm"
-#
-aic7xxx_{seq,reg}.h optional ahc device-driver \
- compile-with "./aic7xxx_asm ${INCLUDES} -o aic7xxx_seq.h -r aic7xxx_reg.h $S/dev/aic7xxx/aic7xxx.seq" \
- no-obj no-implicit-rule before-depend \
- clean "aic7xxx_seq.h aic7xxx_reg.h" \
- dependency "$S/dev/aic7xxx/aic7xxx.{reg,seq} aic7xxx_asm"
-#
-linux_genassym optional compat_linux \
- dependency "$S/i386/linux/linux_genassym.c $S/i386/linux/linux.h" \
- compile-with "${CC} ${CFLAGS} ${PARAM} -UKERNEL -o $@ $<" \
- no-obj no-implicit-rule \
- clean "linux_genassym"
-#
-linux_assym.h optional compat_linux \
- dependency "linux_genassym" \
- compile-with "./linux_genassym > $@" \
- no-obj no-implicit-rule before-depend \
- clean "linux_assym.h"
-#
-i386/scsi/93cx6.c optional ahc device-driver
-i386/apm/apm.c optional apm device-driver
-i386/apm/apm_setup.s optional apm
-i386/eisa/3c5x9.c optional ep device-driver
-i386/eisa/aic7770.c optional ahc device-driver \
- dependency "aic7xxx_reg.h $S/i386/eisa/aic7770.c"
-i386/eisa/aha1742.c optional ahb device-driver
-i386/eisa/bt74x.c optional bt device-driver
-i386/eisa/eisaconf.c optional eisa
-i386/eisa/if_vx_eisa.c optional vx device-driver
-i386/eisa/if_fea.c optional fea device-driver
-i386/i386/autoconf.c standard device-driver
-i386/i386/cons.c standard
-i386/i386/db_disasm.c optional ddb
-i386/i386/db_interface.c optional ddb
-i386/i386/db_trace.c optional ddb
-i386/i386/i386-gdbstub.c optional ddb
-i386/i386/exception.s standard
-i386/i386/identcpu.c standard
-i386/i386/in_cksum.c optional inet
-# locore.s needs to be handled in Makefile to put it first. Otherwise it's
-# now normal.
-# i386/i386/locore.s standard
-i386/i386/machdep.c standard
-i386/i386/math_emulate.c optional math_emulate
-i386/i386/mem.c standard
-i386/i386/microtime.s standard
-i386/i386/perfmon.c optional perfmon profiling-routine
-i386/i386/perfmon.c optional perfmon
-i386/i386/pmap.c standard
-i386/i386/procfs_machdep.c standard
-i386/i386/support.s standard
-i386/i386/swtch.s standard
-i386/i386/sys_machdep.c standard
-i386/i386/trap.c standard
-i386/i386/userconfig.c optional userconfig
-i386/i386/vm_machdep.c standard
-i386/ibcs2/ibcs2_fcntl.c optional ibcs2
-i386/ibcs2/ibcs2_stat.c optional ibcs2
-i386/ibcs2/ibcs2_ipc.c optional ibcs2
-i386/ibcs2/ibcs2_msg.c optional ibcs2
-i386/ibcs2/ibcs2_misc.c optional ibcs2
-i386/ibcs2/ibcs2_other.c optional ibcs2
-i386/ibcs2/ibcs2_signal.c optional ibcs2
-i386/ibcs2/ibcs2_ioctl.c optional ibcs2
-i386/ibcs2/ibcs2_socksys.c optional ibcs2
-i386/ibcs2/ibcs2_sysi86.c optional ibcs2
-i386/ibcs2/ibcs2_util.c optional ibcs2
-i386/ibcs2/ibcs2_isc.c optional ibcs2
-i386/ibcs2/ibcs2_isc_sysent.c optional ibcs2
-i386/ibcs2/ibcs2_xenix.c optional ibcs2
-i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2
-i386/ibcs2/ibcs2_errno.c optional ibcs2
-i386/ibcs2/ibcs2_sysent.c optional ibcs2
-i386/ibcs2/ibcs2_sysvec.c optional ibcs2
-i386/ibcs2/imgact_coff.c optional ibcs2
-i386/isa/aha1542.c optional aha device-driver
-i386/isa/aic6360.c optional aic device-driver
-i386/isa/b004.c optional bqu device-driver
-i386/isa/bt5xx-445.c optional bt device-driver
-i386/isa/clock.c standard
-i386/isa/cronyx.c optional cx device-driver
-i386/isa/ctx.c optional ctx device-driver
-i386/isa/cx.c optional cx device-driver
-i386/isa/cy.c optional cy device-driver
-i386/isa/diskslice_machdep.c standard
-i386/isa/elink.c optional ep device-driver
-i386/isa/elink.c optional ie device-driver
-i386/isa/fd.c optional fd device-driver
-i386/isa/ft.c optional ft device-driver
-i386/isa/gpib.c optional gp device-driver
-i386/isa/asc.c optional asc device-driver
-i386/isa/gsc.c optional gsc device-driver
-i386/isa/if_ar.c optional ar device-driver
-i386/isa/if_cx.c optional cx device-driver
-i386/isa/if_ed.c optional ed device-driver
-i386/isa/if_eg.c optional eg device-driver
-i386/isa/if_el.c optional el device-driver
-i386/isa/if_ep.c optional ep device-driver
-i386/isa/if_ex.c optional ex device-driver
-i386/isa/if_fe.c optional fe device-driver
-i386/isa/if_ie.c optional ie device-driver
-i386/isa/if_ix.c optional ix device-driver
-i386/isa/if_le.c optional le device-driver
-i386/isa/if_lnc.c optional lnc device-driver
-i386/isa/if_sr.c optional sr device-driver
-i386/isa/if_ze.c optional ze device-driver
-i386/isa/if_zp.c optional zp device-driver
-i386/isa/isa.c optional isa device-driver
-i386/isa/istallion.c optional stli device-driver
-i386/isa/joy.c optional joy device-driver
-i386/isa/kbdio.c optional psm device-driver
-i386/isa/kbdio.c optional sc device-driver
-i386/isa/kbdio.c optional vt device-driver
-i386/isa/lpt.c optional lpt device-driver
-i386/isa/labpc.c optional labpc device-driver
-i386/isa/mcd.c optional mcd device-driver
-i386/isa/mse.c optional mse device-driver
-i386/isa/ncr5380.c optional nca device-driver
-i386/isa/npx.c optional npx device-driver
-i386/isa/pcaudio.c optional pca device-driver
-i386/isa/matcd/matcd.c optional matcd device-driver
-i386/isa/pcibus.c optional pci device-driver
-i386/isa/pcicx.c optional ze device-driver
-i386/isa/pcicx.c optional zp device-driver
-i386/isa/pcvt/pcvt_drv.c optional vt device-driver
-i386/isa/pcvt/pcvt_ext.c optional vt device-driver
-i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
-i386/isa/pcvt/pcvt_out.c optional vt device-driver
-i386/isa/pcvt/pcvt_sup.c optional vt device-driver
-i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
-i386/isa/pnp.c optional pnp device-driver
-i386/isa/prof_machdep.c optional profiling-routine
-i386/isa/psm.c optional psm device-driver
-i386/isa/qcam.c optional qcam device-driver
-i386/isa/qcamio.c optional qcam device-driver
-i386/isa/random_machdep.c standard
-i386/isa/rc.c optional rc device-driver
-i386/isa/scd.c optional scd device-driver
-i386/isa/seagate.c optional sea device-driver
-i386/isa/si.c optional si device-driver
-i386/isa/si_code.c optional si device-driver
-i386/isa/sio.c optional sio device-driver
-i386/isa/snd/sound.c optional pcm device-driver
-i386/isa/snd/dmabuf.c optional pcm device-driver
-i386/isa/snd/ad1848.c optional pcm device-driver
-i386/isa/snd/sb_dsp.c optional pcm device-driver
-i386/isa/snd/clones.c optional pcm device-driver
-i386/isa/spigot.c optional spigot device-driver
-i386/isa/spkr.c optional speaker device-driver
-i386/isa/stallion.c optional stl device-driver
-i386/isa/syscons.c optional sc device-driver
-i386/isa/tw.c optional tw device-driver
-i386/isa/ultra14f.c optional uha device-driver
-i386/isa/wd.c optional wdc device-driver
-i386/isa/wd.c optional wd device-driver
-i386/isa/atapi.c optional atapi device-driver
-i386/isa/wcd.c optional wcd device-driver
-i386/isa/wd7000.c optional wds device-driver
-i386/isa/wt.c optional wt device-driver
-i386/linux/imgact_linux.c optional compat_linux
-i386/linux/linux_dummy.c optional compat_linux
-i386/linux/linux_file.c optional compat_linux
-i386/linux/linux_ioctl.c optional compat_linux
-i386/linux/linux_ipc.c optional compat_linux
-i386/linux/linux_locore.s optional compat_linux \
- dependency "linux_assym.h"
-i386/linux/linux_misc.c optional compat_linux
-i386/linux/linux_signal.c optional compat_linux
-i386/linux/linux_socket.c optional compat_linux
-i386/linux/linux_stats.c optional compat_linux
-i386/linux/linux_sysent.c optional compat_linux
-i386/linux/linux_sysvec.c optional compat_linux
-i386/linux/linux_util.c optional compat_linux
-i386/scsi/aic7xxx.c optional ahc device-driver \
- dependency "aic7xxx_{reg,seq}.h"
-i386/scsi/bt.c optional bt device-driver
-libkern/bcd.c standard
-libkern/divdi3.c standard
-libkern/inet_ntoa.c standard
-libkern/index.c standard
-libkern/mcount.c optional profiling-routine
-libkern/moddi3.c standard
-libkern/qdivrem.c standard
-libkern/qsort.c standard
-libkern/random.c standard
-libkern/scanc.c standard
-libkern/skpc.c standard
-libkern/strcat.c standard
-libkern/strcmp.c standard
-libkern/strcpy.c standard
-libkern/strlen.c standard
-libkern/strncmp.c standard
-libkern/strncpy.c standard
-libkern/udivdi3.c standard
-libkern/umoddi3.c standard
-gnu/i386/fpemul/div_small.s optional gpl_math_emulate
-gnu/i386/fpemul/errors.c optional gpl_math_emulate
-gnu/i386/fpemul/fpu_arith.c optional gpl_math_emulate
-gnu/i386/fpemul/fpu_aux.c optional gpl_math_emulate
-gnu/i386/fpemul/fpu_entry.c optional gpl_math_emulate
-gnu/i386/fpemul/fpu_etc.c optional gpl_math_emulate
-gnu/i386/fpemul/fpu_trig.c optional gpl_math_emulate
-gnu/i386/fpemul/get_address.c optional gpl_math_emulate
-gnu/i386/fpemul/load_store.c optional gpl_math_emulate
-gnu/i386/fpemul/poly_2xm1.c optional gpl_math_emulate
-gnu/i386/fpemul/poly_atan.c optional gpl_math_emulate
-gnu/i386/fpemul/poly_div.s optional gpl_math_emulate
-gnu/i386/fpemul/poly_l2.c optional gpl_math_emulate
-gnu/i386/fpemul/poly_mul64.s optional gpl_math_emulate
-gnu/i386/fpemul/poly_sin.c optional gpl_math_emulate
-gnu/i386/fpemul/poly_tan.c optional gpl_math_emulate
-gnu/i386/fpemul/polynomial.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_add_sub.c optional gpl_math_emulate
-gnu/i386/fpemul/reg_compare.c optional gpl_math_emulate
-gnu/i386/fpemul/reg_constant.c optional gpl_math_emulate
-gnu/i386/fpemul/reg_div.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_ld_str.c optional gpl_math_emulate
-gnu/i386/fpemul/reg_mul.c optional gpl_math_emulate
-gnu/i386/fpemul/reg_norm.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_round.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_u_add.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_u_div.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate
-gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate
-gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate
-gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
-gnu/i386/isa/dgb.c optional dgb device-driver
-gnu/i386/isa/nic3008.c optional nic device-driver
-gnu/i386/isa/nic3009.c optional nnic device-driver
-pci/wd82371.c optional wd device-driver
diff --git a/sys/i386/isa/snd/misc/linux.patch b/sys/i386/isa/snd/misc/linux.patch
deleted file mode 100644
index aacfcbc..0000000
--- a/sys/i386/isa/snd/misc/linux.patch
+++ /dev/null
@@ -1,41 +0,0 @@
---- linux.h.orig Tue Dec 3 16:47:28 1996
-+++ linux.h Mon Nov 17 00:05:29 1997
-@@ -491,6 +491,9 @@
- #define LINUX_SNDCTL_DSP_GETOSPACE 0x500C
- #define LINUX_SNDCTL_DSP_GETISPACE 0x500D
- #define LINUX_SNDCTL_DSP_NONBLOCK 0x500E
-+#define LINUX_SNDCTL_DSP_GETCAPS 0x500F
-+#define LINUX_SNDCTL_DSP_GETIPTR 0x5011
-+#define LINUX_SNDCTL_DSP_GETOPTR 0x5012
- #define LINUX_SOUND_MIXER_WRITE_VOLUME 0x4d00
- #define LINUX_SOUND_MIXER_WRITE_BASS 0x4d01
- #define LINUX_SOUND_MIXER_WRITE_TREBLE 0x4d02
---- linux_ioctl.c.orig Sat Nov 9 22:10:15 1996
-+++ linux_ioctl.c Mon Nov 17 10:20:14 1997
-@@ -691,6 +691,26 @@
- args->cmd = SNDCTL_DSP_NONBLOCK;
- return ioctl(p, (struct ioctl_args *)args, retval);
-
-+ case LINUX_SNDCTL_DSP_GETCAPS:
-+ args->cmd = SNDCTL_DSP_GETCAPS;
-+ return ioctl(p, (struct ioctl_args *)args, retval);
-+
-+ case LINUX_SNDCTL_DSP_GETIPTR:
-+ args->cmd = SNDCTL_DSP_GETIPTR;
-+ return ioctl(p, (struct ioctl_args *)args, retval);
-+
-+ case LINUX_SNDCTL_DSP_GETOPTR:
-+ args->cmd = SNDCTL_DSP_GETOPTR;
-+ { int a= ioctl(p, (struct ioctl_args *)args, retval);
-+ struct count_info *p = (struct count_info *)(args->arg);
-+#if 0
-+ p->bytes += 128 ;
-+ uprintf("GETOPTR bytes %d blk %d ptr %d\n",
-+ p->bytes, p->blocks, p->ptr);
-+#endif
-+ return a;
-+ }
-+
- case LINUX_SOUND_MIXER_WRITE_VOLUME:
- args->cmd = SOUND_MIXER_WRITE_VOLUME;
- return ioctl(p, (struct ioctl_args *)args, retval);
diff --git a/sys/i386/isa/snd/misc/linux_a.c b/sys/i386/isa/snd/misc/linux_a.c
deleted file mode 100644
index 3a86aad..0000000
--- a/sys/i386/isa/snd/misc/linux_a.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * TiMidity -- Experimental MIDI to WAVE converter Copyright (C) 1995 Tuukka
- * Toivonen <toivonen@clinet.fi>
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- *
- * linux_audio.c
- *
- * Functions to play sound on the VoxWare audio driver (Linux or FreeBSD)
- *
- */
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#ifdef linux
-#include <sys/ioctl.h> /* new with 1.2.0? Didn't need this under
- * 1.1.64 */
-#include <linux/soundcard.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <stdio.h>
-#include <machine/soundcard.h>
-#endif
-
-#include "config.h"
-#include "output.h"
-#include "controls.h"
-
-static int open_output(void); /* 0=success, 1=warning, -1=fatal
- * error */
-static void close_output(void);
-static void output_data(int32 * buf, int32 count);
-static void flush_output(void);
-static void purge_output(void);
-
-/* export the playback mode */
-
-#define dpm linux_play_mode
-
-PlayMode dpm = {
- DEFAULT_RATE, PE_16BIT | PE_SIGNED,
- -1,
- {0}, /* default: get all the buffer fragments you
- * can */
- "Linux dsp device", 'd',
- "/dev/dsp",
- open_output,
- close_output,
- output_data,
- flush_output,
- purge_output
-};
-
-
-/*************************************************************************/
-/*
- * We currently only honor the PE_MONO bit, the sample rate, and the number
- * of buffer fragments. We try 16-bit signed data first, and then 8-bit
- * unsigned if it fails. If you have a sound device that can't handle either,
- * let me know.
- */
-
-static int
-open_output(void)
-{
- int fd, tmp, i, warnings = 0;
-
- /* Open the audio device */
- fd = open(dpm.name, O_RDWR /* | O_NDELAY */);
- if (fd < 0) {
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
- dpm.name, sys_errlist[errno]);
- return -1;
- }
- /* They can't mean these */
- dpm.encoding &= ~(PE_ULAW | PE_BYTESWAP);
-
-
- /*
- * Set sample width to whichever the user wants. If it fails, try the
- * other one.
- */
-
- i = tmp = (dpm.encoding & PE_16BIT) ? 16 : 8;
- if (dpm.encoding & PE_16BIT) {
- int fmt = AFMT_S16_LE ;
-
- if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0 || fmt != AFMT_S16_LE) {
- fmt = AFMT_U8 ;
- if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0 || fmt != AFMT_U8) {
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
- "%s doesn't support 16- or 8-bit sample width",
- dpm.name);
- close(fd);
- return -1;
- }
- ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
- "Sample width adjusted to %d bits", tmp);
- dpm.encoding ^= PE_16BIT;
- warnings = 1;
- }
- }
- if (dpm.encoding & PE_16BIT)
- dpm.encoding |= PE_SIGNED;
- else
- dpm.encoding &= ~PE_SIGNED;
-
-
- /*
- * Try stereo or mono, whichever the user wants. If it fails, try the
- * other.
- */
-
- i = tmp = (dpm.encoding & PE_MONO) ? 0 : 1;
- if ((ioctl(fd, SNDCTL_DSP_STEREO, &tmp) < 0) || tmp != i) {
- i = tmp = (dpm.encoding & PE_MONO) ? 1 : 0;
-
- if ((ioctl(fd, SNDCTL_DSP_STEREO, &tmp) < 0) || tmp != i) {
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
- "%s doesn't support mono or stereo samples",
- dpm.name);
- close(fd);
- return -1;
- }
- if (tmp == 0)
- dpm.encoding |= PE_MONO;
- else
- dpm.encoding &= ~PE_MONO;
- ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Sound adjusted to %sphonic",
- (tmp == 0) ? "mono" : "stereo");
- warnings = 1;
- }
- /* Set the sample rate */
-
- tmp = dpm.rate;
- if (ioctl(fd, SNDCTL_DSP_SPEED, &tmp) < 0) {
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
- "%s doesn't support a %d Hz sample rate",
- dpm.name, dpm.rate);
- close(fd);
- return -1;
- }
- if (tmp != dpm.rate) {
- dpm.rate = tmp;
- ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
- "Output rate adjusted to %d Hz", dpm.rate);
- warnings = 1;
- }
- /* Older VoxWare drivers don't have buffer fragment capabilities */
-#ifdef SNDCTL_DSP_SETFRAGMENT
- /* Set buffer fragments (in extra_param[0]) */
-
- tmp = 2+ AUDIO_BUFFER_BITS ;
- if (!(dpm.encoding & PE_MONO))
- tmp++;
- if (dpm.encoding & PE_16BIT)
- tmp++;
- tmp |= (dpm.extra_param[0] << 16);
- i = tmp;
- if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) < 0) {
- ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
- "%s doesn't support %d-byte buffer fragments", dpm.name, (1 << i));
- /*
- * It should still work in some fashion. We should use a secondary
- * buffer anyway -- 64k isn't enough.
- */
- warnings = 1;
- }
-#else
- if (dpm.extra_param[0]) {
- ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
- "%s doesn't support buffer fragments", dpm.name);
- warnings = 1;
- }
-#endif
-
- dpm.fd = fd;
-
- return warnings;
-}
-
-static void
-output_data(int32 * buf, int32 count)
-{
- char *p;
- int res, l;
-
- if (!(dpm.encoding & PE_MONO))
- count *= 2; /* Stereo samples */
-
- if (dpm.encoding & PE_16BIT) {
- /* Convert data to signed 16-bit PCM */
- s32tos16(buf, count);
- res = count*2;
- } else {
- /* Convert to 8-bit unsigned and write out. */
- s32tou8(buf, count);
- res = count ;
- }
- for (p = buf ; res > 0 ; res -= l ) {
- l = write(dpm.fd, p, res);
- if (l < 0) return ;
- p += l ;
- }
-}
-
-static void
-close_output(void)
-{
- close(dpm.fd);
-}
-
-static void
-flush_output(void)
-{
- ioctl(dpm.fd, SNDCTL_DSP_SYNC);
-}
-
-static void
-purge_output(void)
-{
- ioctl(dpm.fd, SNDCTL_DSP_RESET);
-}
diff --git a/sys/i386/isa/snd/misc/mmap_test.c b/sys/i386/isa/snd/misc/mmap_test.c
deleted file mode 100644
index f9e8b3e..0000000
--- a/sys/i386/isa/snd/misc/mmap_test.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * This is a simple program which demonstrates use of mmapped DMA buffer
- * of the sound driver directly from application program.
- *
- * This sample program works (currently) only with Linux, FreeBSD and BSD/OS
- * (FreeBSD and BSD/OS require OSS version 3.8-beta16 or later.
- *
- * Note! Don't use mmapped DMA buffers (direct audio) unless you have
- * very good reasons to do it. Programs using this feature will not
- * work with all soundcards. GUS (GF1) is one of them (GUS MAX works).
- *
- * This program requires version 3.5-beta7 or later of OSS
- * (3.8-beta16 or later in FreeBSD and BSD/OS).
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/soundcard.h>
-#include <sys/time.h>
-
-main()
-{
- int fd, sz, fsz, i, tmp, n, l, have_data=0, nfrag;
- int caps;
-
- int sd, sl=0, sp;
-
- unsigned char data[500000], *dp = data;
-
- struct buffmem_desc imemd, omemd;
- caddr_t buf;
- struct timeval tim;
-
- unsigned char *op;
-
- struct audio_buf_info info;
-
- int frag = 0xffff000c; /* Max # fragments of 2^13=8k bytes */
-
- fd_set writeset;
-
- close(0);
- if ((fd=open("/dev/dsp", O_RDWR, 0))==-1)
- {
- perror("/dev/dsp");
- exit(-1);
- }
-/*
- * Then setup sampling parameters. Just sampling rate in this case.
- */
-
- tmp = 48000;
- ioctl(fd, SNDCTL_DSP_SPEED, &tmp);
- printf("Speed set to %d\n", tmp);
-
-/*
- * Load some test data.
- */
-
- sl = sp = 0;
- if ((sd=open("smpl", O_RDONLY, 0))!=-1)
- {
- sl = read(sd, data, sizeof(data));
- printf("%d bytes read from file.\n", sl);
- close(sd);
- }
- else perror("smpl");
-
- if (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
- {
- perror("/dev/dsp");
- fprintf(stderr, "Sorry but your sound driver is too old\n");
- exit(-1);
- }
-
-/*
- * Check that the device has capability to do this. Currently just
- * CS4231 based cards will work.
- *
- * The application should also check for DSP_CAP_MMAP bit but this
- * version of driver doesn't have it yet.
- */
-/* ioctl(fd, SNDCTL_DSP_SETSYNCRO, 0); */
-
-/*
- * You need version 3.5-beta7 or later of the sound driver before next
- * two lines compile. There is no point to modify this program to
- * compile with older driver versions since they don't have working
- * mmap() support.
- */
- if (!(caps & DSP_CAP_TRIGGER) ||
- !(caps & DSP_CAP_MMAP))
- {
- fprintf(stderr, "Sorry but your soundcard can't do this\n");
- exit(-1);
- }
-
-/*
- * Select the fragment size. This is propably important only when
- * the program uses select(). Fragment size defines how often
- * select call returns.
- */
-
- ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
-
-/*
- * Compute total size of the buffer. It's important to use this value
- * in mmap() call.
- */
-
- if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
- {
- perror("GETOSPACE");
- exit(-1);
- }
-
- sz = info.fragstotal * info.fragsize;
- fsz = info.fragsize;
-
-/*
- * Call mmap().
- *
- * IMPORTANT NOTE!!!!!!!!!!!
- *
- * Full duplex audio devices have separate input and output buffers.
- * It is not possible to map both of them at the same mmap() call. The buffer
- * is selected based on the prot argument in the following way:
- *
- * - PROT_READ (alone) selects the input buffer.
- * - PROT_WRITE (alone) selects the output buffer.
- * - PROT_WRITE|PROT_READ together select the output buffer. This combination
- * is required in BSD to make the buffer accessible. With just PROT_WRITE
- * every attempt to access the returned buffer will result in segmentation/bus
- * error. PROT_READ|PROT_WRITE is also permitted in Linux with OSS version
- * 3.8-beta16 and later (earlier versions don't accept it).
- *
- * Non duplex devices have just one buffer. When an application wants to do both
- * input and output it's recommended that the device is closed and re-opened when
- * switching between modes. PROT_READ|PROT_WRITE can be used to open the buffer
- * for both input and output (with OSS 3.8-beta16 and later) but the result may be
- * unpredictable.
- */
-
- if ((buf=mmap(NULL, sz, PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0))==(caddr_t)-1)
- {
- perror("mmap (write)");
- exit(-1);
- }
- printf("mmap (out) returned %08x\n", buf);
- op=buf;
-
-/*
- * op contains now a pointer to the DMA buffer
- */
-
-/*
- * Then it's time to start the engine. The driver doesn't allow read() and/or
- * write() when the buffer is mapped. So the only way to start operation is
- * to togle device's enable bits. First set them off. Setting them on enables
- * recording and/or playback.
- */
-
- tmp = 0;
- ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp);
- printf("Trigger set to %08x\n", tmp);
-
-/*
- * It might be usefull to write some data to the buffer before starting.
- */
-
- tmp = PCM_ENABLE_OUTPUT;
- ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp);
- printf("Trigger set to %08x\n", tmp);
-
-/*
- * The machine is up and running now. Use SNDCTL_DSP_GETOPTR to get the
- * buffer status.
- *
- * NOTE! The driver empties each buffer fragmen after they have been
- * played. This prevents looping sound if there are some performance problems
- * in the application side. For similar reasons it recommended that the
- * application uses some amout of play ahead. It can rewrite the unplayed
- * data later if necessary.
- */
-
- nfrag = 0;
- while (1)
- {
- struct count_info count;
- int p, l, extra;
-
- FD_ZERO(&writeset);
- FD_SET(fd, &writeset);
-
- tim.tv_sec = 10;
- tim.tv_usec= 0;
-
- select(fd+1, &writeset, &writeset, NULL, NULL);
-/*
- * SNDCTL_DSP_GETOPTR (and GETIPTR as well) return three items. The
- * bytes field returns number of bytes played since start. It can be used
- * as a real time clock.
- *
- * The blocks field returns number of fragment transitions (interrupts) since
- * previous GETOPTR call. It can be used as a method to detect underrun
- * situations.
- *
- * The ptr field is the DMA pointer inside the buffer area (in bytes from
- * the beginning of total buffer area).
- */
-
- if (ioctl(fd, SNDCTL_DSP_GETOPTR, &count)==-1)
- {
- perror("GETOPTR");
- exit(-1);
- }
-
- nfrag += count.blocks;
-
-#ifdef VERBOSE
-
- printf("\rTotal: %09d, Fragment: %03d, Ptr: %06d",
- count.bytes, nfrag, count.ptr);
- fflush(stdout);
-#endif
-
-/*
- * Caution! This version doesn't check for bounds of the DMA
- * memory area. It's possible that the returned pointer value is not aligned
- * to fragment boundaries. It may be several samples behind the boundary
- * in case there was extra delay between the actual hardware interrupt and
- * the time when DSP_GETOPTR was called.
- *
- * Don't just call memcpy() with length set to 'fragment_size' without
- * first checking that the transfer really fits to the buffer area.
- * A mistake of just one byte causes seg fault. It may be easiest just
- * to align the returned pointer value to fragment boundary before using it.
- *
- * It would be very good idea to write few extra samples to next fragment
- * too. Otherwise several (uninitialized) samples from next fragment
- * will get played before your program gets chance to initialize them.
- * Take in count the fact thaat there are other processes batling about
- * the same CPU. This effect is likely to be very annoying if fragment
- * size is decreased too much.
- */
-
-/*
- * Just a minor clarification to the above. The following line alings
- * the pointer to fragment boundaries. Note! Don't trust that fragment
- * size is always a power of 2. It may not be so in future.
- */
- count.ptr = (count.ptr/fsz)*fsz;
-
-#ifdef VERBOSE
- printf(" memcpy(%6d, %4d)", (dp-data), fsz);
- fflush(stdout);
-#endif
-
-/*
- * Set few bytes in the beginning of next fragment too.
- */
- if ((count.ptr+fsz+16) < sz) /* Last fragment? */
- extra = 16;
- else
- extra = 0;
-
- memcpy(op+count.ptr, dp, fsz+extra);
-
- dp += fsz;
- if (dp > (data+sl-fsz))
- dp = data;
- }
-
- exit(0);
-}
diff --git a/sys/i386/isa/snd/misc/pcmio.c b/sys/i386/isa/snd/misc/pcmio.c
deleted file mode 100644
index 5bab10e..0000000
--- a/sys/i386/isa/snd/misc/pcmio.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * pcmio.c -- a simple utility for controlling audio I/O
- * (rate, channels, resolution...)
- *
- * (C) Luigi Rizzo 1998
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <machine/soundcard.h>
-
-char * usage_string =
-"Usage: %s [-f device] [+parameters] [len:skip] file { file }\n"
-"where device is the device to be used (default /dev/audio)\n"
-"[len:skip] is the subsection of the file to be played\n"
-"with a '-' indicating the default\n"
-"and parameters is a comma-separated list containing one or more of\n"
-" N the sampling speed\n"
-" stereo|mono \n"
-" cd|u8|alaw|ulaw|s16 data format\n"
-" loop loop (play cyclically)\n"
-;
-
-#define BLKSZ 32768
-int format=AFMT_MU_LAW;
-int rate=8000 ;
-int stereo = 0 ;
-char dev[128];
-int audiodev;
-int play = 1 ; /* default */
-int loop = 0 ;
-int skip = 0;
-int size = -1 ;
-
-extern char *optarg;
-extern int optind, optopt, opterr, optreset;
-
-int
-usage(char *s)
-{
- printf(usage_string, s);
- exit(0);
-}
-
-int
-parse_len(char *s)
-{
- int par = -1;
- int mul = 1;
- int p = strlen(s);
-
- if (p == 0)
- return -1 ;
-
- if (*s != '-')
- par = atoi(s);
- else
- return -1 ;
- switch(s[p-1]) {
- case 'k':
- case 'K':
- mul = 1024;
- break;
- case 'm':
- case 'M':
- mul = 1024*1024;
- break;
- case 's':
- mul = rate * (stereo+1);
- if (format == AFMT_S16_LE)
- mul += mul;
- break;
- }
- return par*mul;
-}
-
-void
-parse_fmt(char *fmt)
-{
- char *s;
- int v, last = 0 ;
-
-again:
- while (*fmt && (*fmt == ' ' || *fmt == '\t')) fmt++;
- s = fmt;
- while (*s && ! (*s == ',' || *s == ':' || *s == ';') ) s++;
- if (*s)
- *s='\0';
- else
- last = 1 ;
- v = atoi(fmt) ;
- if (v > 0 && v < 1000000)
- rate = v ;
- else {
- if (!strcmp(fmt, "ulaw")) format = AFMT_MU_LAW;
- else if (!strcmp(fmt, "alaw")) format = AFMT_A_LAW;
- else if (!strcmp(fmt, "u8")) format = AFMT_U8 ;
- else if (!strcmp(fmt, "s16")) format = AFMT_S16_LE ;
- else if (!strcmp(fmt, "mono")) stereo = 0;
- else if (!strcmp(fmt, "stereo")) stereo = 1;
- else if (!strcmp(fmt, "loop")) loop = 1;
- else if (!strcmp(fmt, "rec")) play = 0;
- else if (!strcmp(fmt, "play")) play = 1;
- else if (!strcmp(fmt, "cd")) {
- stereo = 1 ;
- format = AFMT_S16_LE ;
- rate = 44100;
- }
- }
- if (last == 0) {
- fmt = s+1;
- goto again;
- }
-}
-
-char buf[BLKSZ];
-
-int
-main(int argc, char *argv[])
-{
- int i,c;
- int ac = argc;
- char *p;
-
- strcpy(dev, "/dev/audio");
-
- while ( (c= getopt(argc, argv, "f:") ) != EOF ) {
- switch (c) {
- case 'f' :
- if (optarg[0] >='0' && optarg[0] <='9')
- sprintf(dev, "/dev/audio%s", optarg);
- else
- strcpy(dev, optarg);
- break;
- }
- }
- if (*argv[optind] == '+') {
- parse_fmt(argv[optind]+1);
- optind++;
- }
- /*
- * assume a string with a "," and no "/" as a command
- */
- if (strstr(argv[optind],",") && !strstr(argv[optind],"/") ) {
- parse_fmt(argv[optind]);
- optind++;
- }
- /*
- * assume a string with a ":" and no "/" as a time limit
- */
- if ( (p = strstr(argv[optind] , ":")) && !strstr(argv[optind],"/") ) {
- *p = '\0';
- size = parse_len(argv[optind]);
- skip = parse_len(p+1);
- optind++;
- }
- printf("Using device %s, speed %d, mode 0x%08x, %s\n",
- dev, rate, format, stereo ? "stereo":"mono");
- printf("using files: ");
- for (i=optind; i< argc ; i++)
- printf("[%d] %s, ",i, argv[i]);
- printf("\n");
-
- audiodev = open(dev, play ? 1 : 0);
- if (audiodev < 0) {
- printf("failed to open %d\n", dev);
- exit(2);
- }
- ioctl(audiodev, SNDCTL_DSP_SETFMT, &format);
- ioctl(audiodev, SNDCTL_DSP_STEREO, &stereo);
- ioctl(audiodev, SNDCTL_DSP_SPEED, &rate);
- printf("-- format %d,%s,0x%08x, len %d skip %d\n",
- rate, stereo? "stereo":"mono",format, size, skip);
- if (play) {
- off_t ofs;
- int limit;
-again:
- for (i=optind; i< argc ; i++) {
- int l = -2;
- int f = open(argv[i], O_RDONLY);
- int sz ;
-
- printf("opened %s returns %d\n", argv[i], f);
- if (f < 0)
- continue;
- limit = size;
- if (skip > 0) {
- ofs = skip;
- lseek(f, ofs, 0 /* begin */ );
- }
- sz = BLKSZ;
- if (limit > 0 && limit < sz)
- sz = limit ;
- while ( (l = read(f, buf, sz) ) > 0 ) {
- write(audiodev, buf, l);
- if (limit > 0) {
- limit -= l ;
- if (limit > 0 && limit < sz)
- sz = limit ;
- if (limit <= 0 )
- break;
- if (limit < sz)
- sz = limit ;
- }
- }
- close(f);
- }
- if (loop)
- goto again;
- } else { /* record */
- int l = -2;
- int f ;
- if (!strcmp(argv[optind], "-") )
- f = 1;
- else
- f = open(argv[optind], O_WRONLY | O_CREAT | O_TRUNC, 0664);
- fprintf(stderr,"open %s returns %d\n", argv[optind], f);
-
- while ( size > 0 && (l = read(audiodev, buf, BLKSZ) ) > 0 ) {
- if (l <= skip) {
- skip -= l ; /* at most skip = 0 */
- continue;
- } else { /* l > skip */
- l -= skip ;
- if (l > size)
- l = size ;
- write(f, buf+skip, l);
- skip = 0 ;
- size -= l ;
- }
- }
- close(f);
- }
-}
diff --git a/sys/i386/isa/snd/misc/soundbyte.c b/sys/i386/isa/snd/misc/soundbyte.c
deleted file mode 100644
index 2e8d8cc..0000000
--- a/sys/i386/isa/snd/misc/soundbyte.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Sound interface for Speak Freely for Unix
- *
- * Designed and implemented in July of 1990 by John Walker
- *
- * FreeBSD / voxware version
- */
-
-#define BUFL 8000
-
-#include "speakfree.h"
-
-#include <sys/dir.h>
-#include <sys/file.h>
-
-/* #include <math.h> */
-#include <errno.h>
-
-#include <sys/ioctl.h>
-#ifdef LINUX
-#include <linux/soundcard.h>
-#else
-#include <machine/soundcard.h>
-#endif
-#define AUDIO_MIN_GAIN 0
-#define AUDIO_MAX_GAIN 255
-static int abuf_size;
-
-#define SoundFile "/dev/audio"
-#define AUDIO_CTLDEV "/dev/mixer"
-
-#define MAX_GAIN 100
-
-struct sound_buf {
- struct sound_buf *snext; /* Next sound buffer */
- int sblen; /* Length of this sound buffer */
- unsigned char sbtext[2]; /* Actual sampled sound */
-};
-
-/* Local variables */
-
-static int audiof = -1; /* Audio device file descriptor */
-static int Audio_fd; /* Audio control port */
-struct sound_buf *sbchain = NULL, /* Sound buffer chain links */
- *sbtail = NULL;
-static int sbtotal = 0; /* Total sample bytes in memory */
-static int playing = FALSE;/* Replay in progress ? */
-/* static int playqsize; *//* Output queue size */
-static int playlen = 0; /* Length left to play */
-static unsigned char *playbuf = NULL; /* Current play pointer */
-static int squelch = 0; /* Squelch value */
-
-/* Convert local gain into device parameters */
-
-static unsigned
-scale_gain(unsigned g)
-{
- return (AUDIO_MIN_GAIN + (unsigned)
- ((int) ((((double) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) *
- ((double) g / (double) MAX_GAIN)) + 0.5)));
-}
-
-#ifdef HALF_DUPLEX
-static int oldvol = -1;
-#endif
-
-/*
- * SOUNDINIT -- Open the sound peripheral and initialise for access. Return
- * TRUE if successful, FALSE otherwise.
- */
-
-int
-soundinit(int iomode)
-{
- int attempts = 3;
-
- assert(audiof == -1);
- while (attempts-- > 0) {
- if ((audiof = open(SoundFile, iomode)) >= 0) {
-
- if ((Audio_fd = open(AUDIO_CTLDEV, O_RDWR)) < 0) {
- perror(AUDIO_CTLDEV);
- return FALSE;
- }
- /* fcntl(audiof, F_SETFL, O_NDELAY); */
-#ifndef AUDIO_BLOCKING
- if (ioctl(audiof, SNDCTL_DSP_NONBLOCK, NULL) < 0) {
- perror("SNDCTL_DSP_NONBLOCK");
- return FALSE;
- }
- if (ioctl(audiof, SNDCTL_DSP_GETBLKSIZE, &abuf_size) < 0) {
- perror("SNDCTL_DSP_GETBLKSIZE");
- return FALSE;
- }
-#endif
-#ifdef HALF_DUPLEX
- if (iomode == O_RDONLY) {
- if (oldvol == -1)
- oldvol = soundgetvol();
- soundplayvol(0);
- } else if (iomode == O_WRONLY && oldvol != -1 ) {
- if (soundgetvol() == 0)
- soundplayvol(oldvol);
- oldvol = -1;
- }
-#endif
- return TRUE;
- }
- if (errno != EINTR)
- break;
- fprintf(stderr, "Audio open: retrying EINTR attempt %d\n", attempts);
- }
- return FALSE;
-}
-
-/* SOUNDTERM -- Close the sound device. chan=1 for play, 2:capture */
-
-void
-soundterm(int chan)
-{
- if (audiof >= 0) {
- int arg;
-#ifdef AIOSTOP /* FreeBSD */
- if (chan == 2) {
- arg = AIOSYNC_CAPTURE;
- ioctl(audiof, AIOSTOP, &arg);
- }
-#endif
-#ifdef SNDCTL_DSP_SYNC
- if (chan == 1)
- ioctl(audiof, SNDCTL_DSP_SYNC);
-#endif
-#ifdef HALF_DUPLEX
- if (oldvol != -1) {
- if (soundgetvol() == 0)
- soundplayvol(oldvol);
- oldvol = -1;
- }
-#endif
- if (close(audiof) < 0)
- perror("closing audio device");
- if (close(Audio_fd) < 0)
- perror("closing audio control device");
- audiof = -1;
- }
-}
-
-/* SOUNDPLAY -- Begin playing a sound. */
-
-void
-soundplay(int len, unsigned char *buf)
-{
- int ios;
-
- assert(audiof != -1);
- while (TRUE) {
- ios = write(audiof, buf, len);
- if (ios == -1)
- sf_usleep(100000);
- else {
- if (ios < len) {
- buf += ios;
- len -= ios;
- } else
- break;
- }
- }
-}
-
-/* SOUNDPLAYVOL -- Set playback volume from 0 (silence) to 100 (full on). */
-
-void
-soundplayvol(int value)
-{
- int arg;
-
- arg = (value << 8) | value;
-
- if (ioctl(Audio_fd, SOUND_MIXER_WRITE_PCM, &arg) < 0)
- perror("SOUND_MIXER_WRITE_PCM");
-}
-
-#ifdef HALF_DUPLEX
-
-/* SOUNDGETVOL -- Get current playback volume. */
-
-int
-soundgetvol()
-{
- int arg, v1, v2;
-
- if (ioctl(Audio_fd, SOUND_MIXER_READ_PCM, &arg) < 0) {
- perror("SOUND_MIXER_READ_PCM");
- return -1;
- }
- v1 = arg & 0xFF;
- v2 = (arg >> 8) & 0xFF;
- return (v1 > v2) ? v1 : v2;
-}
-#endif
-
-/* SOUNDRECGAIN -- Set recording gain from 0 (minimum) to 100 (maximum). */
-
-void
-soundrecgain(int value)
-{
- int arg;
-
- arg = (value << 8) | value;
-
- if (ioctl(Audio_fd, SOUND_MIXER_WRITE_RECLEV, &arg) < 0)
- perror("SOUND_MIXER_WRITE_RECLEV");
-}
-
-/*
- * SOUNDDEST -- Set destination for generated sound. If "where" is 0,
- * sound goes to the built-in speaker; if 1, to the audio output jack.
- */
-
-void
-sounddest(int where)
-{
-}
-
-/* SOUNDGRAB -- Return audio information in the record queue. */
-
-int
-soundgrab(char *buf, int len)
-{
- long read_size;
- int c;
-
- read_size = len;
-#ifndef AUDIO_BLOCKING
- if (read_size > abuf_size) {
- read_size = abuf_size;
- }
-#endif
- while (TRUE) {
- c = read(audiof, buf, read_size);
- if (c < 0) {
- if (errno == EINTR) {
- continue;
- } else if (errno == EAGAIN) {
- c = 0;
- }
- }
- break;
- }
- if (c < 0) {
- perror("soundgrab");
- }
- return c;
-}
-
-/* SOUNDFLUSH -- Flush any queued sound. */
-
-void
-soundflush()
-{
- char sb[BUFL];
- int c;
-
-#ifndef AUDIO_BLOCKING
- while (TRUE) {
- c = read(audiof, sb, BUFL < abuf_size ? BUFL : abuf_size);
- if (c < 0 && errno == EAGAIN)
- c = 0;
- if (c < 0)
- perror("soundflush");
- if (c <= 0)
- break;
- }
-#endif
-}
diff --git a/sys/i386/isa/snd/misc/test.c b/sys/i386/isa/snd/misc/test.c
deleted file mode 100644
index 2725dcc..0000000
--- a/sys/i386/isa/snd/misc/test.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * test.c -- a simple utility for testing audio I/O
- *
- * (C) Luigi Rizzo 1997
- *
- * This code mmaps the io descriptor, then every second dumps the
- * relevant data structures.
- *
- * call it as "test unit" where unit is the unit number you want
- * to see displayed.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-
-caddr_t r, w, d;
-
-#include </sys/i386/isa/snd/sound.h>
-
-void
-print_d(u_long *p, int unit)
-{
- snddev_info *d;
- int i;
- for (i=0; i<2000; i++) {
- d = (snddev_info *)&(p[i]);
- if ( d->magic == MAGIC(unit) )
- break;
- }
- if (i == 2000) {
- printf("desc not found\n");
- return;
- }
- printf("device type %d name %s\n", d->type, d->name);
- for (i=0;;i++) {
- if (i%20 == 0)
- printf("flags... fmt speed .bsz. c in-rl:in-dl:in-fl.ints "
- " c ou-fl:ou_dl:ou-rl.ints |\n");
- printf("%08x %3x %5d %5d %d %5d %5d %5d %4d %d %5d %5d %5d %4d |\n",
- d->flags, d->play_fmt, d->play_speed, d->play_blocksize,
- d->dbuf_in.chan,
- d->dbuf_in.rl,
- d->dbuf_in.dl,
- d->dbuf_in.fl,
- d->dbuf_in.int_count,
-
- d->dbuf_out.chan,
- d->dbuf_out.fl,
- d->dbuf_out.dl,
- d->dbuf_out.rl,
- d->dbuf_out.int_count);
- sleep(1);
- }
-}
-
-main(int argc, char *argv[])
-{
- int fd ;
- int unit = 0;
- char devn[64];
-
- if (argc>1) unit=atoi(argv[1]);
- sprintf(devn,"/dev/mixer%d", unit);
- fd = open (devn, O_RDWR);
- printf("open returns %d\n", fd);
-
- w = mmap(NULL, 0x10000, PROT_READ, 0, fd, 0); /* play */
- r = mmap(NULL, 0x10000, PROT_READ, 0, fd, 1<<24); /* rec */
- d = mmap(NULL, 0x2000, PROT_READ, 0, fd, 2<<24); /* desc */
-
- printf("mmap: w 0x%08lx, r 0x%08lx, d 0x%08lx\n", w, r, d);
- if (d && (int)d != -1 ) {
- print_d((u_long *)d, unit);
- }
- if (w && (int)w != -1) munmap(w, 0x10000);
- if (r && (int)r != -1) munmap(r, 0x10000);
- if (d && (int)d != -1) munmap(d, 0x2000);
- return 0;
-}
OpenPOWER on IntegriCloud