Module Name: src Committed By: isaki Date: Wed May 8 14:25:39 UTC 2019
Modified Files: src/distrib/sets/lists/comp: mi src/share/man/man4: audio.4 src/share/man/man9: Makefile audio.9 intro.9 Removed Files: src/share/man/man9: audio_system.9 Log Message: Update manpages respond to isaki-audio2 branch. To generate a diff of this commit: cvs rdiff -u -r1.2272 -r1.2273 src/distrib/sets/lists/comp/mi cvs rdiff -u -r1.87 -r1.88 src/share/man/man4/audio.4 cvs rdiff -u -r1.436 -r1.437 src/share/man/man9/Makefile cvs rdiff -u -r1.51 -r1.52 src/share/man/man9/audio.9 cvs rdiff -u -r1.1 -r0 src/share/man/man9/audio_system.9 cvs rdiff -u -r1.23 -r1.24 src/share/man/man9/intro.9 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/comp/mi diff -u src/distrib/sets/lists/comp/mi:1.2272 src/distrib/sets/lists/comp/mi:1.2273 --- src/distrib/sets/lists/comp/mi:1.2272 Sat Apr 27 23:04:31 2019 +++ src/distrib/sets/lists/comp/mi Wed May 8 14:25:38 2019 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.2272 2019/04/27 23:04:31 kamil Exp $ +# $NetBSD: mi,v 1.2273 2019/05/08 14:25:38 isaki Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. ./etc/mtree/set.comp comp-sys-root @@ -10654,7 +10654,7 @@ ./usr/share/man/cat9/arpresolve.0 comp-sys-catman .cat ./usr/share/man/cat9/atop.0 comp-sys-catman .cat ./usr/share/man/cat9/audio.0 comp-sys-catman .cat -./usr/share/man/cat9/audio_system.0 comp-sys-catman .cat +./usr/share/man/cat9/audio_system.0 comp-sys-catman obsolete ./usr/share/man/cat9/autoconf.0 comp-sys-catman .cat ./usr/share/man/cat9/bawrite.0 comp-sys-catman .cat ./usr/share/man/cat9/bcdtobin.0 comp-sys-catman .cat @@ -18591,7 +18591,7 @@ ./usr/share/man/html9/arpresolve.html comp-sys-htmlman html ./usr/share/man/html9/atop.html comp-sys-htmlman html ./usr/share/man/html9/audio.html comp-sys-htmlman html -./usr/share/man/html9/audio_system.html comp-sys-htmlman html +./usr/share/man/html9/audio_system.html comp-sys-htmlman obsolete ./usr/share/man/html9/autoconf.html comp-sys-htmlman html ./usr/share/man/html9/bawrite.html comp-sys-htmlman html ./usr/share/man/html9/bcdtobin.html comp-sys-htmlman html @@ -26631,7 +26631,7 @@ ./usr/share/man/man9/arpresolve.9 comp-sys-man .man ./usr/share/man/man9/atop.9 comp-sys-man .man ./usr/share/man/man9/audio.9 comp-sys-man .man -./usr/share/man/man9/audio_system.9 comp-sys-man .man +./usr/share/man/man9/audio_system.9 comp-sys-man obsolete ./usr/share/man/man9/autoconf.9 comp-sys-man .man ./usr/share/man/man9/bawrite.9 comp-sys-man .man ./usr/share/man/man9/bcdtobin.9 comp-sys-man .man Index: src/share/man/man4/audio.4 diff -u src/share/man/man4/audio.4:1.87 src/share/man/man4/audio.4:1.88 --- src/share/man/man4/audio.4:1.87 Sat Feb 16 06:50:14 2019 +++ src/share/man/man4/audio.4 Wed May 8 14:25:39 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: audio.4,v 1.87 2019/02/16 06:50:14 isaki Exp $ +.\" $NetBSD: audio.4,v 1.88 2019/05/08 14:25:39 isaki Exp $ .\" .\" Copyright (c) 1996 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -66,137 +66,40 @@ accepts the same operations as .Pa /dev/sound , but no other operations. +It can be opened at any time and can be used to manipulate the +audio device while it is in use. .Pp -.Pa /dev/sound -and -.Pa /dev/audio -can be opened at -.Em any -time and audio sources of different precision and playback -parameters i.e frequency will be mixed and played back simultaneously. -.Pp -.Pa /dev/audioctl -can be used to manipulate the audio device -while it is in use. .Sh SAMPLING DEVICES When .Pa /dev/audio -is opened, it automatically directs the underlying driver to manipulate -monaural 8-bit mu-law samples. -In addition, if it is opened read-only -(write-only) the device is set to half-duplex record (play) mode with -recording (playing) unpaused and playing (recording) paused. +is opened, it automatically sets the track to manipulate +monaural 8-bit mu-law 8000Hz. When .Pa /dev/sound -is opened, it maintains the previous audio sample mode and -record/playback mode most recently set on -.Pa /dev/sound -by any open channel. +is opened, it maintains the audio format and pause/unpause +state of the most recently opened track. In all other respects .Pa /dev/audio and .Pa /dev/sound are identical. -.Sh VIRTUAL CHANNELS -Any process may open a sampling device at a given time. -Any number of devices per process and file descriptors may be shared between -processes. -.Pp -Virtual channels are converted to a common format, signed linear encoding, -frequency channels and precision. -These can be modified to taste by the following -.Xr sysctl 8 -variables: -.Bl -tag -width "hw.driverN.precision" -compact -offset indent -.It Li hw. Ns Ar driverN Ns Li .precision -.It Li hw. Ns Ar driverN Ns Li .frequency -.It Li hw. Ns Ar driverN Ns Li .channels -.It Li hw. Ns Ar driverN Ns Li .latency -.It Li hw. Ns Ar driverN Ns Li .multiuser -.El -.Pp -Where -.Ar driverN -corresponds to the underlying audio device driver and device number. -E.g. in the case of an -.\" XXX: there's no hdafg(4) to xref to -.Xr hdaudio 4 -supported device the variables would be: -.Li hw.hdafg0.channels , -.Li hw.hdafg0.precision , -.Li hw.hdafg0.frequency . -.Pp -For best results, values close to the underlying hardware should be chosen. -These variables may only be changed when the sampling device is not in use. -.Pp -The -.Li hw. Ns Ar driverN Ns Li .latency -.Xr sysctl 8 -variable controls the latency of the in-kernel mixer by varying the hardware -blocksize. -It accepts a value in milliseconds(ms), fractional values are not allowed. -A value of zero will default to 150ms. -.Pp -If a static blocksize is enforced by the underlying hardware driver this value -cannot be changed. -.Pp -For audio applications that do not specify a preferred blocksize when configuring -the audio device, this will be the latency these applications have. -.Pp -For audio applications that -.Xr mmap 2 -the audio device for play back the resultant latency is a third (1/3) of the value -of the -.Li hw. Ns Ar driverN Ns Li .latency -variable. .Pp -The -.Li hw. Ns Ar driverN Ns Li .multiuser -.Xr sysctl 8 -variable determines if multiple users are allowed to access the sampling -device. -.Pp -By default it is set to false. -This means that the sampling device may be only used by -.Em one -user at a time. -Other users (except root) attempting to open the sampling device will be -denied. -.Pp -If set to true, all users may access the sampling device at any time. -.Pp -Each virtual channel has a corresponding mixer: -.Bl -tag -width "vchan.dacN" -compact -offset indent -.It Li vchan.dac Ns Ar N -Output volume -.It Li vchan.mic Ns Ar N -Recording volume -.El +On a full-duplex device, reads and writes may operate concurrently +without interference. +If a full-duplex capable audio device is opened for both reading and writing +it will start in play mode but not start in record mode. .Pp -Where -.Ar N -is the virtual channel number. -E.g.\& -.Li vchan.dac0 -controlling playback volume and -.Li vchan.mic0 -controlling recording volume for the first virtual channel. -.Pp -On a half-duplex device, writes while recording is in progress will be -immediately discarded. -Similarly, reads while playback is in progress -will be filled with silence but delayed to return at the current -sampling rate. -If both playback and recording are requested on a half-duplex -device, playback mode takes precedence and recordings will get silence. +On a half-duplex device, if there are any recording descriptors already, +opening with write mode will fail. +Similarly, if there are any playback descriptors already, +opening with read mode will fail. +If both playback and recording are requested on a half-duplex device, +it will be treated as playback mode. .Pp -On a full-duplex device, reads and writes may operate -concurrently without interference. -If a full-duplex capable audio device is opened for both reading and writing -it will start in half-duplex play mode; full-duplex mode has to be set -explicitly. +On either type of device, opening with write mode will start in playback mode, +opening with read mode will start in recording mode. .Pp -On either type of device, if the playback mode is paused then silence is +If the playback mode is paused then silence is played instead of the provided samples, and if recording is paused then the process blocks in .Xr read 2 @@ -206,46 +109,55 @@ If a writing process does not call .Xr write 2 frequently enough to provide samples at the pace the hardware consumes them silence is inserted. -If the -.Dv AUMODE_PLAY_ALL -mode is not set the writing process must -provide enough data via -subsequent write calls to -.Dq catch up -in time to the current audio -block before any more process-provided samples will be played. If a reading process does not call .Xr read 2 frequently enough, it will simply miss samples. .Pp +The audio driver supports track multiplexing. +All sampling devices can be opened at any time without interference. +For playback, all tracks opened simultaneously are mixed, +even if thier specified format is different. +For recording, recorded data is distributed to all opened tracks, +even if thier specified format is different. +To achieve this, the audio driver has an small efficient encoding converter, +a channel mixer, and a frequency conveter. +The frequency conversion adapts the simplest way +(interpolation method for upward, and simple thinning method for downward) +due to restriction in kernel resources and processing time. +It will work well in most case but don't expect excessively for its quality. +.Pp The audio device is normally accessed with .Xr read 2 or .Xr write 2 calls, but it can also be mapped into user memory with -.Xr mmap 2 +.Xr mmap 2 . Once the device has been mapped it can no longer be accessed by read or write; all access is by reading and writing to the mapped memory. -The device appears as a block of memory -of size +The mmap'ped buffer appears as a block of memory of size .Va buffersize (as available via .Dv AUDIO_GETINFO or .Dv AUDIO_GETBUFINFO ) . -The device driver will continuously move data from this buffer -from/to the audio hardware, wrapping around at the end of the buffer. +The audio driver will continuously move data from this buffer +from/to the mixing buffer, wrapping around at the end of the buffer. To find out where the hardware is currently accessing data in the buffer the .Dv AUDIO_GETIOFFS and .Dv AUDIO_GETOOFFS calls can be used. -The playing and recording buffers are distinct and must be -mapped separately if both are to be used. -Only encodings that are not emulated (i.e. where +Note that +.Xr mmap 2 +no longer maps hardware buffer directly. +Now it is achieved by emulation so don't expect any improvements excessively +rather than normal +.Xr write 2 . +For historical reasons, only encodings that are not set .Dv AUDIO_ENCODINGFLAG_EMULATED -is not set) work properly for a mapped device. +is able to +.Xr mmap 2 . .Pp The audio device, like most devices, can be used in .Xr select 2 , @@ -262,26 +174,23 @@ The following .Xr ioctl 2 commands are supported on the sample devices: .Bl -tag -width indent -.It Dv AUDIO_GETCHAN (int) -This command will return the audio channel in use. -.It Dv AUDIO_SETCHAN (int) -This command will select the audio channel for subsequent ioctl calls. .It Dv AUDIO_FLUSH This command stops all playback and recording, clears all queued -buffers, resets error counters, and restarts recording and playback as +buffers, resets error counters on this track, +and restarts recording and playback as appropriate for the current sampling mode. .It Dv AUDIO_PERROR (int) .It Dv AUDIO_RERROR (int) This command fetches the count of dropped output (input) -samples into its integer argument. +bytes into its integer argument. There is no information regarding when in the sample stream they were dropped. .It Dv AUDIO_WSEEK (u_long) -This command fetches the count of samples that are queued ahead of the +This command fetches the count of bytes that are queued ahead of the first sample in the most recent sample block written into its integer argument. .It Dv AUDIO_DRAIN This command suspends the calling process until all queued playback -samples have been played by the hardware. +samples have been played. .It Dv AUDIO_GETDEV (audio_device_t) This command fetches the current hardware device information into the .Vt audio_device_t @@ -296,6 +205,8 @@ typedef struct audio_device { .It Dv AUDIO_GETENC (audio_encoding_t) This command is used iteratively to fetch sample encoding names and format ids into the input/output audio_encoding_t argument. +The encoding returned by the command is user accessible encoding and +is not hardware supported encoding. .Bd -literal typedef struct audio_encoding { int index; /* input: nth encoding */ @@ -312,13 +223,9 @@ all the supported encodings, start with continue with successive encodings (1, 2, ...) until the command returns an error. .It Dv AUDIO_GETFD (int) -The command returns the current setting of the full duplex mode. +This command is obsoleted. .It Dv AUDIO_SETFD (int) -This command sets the device into full-duplex operation if its integer -argument has a non-zero value, or into half-duplex operation if it -contains a zero value. -If the device does not support full-duplex -operation, attempting to set full-duplex mode returns an error. +This command is obsoleted. .It Dv AUDIO_GETPROPS (int) This command gets a bit set of hardware properties. If the hardware @@ -342,7 +249,7 @@ the device is capable of audio capture. .It Dv AUDIO_GETIOFFS (audio_offset_t) .It Dv AUDIO_GETOOFFS (audio_offset_t) This command fetches the current offset in the input(output) buffer where -the audio hardware's DMA engine will be putting(getting) data. +the track mixer will be putting(getting) data. It mostly useful when the device buffer is available in user space via the .Xr mmap 2 @@ -361,20 +268,22 @@ typedef struct audio_offset { .It Dv AUDIO_GETBUFINFO (audio_info_t) .It Dv AUDIO_SETINFO (audio_info_t) Get or set audio information as encoded in the audio_info structure. +For historical reasons, the audio_info structure has three different +layer's parameters: track, track mixer and hardware rich mixer. .Bd -literal typedef struct audio_info { struct audio_prinfo play; /* info for play (output) side */ struct audio_prinfo record; /* info for record (input) side */ - u_int monitor_gain; /* input to output mix */ + u_int monitor_gain; /* input to output mix [HWmixer] */ /* BSD extensions */ - u_int blocksize; /* H/W read/write block size */ - u_int hiwat; /* output high water mark */ - u_int lowat; /* output low water mark */ + u_int blocksize; /* read/write block size [track] */ + u_int hiwat; /* output high water mark [track] */ + u_int lowat; /* output low water mark [track] */ u_int _ispare1; - u_int mode; /* current device mode */ + u_int mode; /* current operation mode [track] */ #define AUMODE_PLAY 0x01 #define AUMODE_RECORD 0x02 -#define AUMODE_PLAY_ALL 0x04 /* do not do real-time correction */ +#define AUMODE_PLAY_ALL 0x04 /* Not used anymore */ } audio_info_t; .Ed .Pp @@ -392,13 +301,14 @@ first. .Pp The .Va mode -field should be set to -.Dv AUMODE_PLAY , -.Dv AUMODE_RECORD , -.Dv AUMODE_PLAY_ALL , -or a bitwise OR combination of the three. -Only full-duplex audio devices support -simultaneous record and playback. +field indicates current operation mode, either one of +.Dv AUMODE_PLAY +or +.Dv AUMODE_RECORD . +These two flags can not be changed once this descriptor is opened. +On playback mode, obsoleted +.Dv AUMODE_PLAY_ALL +can be set but has no effect. .Pp .Va hiwat and @@ -423,41 +333,40 @@ sets the current audio blocksize. The generic audio driver layer and the hardware driver have the opportunity to adjust this block size to get it within implementation-required limits. -Upon return from an -.Dv AUDIO_SETINFO -call, the actual blocksize set is returned in this field. Normally the .Va blocksize -is calculated to correspond to 50ms of sound and it is recalculated -when the encoding parameter changes, but if the +is calculated to correspond to 40ms +(For some hardware, this value may be different due to +the hardware restrictions) +of sound and it is recalculated +when the encoding parameter changes. +If the descriptor is opened for read only, .Va blocksize -is set explicitly this value becomes sticky, i.e. it remains -even when the encoding is changed. -The stickiness can be cleared by reopening the device or setting the +indicates the blocksize on recording track. +Otherwise, .Va blocksize -to 0. +indicates the blocksize on playback track. .Bd -literal struct audio_prinfo { - u_int sample_rate; /* sample rate in samples/s */ - u_int channels; /* number of channels, usually 1 or 2 */ - u_int precision; /* number of bits/sample */ - u_int encoding; /* data encoding (AUDIO_ENCODING_* below) */ - u_int gain; /* volume level */ - u_int port; /* selected I/O port */ - u_long seek; /* BSD extension */ - u_int avail_ports; /* available I/O ports */ - u_int buffer_size; /* total size audio buffer */ + u_int sample_rate; /* sample rate in samples/s [track] */ + u_int channels; /* number of channels, usually 1 or 2 [track] */ + u_int precision; /* number of bits/sample [track] */ + u_int encoding; /* data encoding (AUDIO_ENCODING_* below) [track] */ + u_int gain; /* volume level [HWmixer] */ + u_int port; /* selected I/O port [HWmixer] */ + u_long seek; /* BSD extension [track] */ + u_int avail_ports; /* available I/O ports [HWmixer] */ + u_int buffer_size; /* total size audio buffer [track] */ u_int _ispare[1]; - /* Current state of device: */ - u_int samples; /* number of samples */ - u_int eof; /* End Of File (zero-size writes) counter */ - u_char pause; /* non-zero if paused, zero to resume */ - u_char error; /* non-zero if underflow/overflow occurred */ - u_char waiting; /* non-zero if another process hangs in open */ - u_char balance; /* stereo channel balance */ + u_int samples; /* number of samples [track] */ + u_int eof; /* End Of File (zero-size writes) counter [track] */ + u_char pause; /* non-zero if paused, zero to resume [track] */ + u_char error; /* non-zero if underflow/overflow occurred [track] */ + u_char waiting; /* non-zero if another process hangs in open [track] */ + u_char balance; /* stereo channel balance [HWmixer] */ u_char cspare[2]; - u_char open; /* non-zero if currently open */ - u_char active; /* non-zero if I/O is currently active */ + u_char open; /* non-zero if currently open [trackmixer] */ + u_char active; /* non-zero if I/O is currently active [trackmixer] */ }; .Ed .Pp @@ -494,6 +403,13 @@ unsigned linear encoding with big endian Dolby Digital AC3 .El .Pp +Regardless of format supported by underlying driver, +audio driver accepts following formats. +encoding and precision is one of those obtained by +.Dv AUDIO_GETENC . +channels ranges from 1 to 12. +frequency ranges from 1000Hz to 192000Hz. +.Pp The .Va gain , .Va port @@ -556,7 +472,7 @@ and .Dv AUDIO_GETBUFINFO . .Va seek represents the count of -samples pending; +bytes pending; .Va samples represents the total number of bytes recorded or played, less those that were dropped due to inadequate consumption/production rates. @@ -567,6 +483,54 @@ For .Dv AUDIO_SETINFO , if the pause value is specified it will either pause or unpause the particular direction. +.It Dv AUDIO_QUERYFORMAT (audio_format_query_t) +This command enumerates formats supported by the hardware. +Similarly to +.Dv AUDIO_GETENC , +to query all the supported formats, +start with an index field of 0 and continue with successive formats +(1, 2, ...) until the command returns an error. +.Bd -literal +typedef struct audio_format_query { + u_int index; + struct audio_format fmt; +} audio_format_query_t; +.Ed +.It Dv AUDIO_GETFORMAT (audio_info_t) +This command fetches the current hardware format. +Only following members in audio_info_t are used. +Members which is not listed here or belong in invalid direction are +filled by -1. +.\" XXX I want something like <ul> on HTML... +.Bd -literal + mode + play.encoding + play.precision + play.channels + play.sample_rate + record.encoding + record.precision + record.channels + record.sample_rate +.Ed +.Pp +.Va mode +indicates which direction is valid. +.It Dv AUDIO_SETFORMAT (audio_info_t) +This command sets the hardware format. +It will fail if there are any opened descriptors. +So obviously, it must be issued on +.Pa /dev/audioctl . +Similarly to +.Dv AUDIO_GETFORMAT , +only above members in audio_info_t are used. +Members which is not listed or belong in invalid direction are ignored. +The parameters can be chosen from the choices obtained by +.Dv AUDIO_QUERYFORMAT . +.It Dv AUDIO_GETCHAN (int) +This command is obsoleted. +.It Dv AUDIO_SETCHAN (int) +This command is obsoleted. .El .Sh MIXER DEVICE The mixer device, @@ -773,13 +737,13 @@ string values. .It Pa /dev/mixer .El .Sh SEE ALSO +.Xr audiocfg 1 , .Xr audioctl 1 , .Xr mixerctl 1 , .Xr ioctl 2 , .Xr ossaudio 3 , .Xr midi 4 , .Xr radio 4 , -.Xr sysctl 8 .Ss ISA bus .Xr aria 4 , .Xr ess 4 , @@ -812,8 +776,10 @@ string values. .Xr bba 4 .Ss USB .Xr uaudio 4 -.Ss The NetBSD audio specification -.Xr audio_system 9 .Sh HISTORY Support for virtual channels and mixing first appeared in .Nx 8.0 . +.Sh BUGS +If the device is used in +.Xr mmap 2 +it is currently always mapped for writing (playing) due to VM system weirdness. Index: src/share/man/man9/Makefile diff -u src/share/man/man9/Makefile:1.436 src/share/man/man9/Makefile:1.437 --- src/share/man/man9/Makefile:1.436 Sat Apr 6 03:06:24 2019 +++ src/share/man/man9/Makefile Wed May 8 14:25:39 2019 @@ -1,9 +1,9 @@ -# $NetBSD: Makefile,v 1.436 2019/04/06 03:06:24 thorpej Exp $ +# $NetBSD: Makefile,v 1.437 2019/05/08 14:25:39 isaki Exp $ # Makefile for section 9 (kernel function and variable) manual pages. MAN= accept_filter.9 accf_data.9 accf_http.9 \ - altq.9 arp.9 audio.9 audio_system.9 autoconf.9 \ + altq.9 arp.9 audio.9 autoconf.9 \ bcdtobin.9 bcmp.9 bcopy.9 bintime_add.9 bluetooth.9 boothowto.9 bpf.9 \ buffercache.9 bufferio.9 bufq.9 bus_dma.9 bus_space.9 byteorder.9 \ bzero.9 \ Index: src/share/man/man9/audio.9 diff -u src/share/man/man9/audio.9:1.51 src/share/man/man9/audio.9:1.52 --- src/share/man/man9/audio.9:1.51 Sat Feb 16 07:00:56 2019 +++ src/share/man/man9/audio.9 Wed May 8 14:25:39 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: audio.9,v 1.51 2019/02/16 07:00:56 wiz Exp $ +.\" $NetBSD: audio.9,v 1.52 2019/05/08 14:25:39 isaki Exp $ .\" .\" Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -44,12 +44,11 @@ structure. struct audio_hw_if { int (*open)(void *, int); void (*close)(void *); - int (*drain)(void *); - int (*query_encoding)(void *, struct audio_encoding *); - int (*set_params)(void *, int, int, - audio_params_t *, audio_params_t *, - stream_filter_list_t *, stream_filter_list_t *); + int (*query_format)(void *, audio_format_query_t *); + int (*set_format)(void *, int, + const audio_params_t *, const audio_params_t *, + audio_filter_reg_t *, audio_filter_reg_t *); int (*round_blocksize)(void *, int, int, const audio_params_t *); int (*commit_settings)(void *); @@ -68,7 +67,6 @@ struct audio_hw_if { #define SPKR_OFF 0 int (*getdev)(void *, struct audio_device *); - int (*setfd)(void *, int); int (*set_port)(void *, mixer_ctrl_t *); int (*get_port)(void *, mixer_ctrl_t *); @@ -78,7 +76,6 @@ struct audio_hw_if { void *(*allocm)(void *, int, size_t); void (*freem)(void *, void *, size_t); size_t (*round_buffersize)(void *, int, size_t); - paddr_t (*mappage)(void *, void *, off_t, int); int (*get_props)(void *); @@ -130,6 +127,15 @@ the hardware request another block a blo Furthermore, if the user process does not read data quickly enough during recording data will be thrown away. .Pp +The phase that these functions are called is classified into three. +Attach phase, Closed phase and Opened phase. +Attach phase is during device attach and +it transits to the Closed phase when the attach succeeded. +Closed phase is when no sampling device is opened and +it transits to the Opened phase when open succeeded. +Opened phase is when any sampling device is opened and +it transits to the Closed phase when close succeeded. +.Pp The fields of .Va audio_hw_if are described in some more detail below. @@ -138,147 +144,173 @@ Some fields are optional and can be set if not needed. .Bl -tag -width indent .It Dv int open(void *hdl, int flags) -optional, is called when the audio device is opened. -It should initialize the hardware for I/O. +optional, is called when the first device combining playback and recording +is opened. +On a full duplex hardware, +.Dv (FREAD | FWRITE) +is passed to flags. +On a half duplex hardware, +.Dv FWRITE +is passed for playback, or +.Dv FREAD +for recording. Every successful call to .Va open is matched by a call to .Va close . Return 0 on success, otherwise an error code. +It is called at Closed phase. .It Dv void close(void *hdl) -optional, is called when the audio device is closed. -.It Dv int drain(void *hdl) -optional, is called before the device is closed or when -.Dv AUDIO_DRAIN -is called. -It should make sure that no samples remain in to be played that could -be lost when -.Va close -is called. -Return 0 on success, otherwise an error code. -.It Dv int query_encoding(void *hdl, struct audio_encoding *ae) -is used when -.Dv AUDIO_GETENC -is called. -It should fill the -.Va audio_encoding -structure and return 0 or, if there is no encoding with the -given number, return EINVAL. -.It Dv int set_params(void *hdl, int setmode, int usemode, -.Dv "audio_params_t *play, audio_params_t *rec," +optional, is called when the last audio device combining +playback and recording is closed. +It is called at Opened phase. +.It Dv int query_format(void *hdl, audio_format_query_t *afp) +is called to enumerate formats supported by the hardware. +It should fill the audio_format_t structure according to given number +afp->index. +If there is no format with given number, return EINVAL. +It is called at any time. +.Bd -literal +typedef struct audio_format_query { + u_int index; + struct audio_format fmt; +} audio_format_query_t; +.Ed .Pp -.Dv "stream_filter_list_t *pfil, stream_filter_list_t *rfil)" +It is also used to determine the default format. +The upper layer chooses the most preferred one as default format by following: +.\" XXX I don't know syntax to represent <OL> in html +1. Higher priority is preferred (normally 0, the highest is 3, the lowest is 0). +2. AUDIO_ENCODING_SLINEAR_NE:16 is preferred if exists. +3. AUDIO_ENCODING_SLINEAR_OE:16 is preferred if exists. +4. More channels is preferred. +.Pp +If the driver supports SLINEAR_NE:16 and the upper layer chooses it, +the driver does not need to provide conversion function in +.Va set_format . +Similarly, if the driver supports SLINEAR_OE:16 and the upper layer chooses it, +the driver does not need to provide conversion function. +Because the upper layer only supports conversion between +SLINEAR_NE:16 and SLINEAR_OE:16 for convenience. +If the upper layer chooses other format, +the driver needs to provide conversion function in +.Va set_format . +See also +.Va set_format . +If the driver can not provide the conversion from/to SLINEAR_NE:16, +set priority to -1. +It means that the hardware supports this format but the driver does not +(e.g. AC3), and it will never be chosen. +.It Dv int set_foramt(void *hdl, int setmode, +.Dv "const audio_params_t *play, const audio_params_t *rec," +.Dv "audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)" .Pp -Called to set the audio encoding mode. +is called to set specified format to the hardware, +when the device is attached or the hardware format is changed. .Va setmode is a combination of the .Dv AUMODE_RECORD and .Dv AUMODE_PLAY -flags to indicate which mode(s) are to be set. -.Va usemode -is also a combination of these flags, but indicates the current -mode of the device (i.e., the value of -.Va mode -in the -.Va audio_info -struct). +flags to indicate which modes are to be set. .Pp The .Va play and .Va rec -structures contain the encoding parameters that should be set. -The values of the structures may also be modified if the hardware -cannot be set to exactly the requested mode (e.g., if the requested -sampling rate is not supported, but one close enough is). -.Pp -If the hardware requires software assistance with some encoding -(e.g., it might be lacking mu-law support) it should fill the +structures contain the encoding parameters that should be set to the hardware. +If the driver has query_format interface, +all parameters on +.Va play +and/or +.Va rec +are chosen from formats returned by query_format. +Therefore +.Va play +and/or +.Va rec +are always settable. +If the driver does not have query_format interface, +the driver has to validate the format. +If the hardware does not support +.Dv AUDIO_ENCODING_SLINEAR_{NE,OE}:16 , +conversion information should be filled the .Va pfil for playing or .Va rfil -for recording with conversion information. -For example, if -.Va play -requests [8000Hz, mu-law, 8/8bit, 1ch] and the hardware does not -support 8bit mu-law, but 16bit slinear_le, the driver should call -.Dv pfil->append() -with -.Va pfil , -.Va mulaw_to_linear16 , -and audio_params_t representing [8000Hz, slinear_le, 16/16bit, 2ch]. -If the driver needs multiple conversions, a conversion nearest to the -hardware should be set to the head of -.Va pfil -or -.Va rfil . -The definition of -.Dv stream_filter_list_t -follows: -.Bd -literal -typedef struct stream_filter_list { - void (*append)(struct stream_filter_list *, - stream_filter_factory_t, - const audio_params_t *); - void (*prepend)(struct stream_filter_list *, - stream_filter_factory_t, - const audio_params_t *); - void (*set)(struct stream_filter_list *, int, - stream_filter_factory_t, - const audio_params_t *); - int req_size; - struct stream_filter_req { - stream_filter_factory_t *factory; - audio_params_t param; /* from-param for recording, - to-param for playing */ - } filters[AUDIO_MAX_FILTERS]; -} stream_filter_list_t; -.Ed -.Pp -For playing, -.Va pfil -constructs conversions as follows: +for recording. +The definition of audio_filter_reg_t and related structure follow: .Bd -literal - (play) == write(2) input - | pfil->filters[pfil->req_size-1].factory - (pfil->filters[pfil->req_size-1].param) - | pfil->filters[pfil->req_size-2].factory - : - | pfil->filters[1].factory - (pfil->filters[1].param) - | pfil->filters[0].factory - (pfil->filters[0].param) == hardware input +typedef struct { + const void *src; + const audio_format2_t *srcfmt; + void *dst; + const audio_format2_t *dstfmt; + int count; + void *context; +} audio_filter_arg_t; + +typedef void(*audio_filter_t)(audio_filter_arg_t *arg); + +typedef struct { + audio_filter_t codec; + void *context; +} audio_filter_reg_t; .Ed .Pp -For recording, -.Va rfil -constructs conversions as follows: -.Bd -literal - (rfil->filters[0].param) == hardware output - | rfil->filters[0].factory - (rfil->filters[1].param) - | rfil->filters[1].factory - : - | rfil->filters[rfil->req_size-2].factory - (rfil->filters[rfil->req_size-1].param) - | rfil->filters[rfil->req_size-1].factory - (rec) == read(2) output -.Ed +.Va codec +is conversion function and +.Va context +is optional opaque pointer passed to +.Va codec . +.Pp +When +.Va codec +is called, all parameters required by +.Va codec +are contained in +.Va arg . +.Va src +points input buffer block, +.Va srcfmt +contains input encoding parameter, +.Va dst +points output buffer block and +.Va dstfmt +contains output encoding parameter. +.Va count +represents the number of frames to process on this call. +.Va src +and +.Va dst +are guaranteed to be able to consecutively access number of frames +specified by +.Va count. +.Va codec +must fill entire +.Va dst . +For example, let count = 100, srcfmt is { precision = 16, channels = 3 }, +dstfmt is { precision = 8, channels = 4 }, +in this case, +src block length = 2(bytes) * 3(channels) * 100(frames) = 600 bytes, +The length to be written to +.Va dst +block is 1(byte) * 4(channels) * 100(frames) = 400 bytes. +.Va codec +cannot abort the conversion halfway and there is no error reporting mechanism. +.Va context +is a opaque pointer that can be used by +.Va codec +if necessary. .Pp If the device does not have the .Dv AUDIO_PROP_INDEPENDENT property the same value is passed in both .Va play and -.Va rec -and the encoding parameters from -.Va play -is copied into -.Va rec -after the call to -.Va set_params . +.Va rec . Return 0 on success, otherwise an error code. +It is called at Attach or Closed phase. .It Dv int round_blocksize(void *hdl, int bs, int mode, .Dv "const audio_params_t *param)" .Pp @@ -294,6 +326,7 @@ and encoding parameters for the hardware. It should return a block size, possibly changed according to the needs of the hardware driver. +It is called at Attach or Closed phase. .It Dv int commit_settings(void *hdl) optional, is called after all calls to .Va set_params , @@ -304,6 +337,7 @@ A hardware driver that needs to get the mode for each change can save all the changes during previous calls and do them all here. Return 0 on success, otherwise an error code. +It is called at Attach or Closed phase. .It Dv int init_output(void *hdl, void *buffer, int size) optional, is called before any output starts, but when the total .Va size @@ -312,6 +346,7 @@ of the output has been determined. It can be used to initialize looping DMA for hardware that needs that. Return 0 on success, otherwise an error code. +It is called at Attach or Closed phase. .It Dv int init_input(void *hdl, void *buffer, int size) optional, is called before any input starts, but when the total .Va size @@ -320,6 +355,7 @@ of the input has been determined. It can be used to initialize looping DMA for hardware that needs that. Return 0 on success, otherwise an error code. +It is called at Attach or Closed phase. .It Dv int start_output(void *hdl, void *block, int blksize, .Dv "void (*intr)(void*), void *intrarg)" .Pp @@ -339,6 +375,7 @@ Calling will normally initiate another call to .Va start_output . Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int start_input(void *hdl, void *block, int blksize, .Dv "void (*intr)(void*), void *intrarg)" .Pp @@ -358,32 +395,32 @@ Calling will normally initiate another call to .Va start_input . Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int halt_output(void *hdl) is called to abort the output transfer (started by .Va start_output ) in progress. Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int halt_input(void *hdl) is called to abort the input transfer (started by .Va start_input ) in progress. Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int speaker_ctl(void *hdl, int on) optional, is called when a half duplex device changes between playing and recording. It can, e.g., be used to turn on and off the speaker. Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int getdev(void *hdl, struct audio_device *ret) Should fill the .Va audio_device struct with relevant information about the driver. Return 0 on success, otherwise an error code. -.It Dv int setfd(void *hdl, int fd) -optional, is called when -.Dv AUDIO_SETFD -is used, but only if the device has AUDIO_PROP_FULLDUPLEX set. -Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int set_port(void *hdl, mixer_ctrl_t *mc) is called in when .Dv AUDIO_MIXER_WRITE @@ -392,6 +429,7 @@ It should take data from the .Va mixer_ctrl_t struct at set the corresponding mixer values. Return 0 on success, otherwise an error code. +It is called at Opened or Closed phase. .It Dv int get_port(void *hdl, mixer_ctrl_t *mc) is called in when .Dv AUDIO_MIXER_READ @@ -400,6 +438,7 @@ It should fill the .Va mixer_ctrl_t struct. Return 0 on success, otherwise an error code. +It is called at Opened or Closed phase. .It Dv int query_devinfo(void *hdl, mixer_devinfo_t *di) is called in when .Dv AUDIO_MIXER_DEVINFO @@ -408,6 +447,7 @@ It should fill the .Va mixer_devinfo_t struct. Return 0 on success, otherwise an error code. +It is called at any time. .It Dv "void *allocm(void *hdl, int direction, size_t size)" optional, is called to allocate the device buffers. If not present @@ -419,12 +459,14 @@ is that some buses need special allocati Returns the address of the buffer, or .Dv NULL on failure. +It is called at Attached or Closed phase. .It Dv void freem(void *hdl, void *addr, size_t size) optional, is called to free memory allocated by .Va allocm . If not supplied .Xr free 9 is used. +It is called at Attached or Closed phase. .It Dv size_t round_buffersize(void *hdl, int direction, size_t bufsize) optional, is called at startup to determine the audio buffer size. @@ -432,21 +474,14 @@ The upper layer supplies the suggested s .Va bufsize , which the hardware driver can then change if needed. E.g., DMA on the ISA bus cannot exceed 65536 bytes. -.It Dv "paddr_t mappage(void *hdl, void *addr, off_t offs, int prot)" -.Pp -optional, is called for -.Xr mmap 2 . -Should return the map value for the page at offset -.Va offs -from address -.Va addr -mapped with protection -.Va prot . -Returns -1 on failure, or a machine dependent opaque value -on success. +It is called at Attached or Closed phase. .It Dv int get_props(void *hdl) Should return the device properties; i.e., a combination of AUDIO_PROP_xxx. +It is called at any time. +.Pp +.Dv AUDIO_PROP_MMAP +is acceptable but obsoleted, so new drivers should not return this property. .It Dv int trigger_output(void *hdl, void *start, void *end, .Dv "int blksize, void (*intr)(void*), void *intrarg," .Pp @@ -471,6 +506,7 @@ should be called with the argument Once started the transfer may be stopped using .Va halt_output . Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int trigger_input(void *hdl, void *start, void *end, .Dv "int blksize, void (*intr)(void*), void *intrarg," .Pp @@ -495,6 +531,7 @@ should be called with the argument Once started the transfer may be stopped using .Va halt_input . Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv int dev_ioctl(void *hdl, u_long cmd, void *addr, .Pp .Dv "int flag, struct lwp *l)" @@ -503,8 +540,10 @@ optional, is called when an .Xr ioctl 2 is not recognized by the generic audio driver. Return 0 on success, otherwise an error code. +It is called at Opened phase. .It Dv void get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread) Returns the interrupt and thread locks to the common audio layer. +It is called at Attach phase. .El .Pp The @@ -591,8 +630,7 @@ and that is a control named of class .Dv AudioCmonitor . .Sh SEE ALSO -.Xr audio 4 , -.Xr audio_system 9 +.Xr audio 4 .Sh HISTORY This .Nm Index: src/share/man/man9/intro.9 diff -u src/share/man/man9/intro.9:1.23 src/share/man/man9/intro.9:1.24 --- src/share/man/man9/intro.9:1.23 Sun Jul 15 05:16:41 2018 +++ src/share/man/man9/intro.9 Wed May 8 14:25:39 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: intro.9,v 1.23 2018/07/15 05:16:41 maxv Exp $ +.\" $NetBSD: intro.9,v 1.24 2019/05/08 14:25:39 isaki Exp $ .\" .\" Copyright (c) 1997, 2007 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -435,11 +435,6 @@ Interface between low and high level aud See .Xr audio 9 . .Pp -The -.Nx audio specification. -See -.Xr audio_system 9 . -.Pp Bluetooth Device/Protocol API. See .Xr bluetooth 9 .