mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
3974 lines
126 KiB
HTML
3974 lines
126 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
|
|
"http://www.w3.org/TR/REC-html40/loose.dtd"><HTML>
|
|
<META NAME="GENERATOR" CONTENT="TtH 1.98">
|
|
|
|
|
|
|
|
<title> Advanced Linux Sound Architecture - Library API</title>
|
|
|
|
<H1 align=center>Advanced Linux Sound Architecture - Library API </H1>
|
|
|
|
<p>
|
|
|
|
<H3 align=center><b>Jaroslav Kysela <perex@jcu.cz></b> with assistance from Alan Robinson and Fred Floberg</H3>
|
|
|
|
<p>
|
|
|
|
<H3 align=center>1998-11-11 </H3>
|
|
|
|
<p>
|
|
<center> <i>This document describes, in full detail, the Advanced Linux
|
|
Sound Architecture library API. </i>
|
|
<p>
|
|
</center>
|
|
<H1>Contents </H1><A href="#tth_sEc1"
|
|
>1 Introduction</A><br>
|
|
<A href="#tth_sEc2"
|
|
>2 Error Codes</A><br>
|
|
<A href="#tth_sEc2.1"
|
|
>2.1 Error Codes in Detail</A><br>
|
|
<A href="#tth_sEc2.2"
|
|
>2.2 Functions</A><br>
|
|
<A href="#tth_sEc3"
|
|
>3 Control Interface</A><br>
|
|
<A href="#tth_sEc3.1"
|
|
>3.1 Low-Level Layer</A><br>
|
|
<A href="#tth_sEc3.1.1"
|
|
>3.1.1 Examples</A><br>
|
|
<A href="#tth_sEc4"
|
|
>4 Mixer Interface</A><br>
|
|
<A href="#tth_sEc4.1"
|
|
>4.1 Low-Level Layer</A><br>
|
|
<A href="#tth_sEc4.1.1"
|
|
>4.1.1 Examples</A><br>
|
|
<A href="#tth_sEc5"
|
|
>5 Digital Audio (PCM) Interface</A><br>
|
|
<A href="#tth_sEc5.1"
|
|
>5.1 Low-Level Layer</A><br>
|
|
<A href="#tth_sEc5.1.1"
|
|
>5.1.1 Example</A><br>
|
|
<A href="#tth_sEc5.2"
|
|
>5.2 PCM Loopback Interface</A><br>
|
|
<A href="#tth_sEc6"
|
|
>6 RawMidi Interface</A><br>
|
|
<A href="#tth_sEc6.1"
|
|
>6.1 Low Level Layer</A><br>
|
|
<A href="#tth_sEc6.1.1"
|
|
>6.1.1 Example</A><br>
|
|
|
|
<p>
|
|
<H2><A NAME="tth_sEc1">
|
|
1</A> Introduction</H2>
|
|
|
|
<p>
|
|
The Advanced Linux Sound Architecture comes with a kernel API & library API.
|
|
This document describes the library API and how it interfaces with the kernel
|
|
API. The kernal API will probably never be documented in standalone form.
|
|
|
|
<p>
|
|
Application programmers should use the library API rather than kernel API. The
|
|
Library offers 100% of the functionally of the kernel API, but add major improvements
|
|
in usability, making the application code simpler and better looking. In addition,
|
|
some of the some fixes/compatibility code may be placed in the library code
|
|
instead of the kernel driver.
|
|
|
|
<p>
|
|
For a complete list of all variables and functions in the API you should look
|
|
at the following header files:
|
|
|
|
<p>
|
|
|
|
<UL>
|
|
<li> /usr/include/sys/asoundlib.h
|
|
|
|
<li> /usr/include/linux/asound.h
|
|
|
|
<li> /usr/include/linux/asoundid.h
|
|
</UL>
|
|
<p>
|
|
<H2><A NAME="tth_sEc2">
|
|
2</A> Error Codes</H2>
|
|
|
|
<p>
|
|
All functions return int (or some sort of signed value). If this value is negative
|
|
it represents an error code. Codes up to <i>SND_ERROR_BEGIN (500000)</i>
|
|
represent standard system errors. Codes equal to or greather than this value
|
|
represent sound library API errors. All error codes begin with the prefix <i>SND_ERROR_</i>.
|
|
|
|
<p>
|
|
<H3><A NAME="tth_sEc2.1">
|
|
2.1</A> Error Codes in Detail</H3>
|
|
|
|
<p>
|
|
|
|
<table border>
|
|
<tr><td align="center">SND_ERROR_UNCOMPATIBLE_VERSION</td><td align="center">500000</td></td></table>
|
|
|
|
|
|
<p>
|
|
This error is caused if the driver uses an incompatible kernel API for this
|
|
interface and hence the library doesn't know how this API can be used.
|
|
|
|
<p>
|
|
<H3><A NAME="tth_sEc2.2">
|
|
2.2</A> Functions</H3>
|
|
|
|
<p>
|
|
|
|
<H4>const char *snd_strerror(int errnum) </H4>
|
|
|
|
<p>
|
|
This function converts an error code to a string. Its functionality is the same
|
|
as the <i>strerror</i> function from the standard C library, but this function
|
|
returns error message strings for sound error codes, as well.
|
|
|
|
<p>
|
|
<H2><A NAME="tth_sEc3">
|
|
3</A> Control Interface</H2>
|
|
|
|
<p>
|
|
The control interface gives applications various information about the currently
|
|
installed sound driver in the system. The interface should be used to detect
|
|
if another sound interface is present for a selected soundcard or, for example,
|
|
to create a list of devices (MIXER, PCM etc) from which the user can select.
|
|
|
|
<p>
|
|
<H3><A NAME="tth_sEc3.1">
|
|
3.1</A> Low-Level Layer</H3>
|
|
|
|
<p>
|
|
|
|
<H4>int snd_cards(void)</H4>
|
|
|
|
<p>
|
|
Returns the number of soundcards present in the system, if any. Otherwise it
|
|
returns a negative value, which maps to an error code. This function will return
|
|
0 if no soundcards are detected.
|
|
|
|
<p>
|
|
|
|
<H4>unsigned int snd_cards_mask(void)</H4>
|
|
|
|
<p>
|
|
Returns the bitmap of soundcards present in the system, if any. This function
|
|
will return 0 if no soundcards are detected. The first soundcard is represented
|
|
with bit 0 (0x00000001). See the documentation on installing ALSA and /etc/conf.modules
|
|
configuration for information on assigning numbers to soundcards.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_card_name(const char *name)</H4>
|
|
|
|
<p>
|
|
Returns soundcard number for appropriate soundcard name. String <i>name</i>
|
|
can contain word identification for card (ALSA driver allows the user choose
|
|
card identification using snd_id module parameter) or soundcard index (1-N)
|
|
encoded into ASCII.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_open(void **handle, int card)</H4>
|
|
|
|
<p>
|
|
Creates a new handle and opens communication with the kernel sound control interface
|
|
for soundcard number <i>card</i> (0-N). The function also checks if the protocol
|
|
is compatible, so as to prevent the use of old programs with a new kernel API.
|
|
Function returns zero if successful, otherwise an error code is returned.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_close(void *handle)</H4>
|
|
|
|
<p>
|
|
Frees all resources allocated with control handle and closes the kernel sound
|
|
control interface. This function returns zero if successful, otherwise it returns
|
|
an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_file_descriptor(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns a file descriptor for the kernel sound control interface. This function
|
|
is normally only used in very special cases. This function returns a negative
|
|
error code if an error was encountered.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_hw_info(void *handle, snd_ctl_hw_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the info structure with data about the sound hardware referenced by handle.
|
|
This function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* driver has MIDI interface */ </i>
|
|
|
|
<p>
|
|
#define SND_CTL_GCAPS_MIDI 0x0000001
|
|
|
|
<p>
|
|
<i>/* soundcard has synthesizer */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_LCAPS_SYNTH 0x0000001
|
|
|
|
<p>
|
|
<i>/* soundcard has RAW FM/OPL3 */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_LCAPS_RAWFM 0x0000002
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_ctl_hw_info {
|
|
|
|
<p>
|
|
<i>/* type of card - see SND_CARD_TYPE_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i>/* global capabilities - see SND_CTL_GCAPS_XXXX*/</i>
|
|
|
|
<p>
|
|
unsigned int gcaps;
|
|
|
|
<p>
|
|
<i>/* local capabilities ¯ see SND_CTL_LCAPS_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int lcaps;
|
|
|
|
<p>
|
|
<i>/* count of PCM devices (0 to N) */</i>
|
|
|
|
<p>
|
|
unsigned int pcmdevs;
|
|
|
|
<p>
|
|
<i>/* count of MIXER devices (0 to N)*/</i>
|
|
|
|
<p>
|
|
unsigned int mixerdevs;
|
|
|
|
<p>
|
|
<i>/* count of raw MIDI devices (0 to N) */</i>
|
|
|
|
<p>
|
|
unsigned int mididevs;
|
|
|
|
<p>
|
|
<i>/* ID of card (user selectable) */</i>
|
|
|
|
<p>
|
|
char id[80];
|
|
|
|
<p>
|
|
<i>/* name/info text about soundcard */</i>
|
|
|
|
<p>
|
|
char name[80];
|
|
|
|
<p>
|
|
<i>/* count of control switches */</i>
|
|
|
|
<p>
|
|
unsigned int switches;
|
|
|
|
<p>
|
|
<i>/* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[124];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_ctl_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns the number of control switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if the soundcard doesn't have any control
|
|
switches.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns the index for the switch with the name <i>switch_id</i>. This function
|
|
returns switch index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_switch_read(void *handle int switchn snd_ctl_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about the switch with index <i>switchn</i>.
|
|
This function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* 0 or 1 (enable member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_SW_TYPE_BOOLEAN 0
|
|
|
|
<p>
|
|
<i>/* 0 to 255 - from low to high (data8[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_SW_TYPE_BYTE 1
|
|
|
|
<p>
|
|
<i>/* 0 to 65535 - from low to high (data16[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_SW_TYPE_WORD 2
|
|
|
|
<p>
|
|
<i>/* 0 to 4294967296 ¯ from low to high (data32[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_SW_TYPE_DWORD 3
|
|
|
|
<p>
|
|
<i>/* user type - no type control */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_SW_TYPE_USER (~0)
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* well known (named) switches */</i>
|
|
|
|
<p>
|
|
#define SND_CTL_SW_JOYSTICK "Joystick"
|
|
|
|
<p>
|
|
#define SND_CTL_SW_JOYSTICK_ADDRESS "Joystick Address"
|
|
|
|
<p>
|
|
#define SND_CTL_SW_JOYSTICK_SPEED "Joystick Speed"
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_ctl_switch {
|
|
|
|
<p>
|
|
<i>/* switch index (filled by application) */</i>
|
|
|
|
<p>
|
|
unsigned int switchn;
|
|
|
|
<p>
|
|
<i>/* indentification of switch (for driver) */</i>
|
|
|
|
<p>
|
|
unsigned char name[32];
|
|
|
|
<p>
|
|
<i>/* type of switch value - See SND_CTL_SW_TYPE_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i>/* low range value */</i>
|
|
|
|
<p>
|
|
unsigned int low;
|
|
|
|
<p>
|
|
<i>/* high range value */</i>
|
|
|
|
<p>
|
|
unsigned int high;
|
|
|
|
<p>
|
|
union {
|
|
|
|
<p>
|
|
unsigned int enable; <i>/* 0 = off 1 = on */</i>
|
|
|
|
<p>
|
|
unsigned char data8[32]; <i>/* 8-bit data */</i>
|
|
|
|
<p>
|
|
unsigned short data16[16]; <i>/* 16-bit data */</i>
|
|
|
|
<p>
|
|
unsigned int data32[8]; <i>/* 32-bit data */</i>
|
|
|
|
<p>
|
|
} value;
|
|
|
|
<p>
|
|
<i>/* reserved for future use ¯ must be zero !!! */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[32];
|
|
|
|
<p>
|
|
}
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_ctl_switch_write(void *handle int switchn snd_ctl_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about the switch with index
|
|
<i>switchn</i> to kernel. This function returns zero if successful, otherwise
|
|
it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_mixer_info(void *handle, int dev, snd_mixer_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the *info structure with data about the mixer device. Returns zero if
|
|
successful, otherwise it returns an error code. Details about the <i>snd_mixer_info_t</i>
|
|
structure are in the <b>Mixer Interface</b> section. The argument <i>dev</i>
|
|
specifies the device number for the appropriate soundcard. Its range is 0 to
|
|
N where N is determined by <i>struct snd_ctl_hw_info->mixerdevs - 1</i>.
|
|
It should be used to collect information about mixer devices.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_mixer_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of mixer switches. In this context 'switch' means universal control
|
|
interface between kernel and application which allows various types control.
|
|
This function returns count if successful, otherwise it returns an error code.
|
|
Return value should be zero if soundcard doesn't have any mixer switches.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_mixer_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns the index for the switch with the name <i>switch_id</i>. This function
|
|
returns switch index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_mixer_switch_read(void *handle int switchn snd_mixer_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about the switch with index <i>switchn</i>.
|
|
This function returns zero if successful, otherwise it returns an error code.
|
|
Details about the <i>snd_mixer_switch_t</i> structure are in the <b>Mixer
|
|
Interface</b> section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_mixer_switch_write(void *handle int switchn snd_mixer_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_mixer_switch_t</i> structure are in the
|
|
<b>Mixer Interface</b> Interface section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_info(void *handle, int dev, snd_pcm_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the PCM device. Function
|
|
returns zero if successful, otherwise it returns an error code. Details about
|
|
the <i>snd_pcm_info_t</i> structure are in the <b>Digital Audio (PCM)</b>
|
|
Interface section. The argument <i>dev</i> selects the device number for the
|
|
sound card referenced by <i>*handle</i>. Its range is 0 to N where N is
|
|
<i>struct snd_ctl_hw_info->pcmdevs - 1</i>. This function will work if
|
|
the selected PCM device is busy, too. It should be used to collect information
|
|
about PCM devices without exclusive lock.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_playback_info(void *handle, int dev, snd_pcm_playback_info_t
|
|
*info) </H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the PCM device and playback
|
|
direction. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_pcm_playback_info_t</i> structure are in
|
|
the <b>Digital Audio (PCM) Interface</b> section. The argument <i>dev</i>
|
|
selects the device number for the sound card referenced by <i>*handle</i>.
|
|
Its range is 0 to N where N is <i>struct snd_ctl_hw_info->pcmdevs -
|
|
1</i>. This function will work if the selected PCM device is busy, too. It should
|
|
be used to collect information about PCM devices without exclusive lock.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_playback_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of PCM playback switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any PCM playback
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_playback_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_playback_switch_read(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code. Details
|
|
about the <i>snd_pcm_switch_t</i> structure are in the <b>Digital
|
|
Audio (PCM)</b> Interface section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_playback_switch_write(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_pcm_switch_t</i> structure are in the <b>Digital
|
|
Audio (PCM)</b> Interface section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_record_info(void *handle, int dev, snd_pcm_record_info_t
|
|
*info)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the PCM device and record
|
|
direction. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_pcm_record_info_t</i> structure are in
|
|
the <b>Digital Audio (PCM) Interface</b> section. The argument <i>dev</i>
|
|
selects the device number for the sound card referenced by <i>*handle</i>.
|
|
Its range is 0 to N where N is <i>struct snd_ctl_hw_info->pcmdevs -
|
|
1</i>. This function will work if the selected PCM device is busy, too. It should
|
|
be used to collect information about PCM devices without exclusive lock.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_record_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of PCM record switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any PCM record
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_record_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_record_switch_read(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code. Details
|
|
about the <i>snd_pcm_switch_t</i> structure are in the <b>Digital
|
|
Audio (PCM)</b> Interface section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_pcm_record_switch_write(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_pcm_switch_t</i> structure are in the <b>Digital
|
|
Audio (PCM)</b> Interface section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_info(void *handle, int dev, snd_rawmidi_info_t
|
|
*info)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the rawmidi device. Function
|
|
returns zero if successful, otherwise it returns an error code. Details about
|
|
the <i>snd_rawmidi_info_t</i> structure are in the <b>RawMidi Interface</b>
|
|
section. The argument <i>dev</i> selects the device number for the sound card
|
|
referenced by <i>*handle</i>. Its range is 0 to N where N is <i>struct
|
|
snd_ctl_hw_info->mididevs - 1</i>. This function will work if the selected rawmidi
|
|
device is busy, too. It should be used to collect information about rawmidi
|
|
devices without exclusive lock.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_output_info(void *handle, int dev, snd_rawmidi_output_info_t
|
|
*info) </H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the rawmidi device and
|
|
output direction. Function returns zero if successful, otherwise it returns
|
|
an error code. Details about the <i>snd_pcm_playback_info_t</i> structure
|
|
are in the <b>RawMidi Interface</b> section. The argument <i>dev</i> selects
|
|
the device number for the sound card referenced by <i>*handle</i>. Its range
|
|
is 0 to N where N is <i>struct snd_ctl_hw_info->mididevs - 1</i>. This
|
|
function will work if the selected rawmidi device is busy, too. It should be
|
|
used to collect information about rawmidi devices without exclusive lock.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_output_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of rawmidi output switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any control switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_output_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code. Return value should
|
|
be zero if sound card doesn't have any rawmidi output switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_output_switch_read(void *handle int switchnsnd_rawmidi_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code. Details
|
|
about the <i>snd_rawmidi_switch_t</i> structure are in the <b>RawMidi
|
|
Interface</b> section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_output_switch_write(void *handle int switchnsnd_rawmidi_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_rawmidi_switch_t</i> structure are in the
|
|
<b>RawMidi Interface</b> section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_input_info(void *handle, int dev, snd_rawmidi_input_info_t
|
|
*info)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the rawmidi device and
|
|
input direction. Function returns zero if successful, otherwise it returns an
|
|
error code. Details about the <i>snd_rawmidi_record_info_t</i> structure
|
|
are in the <b>RawMidi Interface</b> section. The argument <i>dev</i> selects
|
|
the device number for the sound card referenced by <i>*handle</i>. Its range
|
|
is 0 to N where N is <i>struct snd_ctl_hw_info->pcmdevs - 1</i>. This function
|
|
will work if the selected rawmidi device is busy, too. It should be used to
|
|
collect information about rawmidi devices without exclusive lock.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_input_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of rawmidi input switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any rawmidi input
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_input_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_input_switch_read(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code. Details
|
|
about the <i>snd_rawmidi_switch_t</i> structure are in the <b>RawMidi
|
|
Interface</b> Interface section.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_ctl_rawmidi_input_switch_write(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code. Details about the <i>snd_rawmidi_switch_t</i> structure are in the
|
|
<b>RawMidi Interface</b> section.
|
|
|
|
<p>
|
|
<H4><A NAME="tth_sEc3.1.1">
|
|
3.1.1</A> Examples</H4>
|
|
|
|
<p>
|
|
The following example shows how all PCM devices can be detected for the first
|
|
sound card (#0) in the system.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
int card = 0, err;
|
|
|
|
<p>
|
|
void *handle;
|
|
|
|
<p>
|
|
snd_ctl_hw_info_t info;<br>
|
|
|
|
<p>
|
|
if ((err = snd_ctl_open(&handle, card)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "open failed: %s\n", snd_strerror(err));
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
if ((err = snd_ctl_hw_info(handle, &info)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "hw info failed: %s\n",
|
|
|
|
<p>
|
|
snd_strerror(err));
|
|
|
|
<p>
|
|
snd_ctl_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
printf("Installed PCM devices for card #i: %i\n",
|
|
|
|
<p>
|
|
card + 1, info.pcmdevs);
|
|
|
|
<p>
|
|
snd_ctl_close(handle);
|
|
</DL>
|
|
<p>
|
|
<H2><A NAME="tth_sEc4">
|
|
4</A> Mixer Interface</H2>
|
|
|
|
<p>
|
|
The Mixer Interface allows applications to change the volume level of a sound
|
|
card's input/output channels in both the linear range percentage range
|
|
(0-100) and in decibels. It also supports features like hardware mute, input
|
|
sound source, stereo signal routing etc.
|
|
|
|
<p>
|
|
<H3><A NAME="tth_sEc4.1">
|
|
4.1</A> Low-Level Layer</H3>
|
|
|
|
<p>
|
|
Mixer devices aren't opened exclusively. This allows applications to open a
|
|
device multiple times with one or more processes.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_open(void **handle, int card, int device) </H4>
|
|
|
|
<p>
|
|
Creates new handle and opens a connection to the kernel sound mixer interface
|
|
for sound card number <i>card</i> (0-N) and mixer device number <i>device</i>.
|
|
Also checks if protocol is compatible to prevent use of old programs with new
|
|
kernel API. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_close(void *handle)</H4>
|
|
|
|
<p>
|
|
Frees all resources allocated to the mixer handle and closes its connection
|
|
to the kernel sound mixer interface. Function returns zero if successful, otherwise
|
|
it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_file_descriptor(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns the file descriptor for the connection to the kernel sound mixer interface.
|
|
This function should be used only in very special cases. Function returns a
|
|
negative error code if an error was encountered.
|
|
|
|
<p>
|
|
The file descriptor should be used for the <i>select(2)</i> synchronous multiplexer
|
|
function for determining read direction. Applications should call <i>snd_mixer_read()</i>
|
|
function if some data is waiting to be read. It is recommended that you do this,
|
|
since it leaves place for this function to handle some new kernel API specifications.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_channels(void *handle) </H4>
|
|
|
|
<p>
|
|
Returns the count of mixer channels for appropriate mixer device, otherwise
|
|
the return value is negative, and signifies an error code. Never returns zero.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_info(void *handle, snd_mixer_info_t *info) </H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with information about the mixer associated
|
|
with <i>*handle</i>. Returns zero if successful, otherwise it returns an
|
|
error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* mixer can do only exclusive record */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_INFO_CAP_EXCL_RECORD 0x00000001
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_mixer_info {
|
|
|
|
<p>
|
|
<i>/* type of sound card - SND_CARD_TYPE_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i>/* count of mixer devices */</i>
|
|
|
|
<p>
|
|
unsigned int channels;
|
|
|
|
<p>
|
|
<i>/* some flags about this device (SND_MIXER_INFO_CAP_XXXX) */</i>
|
|
|
|
<p>
|
|
unsigned int caps;
|
|
|
|
<p>
|
|
<i>/* ID of this mixer */</i>
|
|
|
|
<p>
|
|
unsigned char id[32];
|
|
|
|
<p>
|
|
<i>/* name of this device */</i>
|
|
|
|
<p>
|
|
unsigned char name[80];
|
|
|
|
<p>
|
|
<i>/* reserved for future use */</i>
|
|
|
|
<p>
|
|
char reserved[ 32 ];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_mixer_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of mixer switches. In this context 'switch' means universal control
|
|
interface between kernel and application which allows various types of control.
|
|
Function returns count if successful, otherwise it returns an error code. Return
|
|
value will be zero if sound card doesn't have any mixer switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_switch_read(void *handle int switchn snd_mixer_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* 0 or 1 (enable member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_TYPE_BOOLEAN 0
|
|
|
|
<p>
|
|
<i>/* 0 to 255 - from low to high (data8[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_TYPE_BYTE 1
|
|
|
|
<p>
|
|
<i>/* 0 to 65535 - from low to high (data16[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_TYPE_WORD 2
|
|
|
|
<p>
|
|
<i>/* 0 to 4294967296 ¯ from low to high (data32[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_TYPE_DWORD 3
|
|
|
|
<p>
|
|
<i>/* user type - no type control */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_TYPE_USER (~0)
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* well known (named) switches */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_LOUDNESS "Loudness" <i>/* bass boost */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_SIM_STEREO "Simulated Stereo Enhancement"
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_3D "3D Stereo Enhancement"
|
|
|
|
<p>
|
|
<i>/* microphone gain */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_MIC_GAIN "MIC Gain"
|
|
|
|
<p>
|
|
<i>/* microphone auto gain control */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_MIC_GAIN "MIC Auto-Gain-Control"
|
|
|
|
<p>
|
|
<i>/* change microphone impedance */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_MIC_GAIN "Change MIC Impedance"
|
|
|
|
<p>
|
|
<i>/* change line-in to output */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_MIC_GAIN "Line In to Output"
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_IEC958OUT "IEC-958 (S/PDIF) Output"
|
|
|
|
<p>
|
|
#define SND_MIXER_SW_IEC958IN "IEC-958 (S/PDIF) Input"
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_mixer_switch {
|
|
|
|
<p>
|
|
<i>/* switch index (filled by application) */</i>
|
|
|
|
<p>
|
|
unsigned int switchn;
|
|
|
|
<p>
|
|
<i>/* identification of switch (for driver) */</i>
|
|
|
|
<p>
|
|
unsigned char name[32];
|
|
|
|
<p>
|
|
<i>/* type of switch value ¯ See SND_CTL_SW_TYPE_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i>/* low range value */</i>
|
|
|
|
<p>
|
|
unsigned int low;
|
|
|
|
<p>
|
|
<i>/* high range value */</i>
|
|
|
|
<p>
|
|
unsigned int high;
|
|
|
|
<p>
|
|
union {
|
|
|
|
<p>
|
|
unsigned int enable; <i>/* 0 = off 1 = on */</i>
|
|
|
|
<p>
|
|
unsigned char data8[32]; <i>/* 8-bit data */</i>
|
|
|
|
<p>
|
|
unsigned short data16[16]; <i>/* 16-bit data */</i>
|
|
|
|
<p>
|
|
unsigned int data32[8]; <i>/* 32-bit data */</i>
|
|
|
|
<p>
|
|
} value;
|
|
|
|
<p>
|
|
<i>/* reserved for future use ¯ must be zero !!! */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[32];
|
|
|
|
<p>
|
|
}
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_mixer_switch_write(void *handle int switchn snd_mixer_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_exact_mode(void *handle, int enable)</H4>
|
|
|
|
<p>
|
|
Turns on = 1 or off = 0 (by default) exact mode. This mode allows application
|
|
to set/get volume values in exact range which uses hardware. In non-exact mode
|
|
range is always from percentage 0 to 100 and driver does conversion to hardware
|
|
range. Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_channel(void *handle, const char *channel_id)</H4>
|
|
|
|
<p>
|
|
Returns the channel number (index) associated with <i>channel_id</i> (channel
|
|
name), or returns an error code. Note: Below mixer channel IDs are subject to
|
|
change and will be extended if new hardware has support for other mixer input/output
|
|
channels.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_MIXER_ID_MASTER "Master"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MASTER1 "Master 1"
|
|
|
|
<p>
|
|
<i>/* digital master */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MASTERD "Master D"
|
|
|
|
<p>
|
|
<i>/* second digital master */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MASTERD1 "Master D1"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_HEADPHONE "Headphone"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MASTER_MONO "Master M"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_3D "3D Wide"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_3D_VOLUME "3D Volume"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_3D_CENTER "3D Center"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_3D_SPACE "3D Space"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_3D_DEPTH "3D Depth"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_BASS "Bass"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_TREBLE "Treble"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_FADER "Fader"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_SYNTHESIZER "Synth"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_SYNTHESIZER1 "Synth 1"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_FM "FM"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_EFFECT "Effect"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_DSP "DSP"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_PCM "PCM"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_PCM1 "PCM 1"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_LINE "Line-In"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MIC "MIC"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_CD "CD"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_VIDEO "Video"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_PHONE "Phone"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_GAIN "Record-Gain"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MIC_GAIN "Mic-Gain"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_IGAIN "In-Gain"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_OGAIN "Out-Gain"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_LOOPBACK "Loopback"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_SPEAKER "PC Speaker"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MONO "Mono"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MONO1 "Mono 1"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_MONO2 "Mono 2"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_AUXA "Aux A"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_AUXB "Aux B"
|
|
|
|
<p>
|
|
#define SND_MIXER_ID_AUXC "Aux C"
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_mixer_channel_info(void *handle, int channel, snd_mixer_channel_info_t
|
|
*info) </H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure. The argument <i>channel</i> specifies
|
|
channel (0 to N) for which is the info requested. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* mixer channel is record source */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_RECORD 0x00000001
|
|
|
|
<p>
|
|
<i>/* mixer channel is stereo */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_STEREO 0x00000002
|
|
|
|
<p>
|
|
<i>/* always set at this moment driver emulates mute */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_MUTE 0x00000004
|
|
|
|
<p>
|
|
<i>/* channel supports hardware mute */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_HWMUTE 0x00000008
|
|
|
|
<p>
|
|
<i>/* channel does digital (not analog) mixing */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_DIGITAL 0x00000010
|
|
|
|
<p>
|
|
<i>/* external input channel */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_INPUT 0x00000020
|
|
|
|
<p>
|
|
<i>/* join mute is supported only */</i>
|
|
|
|
<p>
|
|
<i>/* left and right channel doesn't have separate mute control */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_JOINMUTE 0x00000040
|
|
|
|
<p>
|
|
<i>/* join record is supported only *</i>
|
|
|
|
<p>
|
|
<i>/* left and right channel doesn't have separate record control */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_JOINRECORD 0x00000080
|
|
|
|
<p>
|
|
<i>/* route left input to right output is supported */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_LTOR_OUT 0x00000100
|
|
|
|
<p>
|
|
<i>/* route right input to left output is supported */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_RTOL_OUT 0x00000200
|
|
|
|
<p>
|
|
<i>/* route left input to right ADC is supported */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_LTOR_IN 0x00000400
|
|
|
|
<p>
|
|
<i>/* route right input to left ADC is supported */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_RTOL_IN 0x00000800
|
|
|
|
<p>
|
|
<i>/* output route is only switch (cannot be used separately) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_SWITCH_OUT 0x00001000
|
|
|
|
<p>
|
|
<i>/* input route is only switch (cannot be used separately) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_SWITCH_IN 0x00002000
|
|
|
|
<p>
|
|
<i>/* data can be recorded even if output path is muted */</i>
|
|
|
|
<p>
|
|
<i>/* (to avoid loopback) */</i>
|
|
|
|
<p>
|
|
#define SND_MIXER_CINFO_CAP_RECORDBYMUTE 0x00004000
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_mixer_channel_info {
|
|
|
|
<p>
|
|
<i> /* channel index (filled by application) */</i>
|
|
|
|
<p>
|
|
unsigned int channel;
|
|
|
|
<p>
|
|
<i> /* parent channel # or SND_MIXER_PARENT */</i>
|
|
|
|
<p>
|
|
unsigned int parent;
|
|
|
|
<p>
|
|
<i> /* name of this device */</i>
|
|
|
|
<p>
|
|
unsigned char name[12];
|
|
|
|
<p>
|
|
<i> /* some flags about this device (SND_MIXER_CINFO_XXXX) */</i>
|
|
|
|
<p>
|
|
unsigned int caps;
|
|
|
|
<p>
|
|
<i> /* min. value when exact mode (or always 0) */</i>
|
|
|
|
<p>
|
|
int min;
|
|
|
|
<p>
|
|
<i> /* max. value when exact mode (or always 100) */ </i>
|
|
|
|
<p>
|
|
int max;
|
|
|
|
<p>
|
|
<i> /* minimum decibel value (*100) */</i>
|
|
|
|
<p>
|
|
int min_dB;
|
|
|
|
<p>
|
|
<i> /* maximum decibel value (*100) */</i>
|
|
|
|
<p>
|
|
int max_dB;
|
|
|
|
<p>
|
|
<i> /* step decibel value (*100) */</i>
|
|
|
|
<p>
|
|
int step_dB;
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_mixer_channel_read(void *handle, int channel, snd_mixer_channel_t
|
|
*data) </H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure. The argument <i>channel</i> specifies
|
|
the channel (0 to N) for which is data requested. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
/* channel record source flags */
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_RECORD_LEFT 0x00000001
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_RECORD_RIGHT 0x00000002
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_RECORD 0x00000003
|
|
|
|
<p>
|
|
/* mute channel flags */
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_MUTE_LEFT 0x00010000
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_MUTE_RIGHT 0x00020000
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_MUTE 0x00030000
|
|
|
|
<p>
|
|
/* input to output route setup */
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_LTOR_OUT 0x00100000
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_RTOL_OUT 0x00200000
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_SWITCH_OUT 0x00300000
|
|
|
|
<p>
|
|
/* input to ADC route setup */
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_LTOR_IN 0x00400000
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_RTOL_IN 0x00800000
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_SWITCH_IN 0x00c00000
|
|
|
|
<p>
|
|
/* set volume in decibels from dB variables */
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_DECIBEL 0x40000000
|
|
|
|
<p>
|
|
/* reserved for kernel use, don't use this flag from application */
|
|
|
|
<p>
|
|
#define SND_MIXER_FLG_FORCE 0x80000000
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_mixer_channel {
|
|
|
|
<p>
|
|
/* channel # (filled by application) */
|
|
|
|
<p>
|
|
unsigned int channel;
|
|
|
|
<p>
|
|
/* some flags to read/write (SND_MIXER_FLG_XXXX) */
|
|
|
|
<p>
|
|
unsigned int flags;
|
|
|
|
<p>
|
|
/* min - max when exact mode (or 0 - 100) */
|
|
|
|
<p>
|
|
int left;
|
|
|
|
<p>
|
|
/* min - max when exact mode (or 0 - 100) */
|
|
|
|
<p>
|
|
int right;
|
|
|
|
<p>
|
|
/* dB * 100 */
|
|
|
|
<p>
|
|
int left_dB;
|
|
|
|
<p>
|
|
/* dB * 100 */
|
|
|
|
<p>
|
|
int right_dB;
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_mixer_channel_write(void *handle, int channel, snd_mixer_channel_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure to kernel. The <i>channel</i> argument
|
|
specifies the channel (0 to N) for which is data is to be applied. Function
|
|
returns zero if successful, otherwise it returns an error code. This functions
|
|
is the opposite of <i>snd_mixer_channel_read</i>.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_mixer_read(void *handle, snd_mixer_callbacks_t *callbacks)</H4>
|
|
|
|
<p>
|
|
This function reads and parses data from driver. Parsed actions are returned
|
|
back to the application using the <i>callbacks</i> structure. Applications
|
|
should not parse data from the driver in standard cases. This function returns
|
|
immediately after all data is read from driver. Does not block process.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
typedef struct snd_mixer_callbacks {
|
|
|
|
<p>
|
|
/* should be used by application */
|
|
|
|
<p>
|
|
void *private_data;
|
|
|
|
<p>
|
|
void (*channel_was_changed)(void *private_data, int channel);
|
|
|
|
<p>
|
|
void (*switch_was_changed)(void *private_data, int switchn);
|
|
|
|
<p>
|
|
/* reserved for future use - must be NULL!!! */
|
|
|
|
<p>
|
|
void *reserved[14];
|
|
|
|
<p>
|
|
} snd_mixer_callbacks_t;
|
|
</DL>
|
|
<p>
|
|
<H4><A NAME="tth_sEc4.1.1">
|
|
4.1.1</A> Examples</H4>
|
|
|
|
<p>
|
|
The following example shows installed mixer channels for sound card #0 and
|
|
mixer device #0 in the system, and also sets the master volume (if present)
|
|
to 50.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
int card = 0, device = 0, err;
|
|
|
|
<p>
|
|
void *handle;
|
|
|
|
<p>
|
|
snd_mixer_info_t info;
|
|
|
|
<p>
|
|
snd_mixer_channel_t channel;
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
if ((err = snd_mixer_open(&handle, card, device)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "open failed: %s\n", snd_strerror(err));
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
if ((err = snd_mixer_info(handle, &info)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "info failed: %s\n", snd_strerror(err));
|
|
|
|
<p>
|
|
snd_mixer_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
printf("Installed MIXER channels for card #i and device %i: %i\n", card + 1, device,
|
|
|
|
<p>
|
|
info.channels);
|
|
|
|
<p>
|
|
master = snd_mixer_channel(handle, SND_MIXER_ID_MASTER);
|
|
|
|
<p>
|
|
if (master >= 0) {
|
|
|
|
<p>
|
|
if ((err = snd_mixer_read(handle, master, &channel)) < 0) { fprintf(stderr, "master read failed: %s\n", snd_strerror( err ));
|
|
|
|
<p>
|
|
snd_mixer_close( handle );
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
channel.left = channel.right = 50;
|
|
|
|
<p>
|
|
if ((err = snd_mixer_write(handle, master, &channel)) < 0 ) { fprintf(stderr, "master write failed: %s\n", snd_strerror( err ));
|
|
|
|
<p>
|
|
snd_mixer_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
snd_mixer_close(handle);
|
|
</DL>
|
|
<p>
|
|
<H2><A NAME="tth_sEc5">
|
|
5</A> Digital Audio (PCM) Interface</H2>
|
|
|
|
<p>
|
|
Digital audio is the most commonly used method of representing sound inside
|
|
a computer. In this method sound is stored as a sequence of samples taken from
|
|
the audio signal using constant time intervals. A sample represents volume of
|
|
the signal at the moment when it was measured. In uncompressed digital audio
|
|
each sample require one or more bytes of storage. The number of bytes required
|
|
depends on number of channels (mono, stereo) and sample format (8 or 16 bits,
|
|
mu-Law, etc.). The length of this interval determines the sampling rate. Commonly
|
|
used sampling rates are between 8 kHz (telephone quality) and 48 kHz (DAT tapes).
|
|
|
|
<p>
|
|
The physical devices used in digital audio are called the ADC (Analog to Digital
|
|
Converter) and DAC (Digital to Analog Converter). A device containing both ADC
|
|
and DAC is commonly known as a codec. The codec device used in a Sound Blaster
|
|
cards is called a DSP which is somewhat misleading since DSP also stands for
|
|
Digital Signal Processor (the SB DSP chip is very limited when compared to "true"
|
|
DSP chips).
|
|
|
|
<p>
|
|
Sampling parameters affect the quality of sound which can be reproduced from
|
|
the recorded signal. The most fundamental parameter is sampling rate which limits
|
|
the highest frequency that can be stored. It is well known (Nyquist's Sampling
|
|
Theorem) that the highest frequency that can be stored in a sampled signal is
|
|
at most 1/2 of the sampling frequency. For example, an 8 kHz sampling rate permits
|
|
the recording of a signal in which the highest frequency is less than 4 kHz.
|
|
Higher frequency signals must be filtered out before feeding them to DAC.
|
|
|
|
<p>
|
|
Sample encoding limits the dynamic range of a recorded signal (difference between
|
|
the faintest and the loudest signal that can be recorded). In theory the maximum
|
|
dynamic range of signal is number_of_bits * 6 dB . This means that 8 bits
|
|
sampling resolution gives dynamic range of 48 dB and 16 bit resolution gives
|
|
96 dB.
|
|
|
|
<p>
|
|
Quality has price. The number of bytes required to store an audio sequence depends
|
|
on sampling rate, number of channels and sampling resolution. For example just
|
|
8000 bytes of memory is required to store one second of sound using 8 kHz/8
|
|
bits/mono but 48 kHz/16bit/stereo takes 192 kilobytes. A 64 kbps ISDN channel
|
|
is required to transfer a 8kHz/8bit/mono audio stream in real time, and about
|
|
1.5 Mbps is required for DAT quality (48kHz/16bit/stereo). On the other hand
|
|
it is possible to store just 5.46 seconds of sound in a megabyte of memory when
|
|
using 48kHz/16bit/stereo sampling. With 8kHz/8bits/mono it is possible to store
|
|
131 seconds of sound using the same amount of memory. It is possible to reduce
|
|
memory and communication costs by compressing the recorded signal but this is
|
|
beyond the scope of this document.
|
|
|
|
<p>
|
|
<H3><A NAME="tth_sEc5.1">
|
|
5.1</A> Low-Level Layer</H3>
|
|
|
|
<p>
|
|
Audio devices are opened exclusively for a selected direction. This doesn't
|
|
allow open from more than one processes for the same audio device in the same
|
|
direction, but does allow one open call to each playback direction and second
|
|
open call to record direction independently. Audio devices return EBUSY error
|
|
to applications when other applications have already opened the requested direction.
|
|
|
|
<p>
|
|
Low-Level layer supports these formats:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* muLaw compressed samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_MU_LAW 0
|
|
|
|
<p>
|
|
<i>/* aLaw compressed samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_A_LAW 1
|
|
|
|
<p>
|
|
<i>/* Ima-ADPM 4:1 compressed samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_IMA_ADPCM 2
|
|
|
|
<p>
|
|
<i>/* Unsigned 8-bit samples (most common 8-bit format) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_U8 3
|
|
|
|
<p>
|
|
<i>/* Signed 16-bit Little Endian samples (most common 16-bit format) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_S16_LE 4
|
|
|
|
<p>
|
|
<i>/* Signed 16-bit Big Endian samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_S16_BE 5
|
|
|
|
<p>
|
|
<i>/* Signed 8-bit samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_S8 6
|
|
|
|
<p>
|
|
<i>/* Unsigned 16-bit Little Endian samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_U16_LE 7
|
|
|
|
<p>
|
|
<i>/* Unsigned 16-bit Big Endian samples */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_U16_BE 8
|
|
|
|
<p>
|
|
<i>/* MPEG 1/2 stream */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_MPEG 9
|
|
|
|
<p>
|
|
<i>/* GSM stream */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SFMT_GSM 10
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_FMT_MU_LAW (1 << SND_PCM_SFMT_MU_LAW)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_A_LAW (1 << SND_PCM_SFMT_A_LAW)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_IMA_ADPCM (1 << SND_PCM_SFMT_IMA_ADPCM)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_U8 (1 << SND_PCM_SFMT_U8)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_S16_LE (1 << SND_PCM_SFMT_S16_LE)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_S16_BE (1 << SND_PCM_SFMT_S16_BE)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_S8 (1 << SND_PCM_SFMT_S8)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_U16_LE (1 << SND_PCM_SFMT_U16_LE)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_U16_BE (1 << SND_PCM_SFMT_U16_BE)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_MPEG (1 << SND_PCM_SFMT_MPEG)
|
|
|
|
<p>
|
|
#define SND_PCM_FMT_GSM (1 << SND_PCM_SFMT_GSM)
|
|
</DL>
|
|
<p>
|
|
Constants with prefix <i>SND_PCM_FMT_</i> are used in info structures and
|
|
constants with prefix <i>SND_PCM_SFMT_</i> are used in format structures.
|
|
|
|
<p>
|
|
ALSA PCM API uses an enhanced double buffering scheme. This allows the user
|
|
to implement a more comfortable buffer setup. Audio buffer is separated to small
|
|
fragments. Each fragment has the same size. Application can set wakeup limits
|
|
like ``I want to get recorded data when at least two fragments with size 160
|
|
bytes are filled.''. For more information you should see description of <i>snd_pcm_*_params_t</i>
|
|
and <i>snd_pcm_*_status_t</i> structures and the <em>snd_pcm_playback_status(),
|
|
snd_pcm_record_status()</em> functions, documented below.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_open(void **handle, int card, int device, int mode)</H4>
|
|
|
|
<p>
|
|
Creates a new handle and opens a connection to the kernel sound audio interface
|
|
for sound card number <i>card</i> (0-N) and audio device number <i>device</i>.
|
|
Function also checks if protocol is compatible to prevent use of old programs
|
|
with a new kernel API. Function returns zero if successful otherwise it returns
|
|
an error code. Error code -EBUSY is returned when some process owns the selected
|
|
direction.
|
|
|
|
<p>
|
|
Default format after opening is mono <i>mu-Law</i> at 8000Hz. This device
|
|
can be used directly for playback of standard .au (Sparc) files.
|
|
|
|
<p>
|
|
The following modes should be used for the <i>mode</i> argument:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_OPEN_PLAYBACK (O_WRONLY)
|
|
|
|
<p>
|
|
#define SND_PCM_OPEN_RECORD (O_RDONLY)
|
|
|
|
<p>
|
|
#define SND_PCM_OPEN_DUPLEX (O_RDWR)
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_close(void *handle)</H4>
|
|
|
|
<p>
|
|
Frees all resources allocated with audio handle and closes the connection to
|
|
the kernel sound audio interface. Function returns zero if successful, otherwise
|
|
it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_file_descriptor(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns the file descriptor of the connection to the kernel sound audio interface.
|
|
Function returns an error code if an error was encountered.
|
|
|
|
<p>
|
|
The file descriptor should be used for the <i>select(2)</i> synchronous multiplexer
|
|
function for setting the read direction. Application should call <i>snd_pcm_read()</i>
|
|
or <i>snd_pcm_write()</i> functions if data is waiting to be read or a write
|
|
can be performed. Calling these functions is highly recommended, as it leaves
|
|
a place for the API to do things like data conversions, if needed.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_block_mode(void *handle, int enable) </H4>
|
|
|
|
<p>
|
|
Sets up block (default) or non-block mode for a handle. Block mode suspends
|
|
execution of a program when <i>snd_pcm_read()</i> or <i>snd_pcm_write()</i>
|
|
is called for the time which is needed for the actual playback or record over
|
|
of the selected limit. In non-block mode, programs aren't suspended and the
|
|
above functions return immediately with the count of bytes which were read or
|
|
written by the driver. When used in this way, don't try to use the entire buffer
|
|
after the call, but instead process the number of bytes returned, and call the
|
|
function again.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_info(void *handle, snd_pcm_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the PCM device selected
|
|
by <i>*handle</i>. Function returns zero if successful, otherwise it returns
|
|
an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* hardware have codec */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_CODEC 0x00000001
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_DSP SND_PCM_INFO_CODEC
|
|
|
|
<p>
|
|
<i>/* this flag is reserved and should be never used */</i>
|
|
|
|
<p>
|
|
<i>/* It remains for compatibility with Open Sound System driver. */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_MMAP 0x00000002
|
|
|
|
<p>
|
|
<i>/* playback direction is supported */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_PLAYBACK 0x00000100
|
|
|
|
<p>
|
|
<i>/* record direction is supported */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_RECORD 0x00000200
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_DUPLEX 0x00000400
|
|
|
|
<p>
|
|
<i>/* rate for playback & record must be same */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_DUPLEX_LIMIT 0x00000800
|
|
|
|
<p>
|
|
<i>/* duplex is supported only by mono (one channel) format */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_INFO_DUPLEX_MONO 0x00001000
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_info {
|
|
|
|
<p>
|
|
<i> /* sound card type */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i> /* see SND_PCM_INFO_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int flags;
|
|
|
|
<p>
|
|
<i> /* ID of this PCM device */</i>
|
|
|
|
<p>
|
|
unsigned char id[32];
|
|
|
|
<p>
|
|
<i> /* name of this device */</i>
|
|
|
|
<p>
|
|
unsigned char name[80];
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[64];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_info(void *handle, snd_pcm_playback_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the *info structure with data about PCM playback. Function returns zero
|
|
if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_PINFO_BATCH 0x00000001
|
|
|
|
<p>
|
|
#define SND_PCM_PINFO_8BITONLY 0x00000002
|
|
|
|
<p>
|
|
#define SND_PCM_PINFO_16BITONLY 0x00000004
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_playback_info {
|
|
|
|
<p>
|
|
<i> /* see SND_PCM_PINFO_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int flags;
|
|
|
|
<p>
|
|
<i> /* supported formats */ </i>
|
|
|
|
<p>
|
|
unsigned int formats;
|
|
|
|
<p>
|
|
<i> /* min rate (in Hz) */ </i>
|
|
|
|
<p>
|
|
unsigned int min_rate;
|
|
|
|
<p>
|
|
<i> /* max rate (in Hz) */ </i>
|
|
|
|
<p>
|
|
unsigned int max_rate;
|
|
|
|
<p>
|
|
<i> /* min channels - voices (probably always 1) */ </i>
|
|
|
|
<p>
|
|
unsigned int min_channels;
|
|
|
|
<p>
|
|
<i> /* max channels - voices */ </i>
|
|
|
|
<p>
|
|
unsigned int max_channels;
|
|
|
|
<p>
|
|
<i> /* playback buffer size in bytes */</i>
|
|
|
|
<p>
|
|
unsigned int buffer_size;
|
|
|
|
<p>
|
|
<i> /* min fragment size in bytes */ </i>
|
|
|
|
<p>
|
|
unsigned int min_fragment_size;
|
|
|
|
<p>
|
|
<i> /* max fragment size in bytes */</i>
|
|
|
|
<p>
|
|
unsigned int max_fragment_size;
|
|
|
|
<p>
|
|
<i> /* align fragment value */</i>
|
|
|
|
<p>
|
|
unsigned int fragment_align;
|
|
|
|
<p>
|
|
<i> /* supported formats directly by hardware */</i>
|
|
|
|
<p>
|
|
unsigned int hw_formats;
|
|
|
|
<p>
|
|
<i> /* count of playback switches */</i>
|
|
|
|
<p>
|
|
unsigned int switches;
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[56];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [SND_PCM_PINFO_BATCH]Driver implements double buffering with this device.
|
|
This means that the chip used for data processing has its own memory, and output
|
|
will be more delayed than if a traditional codec chip is used.
|
|
<dt><b></b></dt>
|
|
<dd> [SND_PCM_PINFO_8BITONLY]If this bit is set, the driver uses 8-bit format
|
|
for 16-bit samples and does software conversion. This bit is set on broken SoundBlaster
|
|
16/AWE sound cards which can't do full 16-bit duplex. If this bit is set application
|
|
or higher digital audio layer should do the conversion from 16-bit samples to
|
|
8-bit samples rather than making the driver to do it in the kernel.
|
|
<dt><b></b></dt>
|
|
<dd> [SND_PCM_PINFO_16BITONLY]If this bit is set, driver uses 16-bit format for
|
|
8-bit samples and does software conversion. This bit is set on broken SoundBlaster
|
|
16/AWE sound cards which can't do full 8-bit duplex. If this bit is set the
|
|
application or higher digital audio layer should do conversion from 8-bit samples
|
|
to 16-bit samples rather than making the driver to do it in the kernel.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_info(void *handle, snd_pcm_record_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the *info structure. Returns zero if successful, otherwise it returns
|
|
an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_RINFO_BATCH 0x00000001
|
|
|
|
<p>
|
|
#define SND_PCM_RINFO_8BITONLY 0x00000002
|
|
|
|
<p>
|
|
#define SND_PCM_RINFO_16BITONLY 0x00000004
|
|
|
|
<p>
|
|
#define SND_PCM_RINFO_OVERRANGE 0x00001000
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_record_info {
|
|
|
|
<p>
|
|
<i> /* see SND_PCM_RINFO_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int flags;
|
|
|
|
<p>
|
|
<i> /* supported formats */ </i>
|
|
|
|
<p>
|
|
unsigned int formats;
|
|
|
|
<p>
|
|
<i> /* min rate (in Hz) */ </i>
|
|
|
|
<p>
|
|
unsigned int min_rate;
|
|
|
|
<p>
|
|
<i> /* max rate (in Hz) */ </i>
|
|
|
|
<p>
|
|
unsigned int max_rate;
|
|
|
|
<p>
|
|
<i> /* min channels - voices (probably always 1) */ </i>
|
|
|
|
<p>
|
|
unsigned int min_channels;
|
|
|
|
<p>
|
|
<i> /* max channels - voices */ </i>
|
|
|
|
<p>
|
|
unsigned int max_channels;
|
|
|
|
<p>
|
|
<i> /* playback buffer size in bytes */</i>
|
|
|
|
<p>
|
|
unsigned int buffer_size;
|
|
|
|
<p>
|
|
<i> /* min fragment size in bytes */ </i>
|
|
|
|
<p>
|
|
unsigned int min_fragment_size;
|
|
|
|
<p>
|
|
<i> /* max fragment size in bytes */</i>
|
|
|
|
<p>
|
|
unsigned int max_fragment_size;
|
|
|
|
<p>
|
|
<i> /* align fragment value */</i>
|
|
|
|
<p>
|
|
unsigned int fragment_align;
|
|
|
|
<p>
|
|
<i> /* supported formats directly by hardware */</i>
|
|
|
|
<p>
|
|
unsigned int hw_formats;
|
|
|
|
<p>
|
|
<i> /* count of record switches */</i>
|
|
|
|
<p>
|
|
unsigned int switches;
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[56];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [SND_PCM_RINFO_BATCH]Driver implements double buffering with this device.
|
|
This means that the chip used for data processing has its own memory, and input
|
|
will be more delayed than if a traditional codec chip is used.
|
|
<dt><b></b></dt>
|
|
<dd> [SND_PCM_RINFO_8BITONLY]If this bit is set, the driver uses 8-bit format
|
|
for 16-bit samples and does software conversion. This bit is set on broken SoundBlaster
|
|
16/AWE sound cards which can't do full 16-bit duplex. If this bit is set application
|
|
or higher digital audio layer should do the conversion from 16-bit samples to
|
|
8-bit samples rather than making the driver to do it in the kernel.
|
|
<dt><b></b></dt>
|
|
<dd> [SND_PCM_RINFO_16BITONLY]If this bit is set, driver uses 16-bit format for
|
|
8-bit samples and does software conversion. This bit is set on broken SoundBlaster
|
|
16/AWE sound cards which can't do full 8-bit duplex. If this bit is set the
|
|
application or higher digital audio layer should do conversion from 8-bit samples
|
|
to 16-bit samples rather than making the driver to do it in the kernel.
|
|
<dt><b></b></dt>
|
|
<dd> [SND_PCM_RINFO_OVERRANGE]If this bit is set the hardware can do ADC
|
|
over-range detection.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of PCM playback switches. In this contents switch means universal
|
|
control interface between kernel and application which allows variable type
|
|
control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any PCM playback
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_switch_read(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* 0 or 1 (enable member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_BOOLEAN 0
|
|
|
|
<p>
|
|
<i>/* 0 to 255 - from low to high (data8[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_BYTE 1
|
|
|
|
<p>
|
|
<i>/* 0 to 65535 - from low to high (data16[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_WORD 2
|
|
|
|
<p>
|
|
<i>/* 0 to 4294967296 ¯ from low to high (data32[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_DWORD 3
|
|
|
|
<p>
|
|
<i>/* user type - no type control */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_USER (~0)
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_switch {
|
|
|
|
<p>
|
|
<i>/* switch index (filled by application) */</i>
|
|
|
|
<p>
|
|
unsigned int switchn;
|
|
|
|
<p>
|
|
<i>/* identification of switch (for driver) */</i>
|
|
|
|
<p>
|
|
unsigned char name[32];
|
|
|
|
<p>
|
|
<i>/* type of switch value ¯ See SND_PCM_SW_TYPE_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i>/* low range value */</i>
|
|
|
|
<p>
|
|
unsigned int low;
|
|
|
|
<p>
|
|
<i>/* high range value */</i>
|
|
|
|
<p>
|
|
unsigned int high;
|
|
|
|
<p>
|
|
union {
|
|
|
|
<p>
|
|
unsigned int enable; <i>/* 0 = off 1 = on */</i>
|
|
|
|
<p>
|
|
unsigned char data8[32]; <i>/* 8-bit data */</i>
|
|
|
|
<p>
|
|
unsigned short data16[16]; <i>/* 16-bit data */</i>
|
|
|
|
<p>
|
|
unsigned int data32[8]; <i>/* 32-bit data */</i>
|
|
|
|
<p>
|
|
} value;
|
|
|
|
<p>
|
|
<i>/* reserved for future use ¯ must be zero !!! */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[32];
|
|
|
|
<p>
|
|
}
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_switch_write(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of PCM record switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any PCM record
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_switch_read(void *handle int switchn snd_pcm_switch_t
|
|
*data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_switch_write(void *handle int switchnsnd_pcm_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_format(void *handle, snd_pcm_format_t *format)</H4>
|
|
|
|
<p>
|
|
Sets up format, rate (in Hz) and number of channels for playback, in the desired
|
|
direction. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_format {
|
|
|
|
<p>
|
|
unsigned int format; <i>/* SND_PCM_SFMT_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int rate; <i>/* rate in Hz */</i>
|
|
|
|
<p>
|
|
unsigned int channels; <i>/* channels (voices) */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_format(void *handle, snd_pcm_format_t *format) </H4>
|
|
|
|
<p>
|
|
Sets up format, rate (in Hz) and number of channels for used for recording in
|
|
the specified direction. Function returns zero if successful, otherwise it returns
|
|
an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_format {
|
|
|
|
<p>
|
|
unsigned int format; <i>/* SND_PCM_SFMT_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int rate; <i>/* rate in Hz */</i>
|
|
|
|
<p>
|
|
unsigned int channels; <i>/* channels (voices) */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_params(void *handle, snd_pcm_playback_params_t
|
|
*params)</H4>
|
|
|
|
<p>
|
|
Sets various parameters for playback direction. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_playback_params {
|
|
|
|
<p>
|
|
int fragment_size;
|
|
|
|
<p>
|
|
int fragments_max;
|
|
|
|
<p>
|
|
int fragments_room;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [fragment_size]Requested size of fragment. This value should be aligned for
|
|
current format (for example to 4 if stereo 16-bit samples are used) or with
|
|
the <i>fragment_align</i> variable from <i>snd_pcm_playback_info_t</i>
|
|
structure. Its range can be from <i>min_fragment_size</i> to <i>max_fragment_size</i>.
|
|
<dt><b></b></dt>
|
|
<dd> [fragments_max]Maximum number of fragments in queue for wakeup. This number
|
|
doesn't include partly used fragments. If the current count of filled playback
|
|
fragments is greater than this value the driver will block the application or
|
|
return immediately back if non-block mode is active.
|
|
<dt><b></b></dt>
|
|
<dd> [fragments_room]Minimum number of fragments writable for wakeup. This value
|
|
should in most cases be 1 which means return back to application if at least
|
|
one fragment is free for playback. This value includes partly used fragments,
|
|
too.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_params(void *handle, snd_pcm_record_params_t *params)</H4>
|
|
|
|
<p>
|
|
Function sets various parameters for the recording direction. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_record_params {
|
|
|
|
<p>
|
|
int fragment_size;
|
|
|
|
<p>
|
|
int fragments_min;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [fragment_size]Requested size of fragment. This value should be aligned for
|
|
current format (for example to 4 if stereo 16-bit samples are used) or set to
|
|
the <i>fragment_align</i> variable from <i>snd_pcm_playback_info_t</i>
|
|
structure. Its range can be from <i>min_fragment_size</i> to <i>max_fragment_size</i>.
|
|
<dt><b></b></dt>
|
|
<dd> [fragments_min]Minimum filled fragments for wakeup. Driver blocks the application
|
|
(if block mode is selected) until input buffer is filled with less than the
|
|
number of fragments specified with this value.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_status(void *handle, snd_pcm_playback_status_t
|
|
*status)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*status</i> structure. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_playback_status {
|
|
|
|
<p>
|
|
unsigned int rate;
|
|
|
|
<p>
|
|
int fragments;
|
|
|
|
<p>
|
|
int fragment_size;
|
|
|
|
<p>
|
|
int count;
|
|
|
|
<p>
|
|
int queue;
|
|
|
|
<p>
|
|
int underrun;
|
|
|
|
<p>
|
|
struct timeval time;
|
|
|
|
<p>
|
|
struct timeval stime;
|
|
|
|
<p>
|
|
int scount;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [rate]Real playback rate. This value reflects hardware limitations.
|
|
<dt><b></b></dt>
|
|
<dd> [fragments]Currently allocated fragments by the driver for playback direction.
|
|
<dt><b></b></dt>
|
|
<dd> [fragment_size]Current fragment size used by driver for the playback direction.
|
|
<dt><b></b></dt>
|
|
<dd> [count]Count of bytes writable without blocking.
|
|
<dt><b></b></dt>
|
|
<dd> [queue]Count of bytes in queue. Note: <i>(fragments*fragment_size) -
|
|
queue</i> should not be equal to <i>count</i>.
|
|
<dt><b></b></dt>
|
|
<dd> [underrun]This value tells the application the number of underruns since the
|
|
last call to <i>snd_pcm_playback_status</i><em>()</em>.
|
|
<dt><b></b></dt>
|
|
<dd> [time]Estimated time when the next written sample will actually be played (time
|
|
is always in the future). The estimate is calculated with: current time + sample
|
|
queue <em></em>converted to time (number of samples waiting for write to device,
|
|
i.e., the same as the <em>queue</em> member above). This value should be used
|
|
for time synchronization. Returned value is in the same format as returned from
|
|
the standard C function <em>gettimeofday</em>(&<em>time</em>, <em>NULL</em>). This
|
|
variable contains valid information only if playback time mode is enabled (see
|
|
<i>snd_pcm_playback_time()</i> function).
|
|
<dt><b></b></dt>
|
|
<dd> [stime]Time when playback was started. This variable contains valid information
|
|
only if playback time mode is enabled (see <i>snd_pcm_playback_time()</i>
|
|
function).
|
|
<dt><b></b></dt>
|
|
<dd> [scount]Number of bytes processed (actually played) from playback start. This
|
|
number is not necessarily the same as byte count written by application.
|
|
</DL>
|
|
<p>
|
|
<center><img src="pcmbuf.gif">
|
|
<p>
|
|
</center> The figure above shows an example situation in the audio playback buffer in
|
|
the ALSA driver. The driver splits the audio buffer into 16 <em>fragments</em>,
|
|
each being <em>fragment_size</em> bytes long. Fragments 0 and 12-15 are filled
|
|
with samples. Fragment 1 is filled partly (about 75%). Driver is playing and
|
|
current playback position is in fragment 12 (about 35%). As you can seefree space (structure member <i>count</i>) is counted without including the
|
|
fragment which is being played.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_status(void *handle, snd_pcm_record_status_t *status)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*status</i> structure. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_record_status {
|
|
|
|
<p>
|
|
unsigned int rate;
|
|
|
|
<p>
|
|
int fragments;
|
|
|
|
<p>
|
|
int fragment_size;
|
|
|
|
<p>
|
|
int count;
|
|
|
|
<p>
|
|
int free;
|
|
|
|
<p>
|
|
int overrun;
|
|
|
|
<p>
|
|
struct timeval time;
|
|
|
|
<p>
|
|
struct timeval stime;
|
|
|
|
<p>
|
|
int scount;
|
|
|
|
<p>
|
|
int overrange;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [rate]Real record rate. This value reflects hardware limitations.
|
|
<dt><b></b></dt>
|
|
<dd> [fragments]Currently allocated fragments by driver for the record direction.
|
|
<dt><b></b></dt>
|
|
<dd> [fragment_size]Current fragment size used by driver for the record direction.
|
|
<dt><b></b></dt>
|
|
<dd> [count]Count of bytes readable without blocking.
|
|
<dt><b></b></dt>
|
|
<dd> [free]Count of bytes in buffer still free. Note: <i>(fragments*fragment_size)
|
|
- free</i> should not be equal to <i>count</i>.
|
|
<dt><b></b></dt>
|
|
<dd> [overrun]This value tells application the count of overruns since the last call
|
|
to <i>snd_pcm_record_status</i>.
|
|
<dt><b></b></dt>
|
|
<dd> [time]Returns a timestamp for the next sample to be read from the record ring
|
|
buffer (time is always in the past). The timestamp is calculated with: current
|
|
time - sample queue converted to time (waiting for application read() + current
|
|
position in fragment is the same as record count + current position in fragment).
|
|
This value should be used for time synchronization. Returned value is in the
|
|
same format as returned by the standard C function gettimeofday(&time, NULL).
|
|
This variable contains right valid information only if record time mode is enabled
|
|
(see <i>snd_pcm_record_time()</i> function).
|
|
<dt><b></b></dt>
|
|
<dd> [stime]Time when record was started. This variable contains valid information
|
|
only if record time mode is enabled (see <i>snd_pcm_record_time</i> function).
|
|
<dt><b></b></dt>
|
|
<dd> [scount]Number of bytes processed (actually recorded) from record start (stime).
|
|
This number is not necessarily the same as the byte count read by application.
|
|
<dt><b></b></dt>
|
|
<dd> [overrange]ADC overrange count. This value is used only when <i>SND_PCM_RINFO_OVERRANGE</i>
|
|
bit in <i>struct snd_pcm_record_info_t->flags</i> is set (if hardware
|
|
supports this feature).
|
|
</DL>
|
|
<p>
|
|
<center><img src="pcmbuf1.gif">
|
|
<p>
|
|
</center> The figure above shows an example situation in the audio record buffer in the
|
|
ALSA driver. The driver splits the audio buffer into 16 <em>fragments</em>, each
|
|
being <em>fragment_size</em> bytes in length. Fragments 0 and 12-15 are filled
|
|
with samples. Fragment 1 is partly filled (about 75%) and at the end of the
|
|
filled area is the active record position. Data which is ready for the application
|
|
begins in fragment 12 (about 35%). As you can see free space (structure
|
|
member <i>free</i>) is counted without including the fragment which is partly
|
|
filled with samples and the application reads data from this fragment.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_drain_playback(void *handle)</H4>
|
|
|
|
<p>
|
|
This function stops and drains (destroys) the playback buffers immediately.
|
|
Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_flush_playback(void *handle)</H4>
|
|
|
|
<p>
|
|
This function flushes the playback buffers. It blocks the program while the
|
|
all the waiting samples in kernel playback buffers are processed. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_flush_record(void *handle)</H4>
|
|
|
|
<p>
|
|
This function flushes (destroys) record buffers. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_pause(void *handle int enable)</H4>
|
|
|
|
<p>
|
|
This function pauses playback if <i>enable</i> is non-zero. To restore playing
|
|
mode call this function with <i>enable</i> equal to zero. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_playback_time(void *handle, int enable)</H4>
|
|
|
|
<p>
|
|
This function enables or disables time mode for the playback direction. Time
|
|
mode is useful in synchronizing an application with other events. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_record_time(void *handle, int enable)</H4>
|
|
|
|
<p>
|
|
This function enables or disables time mode for record direction. Time mode
|
|
is useful in synchronizing an application with other events. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>ssize_t snd_pcm_write(void *handle, const void *buffer, size_t size)</H4>
|
|
|
|
<p>
|
|
Writes samples to the device which must be in the proper format specified by
|
|
the <i>snd_pcm_playback_format</i> function. Function returns zero or positive
|
|
value if playback was successful (value represents count of bytes which were
|
|
successfully written to device) or an error value if an error occurred. Function
|
|
will suspend process if block mode is active.
|
|
|
|
<p>
|
|
|
|
<H4>ssize_t snd_pcm_read(void *handle, void *buffer, size_t size)</H4>
|
|
|
|
<p>
|
|
Function reads samples from driver. Samples are in format specified by <i>snd_pcm_record_format</i>
|
|
function. Function returns zero or positive value if record was success (value
|
|
represents count of bytes which was successfully read from device) or negative
|
|
error value if error occurred. Function will suspend process if block mode is
|
|
active.
|
|
|
|
<p>
|
|
<H4><A NAME="tth_sEc5.1.1">
|
|
5.1.1</A> Example</H4>
|
|
|
|
<p>
|
|
The following example shows how to play the first 512kB from the /tmp/test.au
|
|
file with sound card #0 and PCM device #0:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
int card = 0, device = 0, err, fd, count, size, idx;
|
|
|
|
<p>
|
|
void *handle;
|
|
|
|
<p>
|
|
snd_pcm_format_t format;
|
|
|
|
<p>
|
|
char *buffer;
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
buffer = (char *)malloc(512 * 1024);
|
|
|
|
<p>
|
|
if (!buffer) return;
|
|
|
|
<p>
|
|
if ((err = snd_pcm_open(&handle, card, device,
|
|
|
|
<p>
|
|
SND_PCM_OPEN_PLAYBACK)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "open failed: %s\n", snd_strerror( err ));
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
bzero(&format sizeof(format));
|
|
|
|
<p>
|
|
format.format = SND_PCM_SFMT_MU_LAW;
|
|
|
|
<p>
|
|
format.rate = 8000;
|
|
|
|
<p>
|
|
format.channels = 1;
|
|
|
|
<p>
|
|
if ((err = snd_pcm_playback_format(handle, &format)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "format setup failed: %s\n",
|
|
|
|
<p>
|
|
snd_strerror( err ));
|
|
|
|
<p>
|
|
snd_pcm_close( handle );
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
fd = open("/tmp/test.au", O_RDONLY);
|
|
|
|
<p>
|
|
if (fd < 0) {
|
|
|
|
<p>
|
|
perror("open file");
|
|
|
|
<p>
|
|
snd_pcm_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
idx = 0;
|
|
|
|
<p>
|
|
count = read(fd, buffer, 512 * 1024);
|
|
|
|
<p>
|
|
if (count <= 0) {
|
|
|
|
<p>
|
|
perror("read from file");
|
|
|
|
<p>
|
|
snd_pcm_close( handle );
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
close( fd );
|
|
|
|
<p>
|
|
if (!memcmp(buffer, ".snd", 4)) {
|
|
|
|
<p>
|
|
idx = (buffer[4]<<24)|(buffer[5]<<16)|
|
|
|
|
<p>
|
|
(buffer[6]<<8)|(buffer[7]);
|
|
|
|
<p>
|
|
if (idx > 128) idx = 128;
|
|
|
|
<p>
|
|
if (idx > count) idx = count;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
size = snd_pcm_write(handle, &buffer[ idx ], count - idx);
|
|
|
|
<p>
|
|
printf("Bytes written %i from %i...\n", size, count - idx);
|
|
|
|
<p>
|
|
snd_pcm_close(handle);
|
|
|
|
<p>
|
|
free(buffer);
|
|
</DL>
|
|
<p>
|
|
<H3><A NAME="tth_sEc5.2">
|
|
5.2</A> PCM Loopback Interface</H3>
|
|
|
|
<p>
|
|
This interface is designed to pass data currently being played or recorded from
|
|
one application to another application for other processing like a graphical
|
|
equalizer sample recorder etc... The programmer should be aware that each
|
|
loopback connection eats CPU time (for data copying from the process which is
|
|
doing the playback or record).
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_loopback_open(void **handle, int card, int device, int mode)</H4>
|
|
|
|
<p>
|
|
Creates a new handle and opens a connection to the kernel sound audio loopback
|
|
interface for sound card number <i>card</i> (0-N) and audio device number
|
|
<i>device</i>. Function also checks if protocol is compatible to prevent use
|
|
of old programs with a new kernel API. Function returns zero if successful otherwise
|
|
it returns an error code. Error code -EBUSY is returned when another process
|
|
owns the selected direction.
|
|
|
|
<p>
|
|
The following modes should be used for the <i>mode</i> argument:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_LB_OPEN_PLAYBACK 0
|
|
|
|
<p>
|
|
#define SND_PCM_LB_OPEN_RECORD 1
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_loopback_close(void *handle)</H4>
|
|
|
|
<p>
|
|
Frees all resources allocated with audio handle and closes the connection to
|
|
the kernel sound audio interface. Function returns zero if successful, otherwise
|
|
it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_loopback_file_descriptor(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns the file descriptor of the connection to the kernel sound audio interface.
|
|
Function returns an error code if an error was encountered.
|
|
|
|
<p>
|
|
The file descriptor should be used for the <i>select(2)</i> synchronous multiplexer
|
|
function for setting the read direction. Application should call <i>snd_pcm_loopback_read()</i>
|
|
function if data is waiting to be read.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_loopback_block_mode(void *handle, int enable) </H4>
|
|
|
|
<p>
|
|
Sets up block (default) or non-block mode for a handle. Block mode suspends
|
|
execution of a program when <i>snd_pcm_loopback_read()</i> is called for
|
|
the time until some data arrives for file descriptor. In non-block mode, programs
|
|
aren't suspended and the above function returns immediately with the count of
|
|
bytes which were read by the driver. When used in this way, don't try to use
|
|
the entire buffer after the call, but instead process the number of bytes returned,
|
|
and call the function again.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_pcm_loopback_stream_mode(void *handle, int mode)</H4>
|
|
|
|
<p>
|
|
Sets up stream mode which should be one of these values:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_LB_STREAM_MODE_RAW 0
|
|
|
|
<p>
|
|
#define SND_PCM_LB_STREAM_MODE_PACKET 1
|
|
</DL>
|
|
<p>
|
|
Mode raw (default mode) means that the stream contains only PCM samples. Packet
|
|
mode is more complicated. The stream contains a header at the begining of the
|
|
packet. Information like data type and data size is contain in this header.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_PCM_LB_TYPE_DATA 0 <i>/* sample data */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_LB_TYPE_FORMAT 1 <i>/* PCM format */</i>
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_loopback_header {
|
|
|
|
<p>
|
|
unsigned int size; <i>/* block size */</i>
|
|
|
|
<p>
|
|
unsigned int type; <i>/* block type (SND_PCM_LB_TYPE_*) */</i>
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_pcm_loopback_format(void *handle, snd_pcm_format_t *format) </H4>
|
|
|
|
<p>
|
|
Get current format for PCM stream.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_pcm_format {
|
|
|
|
<p>
|
|
unsigned int format; <i>/* SND_PCM_SFMT_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int rate; <i>/* rate in Hz */</i>
|
|
|
|
<p>
|
|
unsigned int channels; <i>/* number of channels (voices) */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>ssize_t snd_pcm_loopback_read(void *handle, void *buffer, size_t size)</H4>
|
|
|
|
<p>
|
|
This function reads samples or loopback packets from the stream. Data depends
|
|
on stream mode which should be set with <i>snd_pcm_loopback_stream_mode()</i>
|
|
function. Function returns zero or positive value if record was success (value
|
|
represents count of bytes which were successfully read from device) or negative
|
|
error value if error occurred. Function will suspend process if block mode is
|
|
active.
|
|
|
|
<p>
|
|
<H2><A NAME="tth_sEc6">
|
|
6</A> RawMidi Interface</H2>
|
|
|
|
<p>
|
|
RawMidi Interface is designed to write or read raw (unchanged) MIDI data over
|
|
the MIDI line. MIDI stands Musical Instrument Digital Interface and more informations
|
|
about this standard can be found at <b>http://www.midi.org</b>.
|
|
|
|
<p>
|
|
<H3><A NAME="tth_sEc6.1">
|
|
6.1</A> Low Level Layer</H3>
|
|
|
|
<p>
|
|
RawMidi devices are opened exclusively for a selected direction. While more
|
|
than one process may not open a given MIDI device in the same direction simultaniously,
|
|
seperate processes may open a single MIDI device in different directions (i.e.
|
|
process one opens a MIDI device in playback direction and process two opens
|
|
the same device in record direction). Audio devices (with MIDI ports) return
|
|
EBUSY error to applications when other applications have already opened the
|
|
requested direction.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_open(void **handle, int card, int device, int mode)</H4>
|
|
|
|
<p>
|
|
Creates a new handle and opens a connection to the kernel sound audio interface
|
|
for sound card number <i>card</i> (0-N) and rawmidi device number <i>device</i>.
|
|
Function also checks if protocol is compatible to prevent use of old programs
|
|
with a new kernel API. Function returns zero if successful, otherwise it returns
|
|
an error code. Error code -EBUSY is returned when another process owns the selected
|
|
direction.
|
|
|
|
<p>
|
|
The following modes should be used for the <i>mode</i> argument:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
#define SND_RAWMIDI_OPEN_OUTPUT (O_WRONLY)
|
|
|
|
<p>
|
|
#define SND_RAWMIDI_OPEN_INPUT (O_RDONLY)
|
|
|
|
<p>
|
|
#define SND_RAWMIDI_OPEN_DUPLEX (O_RDWR)
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_close(void *handle)</H4>
|
|
|
|
<p>
|
|
Frees all resources allocated with audio handle and closes the connection to
|
|
the kernel sound rawmidi interface. Function returns zero if successful, otherwise
|
|
it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_file_descriptor(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns the file descriptor of the connection to the kernel sound audio interface.
|
|
Function returns an error code if an error was encountered.
|
|
|
|
<p>
|
|
The file descriptor should be used for the <i>select(2)</i> synchronous multiplexer
|
|
function for setting the read direction. Application should call <i>snd_rawmidi_read()</i>
|
|
or <i>snd_rawmidi_write()</i> functions if data is waiting to be read or
|
|
a write can be performed. Calling these functions is highly recommended.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_block_mode(void *handle, int enable) </H4>
|
|
|
|
<p>
|
|
Sets up block (default) or non-block mode for a handle. Block mode suspends
|
|
execution of a program when <i>snd_rawmidi_read()</i> or <i>snd_rawmidi_write()</i>
|
|
is called for the time which is needed for the actual output or input over of
|
|
the selected limit. In non-block mode, programs aren't suspended and the above
|
|
functions return immediately with the count of bytes which were read or written
|
|
by the driver. When used in this way, don't try to use the entire buffer after
|
|
the call, but instead process the number of bytes returned, and call the function
|
|
again.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_info(void *handle, snd_pcm_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*info</i> structure with data about the PCM device selected
|
|
by <i>*handle</i>. Function returns zero if successful, otherwise it returns
|
|
an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/*</i> device is capable rawmidi output *<i>/</i>
|
|
|
|
<p>
|
|
#define SND_RAWMIDI_INFO_OUTPUT 0x00000001
|
|
|
|
<p>
|
|
<i>/* device is capable rawmidi input */</i>
|
|
|
|
<p>
|
|
#define SND_RAWMIDI_INFO_INPUT 0x00000002
|
|
|
|
<p>
|
|
<i>/* device is capable duplex mode */</i>
|
|
|
|
<p>
|
|
#define SND_RAWMIDI_INFO_DUPLEX 0x00000004
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_info {
|
|
|
|
<p>
|
|
<i> /* sound card type */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i> /* see SND_RAWMIDI_INFO_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int flags;
|
|
|
|
<p>
|
|
<i> /* ID of this PCM device */</i>
|
|
|
|
<p>
|
|
unsigned char id[32];
|
|
|
|
<p>
|
|
<i> /* name of this device */</i>
|
|
|
|
<p>
|
|
unsigned char name[80];
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[64];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_info(void *handle, snd_rawmidi_output_info_t
|
|
*info)</H4>
|
|
|
|
<p>
|
|
Fills the *info structure with data about rawmidi output. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_output_info {
|
|
|
|
<p>
|
|
<i> /* count of output switches */</i>
|
|
|
|
<p>
|
|
unsigned int switches;
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[64];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_info(void *handle, snd_pcm_record_info_t *info)</H4>
|
|
|
|
<p>
|
|
Fills the *info structure. Returns zero if successful, otherwise it returns
|
|
an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_input_info {
|
|
|
|
<p>
|
|
<i> /* count of output switches */</i>
|
|
|
|
<p>
|
|
unsigned int switches;
|
|
|
|
<p>
|
|
<i> /* reserved for future use */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[64];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of rawmidi output switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any rawmidi output
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_switch_read(void *handle int switchnsnd_rawmidi_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
<i>/* 0 or 1 (enable member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_BOOLEAN 0
|
|
|
|
<p>
|
|
<i>/* 0 to 255 - from low to high (data8[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_BYTE 1
|
|
|
|
<p>
|
|
<i>/* 0 to 65535 - from low to high (data16[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_WORD 2
|
|
|
|
<p>
|
|
<i>/* 0 to 4294967296 ¯ from low to high (data32[0] member of union) */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_DWORD 3
|
|
|
|
<p>
|
|
<i>/* user type - no type control */</i>
|
|
|
|
<p>
|
|
#define SND_PCM_SW_TYPE_USER (~0)
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_switch {
|
|
|
|
<p>
|
|
<i>/* switch index (filled by application) */</i>
|
|
|
|
<p>
|
|
unsigned int switchn;
|
|
|
|
<p>
|
|
<i>/* identification of switch (for driver) */</i>
|
|
|
|
<p>
|
|
unsigned char name[32];
|
|
|
|
<p>
|
|
<i>/* type of switch value ¯ See SND_PCM_SW_TYPE_XXXX */</i>
|
|
|
|
<p>
|
|
unsigned int type;
|
|
|
|
<p>
|
|
<i>/* low range value */</i>
|
|
|
|
<p>
|
|
unsigned int low;
|
|
|
|
<p>
|
|
<i>/* high range value */</i>
|
|
|
|
<p>
|
|
unsigned int high;
|
|
|
|
<p>
|
|
union {
|
|
|
|
<p>
|
|
unsigned int enable; <i>/* 0 = off 1 = on */</i>
|
|
|
|
<p>
|
|
unsigned char data8[32]; <i>/* 8-bit data */</i>
|
|
|
|
<p>
|
|
unsigned short data16[16]; <i>/* 16-bit data */</i>
|
|
|
|
<p>
|
|
unsigned int data32[8]; <i>/* 32-bit data */</i>
|
|
|
|
<p>
|
|
} value;
|
|
|
|
<p>
|
|
<i>/* reserved for future use ¯ must be zero !!! */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[32];
|
|
|
|
<p>
|
|
}
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_switch_write(void *handle int switchnsnd_rawmidi_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_switches(void *handle)</H4>
|
|
|
|
<p>
|
|
Returns count of rawmidi input switches. In this context 'switch' means universal
|
|
control interface between kernel and application which allows various types
|
|
of control. Function returns count if successful, otherwise it returns an error
|
|
code. Return value should be zero if sound card doesn't have any rawmidi input
|
|
switch.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_switch(void *handle, const char *switch_id)</H4>
|
|
|
|
<p>
|
|
Returns index for switch with name <i>switch_id</i>. Function returns switch
|
|
index if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_switch_read(void *handle int switchnsnd_rawmidi_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*data</i> structure with data about switch with index <i>switchn</i>.
|
|
Function returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_switch_write(void *handle int switchnsnd_rawmidi_switch_t *data)</H4>
|
|
|
|
<p>
|
|
Writes the <i>*data</i> structure with data about switch with index <i>switchn</i>
|
|
to kernel. Function returns zero if successful, otherwise it returns an error
|
|
code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_params(void *handle, snd_rawmidi_output_params_t
|
|
*params)</H4>
|
|
|
|
<p>
|
|
Sets various parameters for output direction. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_output_params {
|
|
|
|
<p>
|
|
int size;
|
|
|
|
<p>
|
|
int max;
|
|
|
|
<p>
|
|
int room;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [size]Requested queue size of output buffer in bytes (default setup is 4096
|
|
[i386] or 8192 [alpha] bytes - this is system architecture dependent).
|
|
<dt><b></b></dt>
|
|
<dd> [max]Maximum number of bytes in queue for wakeup. If the current byte count
|
|
of filled portion of output buffer is greater than this value the driver will
|
|
block an application or return immediately if non block mode is active.
|
|
<dt><b></b></dt>
|
|
<dd> [room]Minimum number of bytes writable for wakeup. This value should be in most
|
|
cases 1 which means return back to application if at least one byte is free
|
|
in output buffer.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_params(void *handle, snd_rawmidi_input_params_t
|
|
*params)</H4>
|
|
|
|
<p>
|
|
Function sets various parameters for the recording direction. Function returns
|
|
zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_input_params {
|
|
|
|
<p>
|
|
int size;
|
|
|
|
<p>
|
|
int min;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [size]Requested queue size of input buffer in bytes (default setup is 4096 [i386]
|
|
or 8192 [alpha] bytes - this is system architecture dependent).
|
|
<dt><b></b></dt>
|
|
<dd> [min]Minimum filled bytes in queue for wakeup. Driver blocks the application
|
|
(if block mode is selected) until input buffer is filled with fewer than the
|
|
number of bytes specified with this value.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_output_status(void *handle, snd_rawmidi_output_status_t
|
|
*status)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*status</i> structure. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_output_status {
|
|
|
|
<p>
|
|
int size;
|
|
|
|
<p>
|
|
int count;
|
|
|
|
<p>
|
|
int queue;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [size]Size of currently allocated queue in bytes.
|
|
<dt><b></b></dt>
|
|
<dd> [count]Count of bytes writable without blocking.
|
|
<dt><b></b></dt>
|
|
<dd> [queue]Count of bytes in queue (number of bytes waiting to be output).
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_input_status(void *handle, snd_rawmidi_input_status_t
|
|
*status)</H4>
|
|
|
|
<p>
|
|
Fills the <i>*status</i> structure. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
struct snd_rawmidi_input_status {
|
|
|
|
<p>
|
|
int size;
|
|
|
|
<p>
|
|
int count;
|
|
|
|
<p>
|
|
int free;
|
|
|
|
<p>
|
|
int overrun;
|
|
|
|
<p>
|
|
<i> /* reserved for future use - must be filled with zero */</i>
|
|
|
|
<p>
|
|
unsigned char reserved[16];
|
|
|
|
<p>
|
|
};
|
|
</DL>
|
|
<p>
|
|
|
|
<DL compact><dt><b></b></dt>
|
|
<dd> [size]Size of currently allocated queue in bytes.
|
|
<dt><b></b></dt>
|
|
<dd> [count]Count of bytes readable without blocking.
|
|
<dt><b></b></dt>
|
|
<dd> [free]Count of bytes in queue still free.
|
|
<dt><b></b></dt>
|
|
<dd> [overrun]This value tells the application the count of overruns since the last
|
|
call to <i>snd_rawmidi_input_status</i>.
|
|
</DL>
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_drain_output(void *handle)</H4>
|
|
|
|
<p>
|
|
This function stops and drains (destroys) the output queue immediately. Function
|
|
returns zero if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_flush_output(void *handle)</H4>
|
|
|
|
<p>
|
|
This function flushes the output queue. It blocks the program while the all
|
|
the waiting bytes in kernel output queue are processed. Function returns zero
|
|
if successful, otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>int snd_rawmidi_flush_input(void *handle)</H4>
|
|
|
|
<p>
|
|
This function flushes (destroys) input queue. Function returns zero if successful,
|
|
otherwise it returns an error code.
|
|
|
|
<p>
|
|
|
|
<H4>ssize_t snd_rawmidi_write(void *handle, const void *buffer, size_t
|
|
size)</H4>
|
|
|
|
<p>
|
|
Writes bytes to the output queue. Function returns zero or positive value if
|
|
the write was successful (value represents count of bytes which were successfully
|
|
written to the device) or an error value if error occurred. Function will suspend
|
|
the process if block mode is active.
|
|
|
|
<p>
|
|
|
|
<H4>ssize_t snd_rawmidi_read(void *handle, void *buffer, size_t size)</H4>
|
|
|
|
<p>
|
|
Function reads bytes from input queue. Function returns zero or positive value
|
|
if the read was successful (value represents count of bytes which were successfully
|
|
read from device) or negative error value if error occurred. Function will suspend
|
|
the process if block mode is active.
|
|
|
|
<p>
|
|
<H4><A NAME="tth_sEc6.1.1">
|
|
6.1.1</A> Example</H4>
|
|
|
|
<p>
|
|
The following example shows how to send a control sequence (such as SysEx) to
|
|
a MIDI device. Sound card #0 and rawmidi device #0 are used here:
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
int card = 0, device = 0, err, fd, count, size;
|
|
|
|
<p>
|
|
void *handle;
|
|
|
|
<p>
|
|
snd_pcm_format_t format;
|
|
|
|
<p>
|
|
char *buffer;
|
|
</DL>
|
|
<p>
|
|
|
|
|
|
<p>
|
|
|
|
<DL compact> <dt><b></b></dt>
|
|
<dd>
|
|
buffer = (char *)malloc(64 * 1024);
|
|
|
|
<p>
|
|
if (!buffer) return;
|
|
|
|
<p>
|
|
if ((err = snd_rawmidi_open(&handle, card, device,
|
|
|
|
<p>
|
|
SND_RAWMIDI_OPEN_OUTPUT)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "open failed: %s\n", snd_strerror( err ));
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
if ((err = snd_rawmidi_block_mode(handle 1)) < 0) {
|
|
|
|
<p>
|
|
fprintf(stderr, "block failed: %s\n", snd_strerror( err ));
|
|
|
|
<p>
|
|
snd_rawmidi_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
fd = open("/tmp/test.sysex", O_RDONLY);
|
|
|
|
<p>
|
|
if (fd < 0) {
|
|
|
|
<p>
|
|
perror("open file");
|
|
|
|
<p>
|
|
snd_rawmidi_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
idx = 0;
|
|
|
|
<p>
|
|
count = read(fd, buffer, 64 * 1024);
|
|
|
|
<p>
|
|
if (count <= 0) {
|
|
|
|
<p>
|
|
perror("read from file");
|
|
|
|
<p>
|
|
snd_rawmidi_close(handle);
|
|
|
|
<p>
|
|
return;
|
|
|
|
<p>
|
|
}
|
|
|
|
<p>
|
|
close(fd);
|
|
|
|
<p>
|
|
size = snd_rawmidi_write(handle, &buffer, count);
|
|
|
|
<p>
|
|
printf("Bytes written %i from %i...\n", size, count);
|
|
|
|
<p>
|
|
snd_rawmidi_close(handle);
|
|
|
|
<p>
|
|
free(buffer);
|
|
|
|
<p>
|
|
</DL>
|
|
<p><hr><small>File translated from T<sub><font size="-1">E</font></sub>X by <a href="http://hutchinson.belmont.ma.us/tth/">T<sub><font size="-1">T</font></sub>H</a>, version 1.98.<br>On 19 Jan 1999, 16:22.</small>
|
|
</HTML>
|