본문 바로가기

IT관련/linux

linux sound programming

 

 

 

 

 

 

 

 

Linux Sound Programming

Please see disclaimer on the main page.

This is a bit rough - the better source is probably the official programmer's guide, but then it's not in one file.

Sound Devices

These do not exist on every system, and may not "work" on every system (trying to open them will produce errors etc), if sound is not supported or has not been configured correctly.

Generally, we have device names of the form <device-description>< id-number>. For instance, if there are two sound cards installed there is usually a /dev/dsp0 as well as a /dev/dsp1. There should be a link, /dev/<device-description>, which points to the default device.

  • /dev/midi - ???
  • /dev/sequencer - ???
  • /dev/sndstat - when read, produces human readable information about installed sound drivers
  • /dev/dsp, /dev/dsp1 etc - DSP access
  • /dev/audio, /dev/audio1 etc - takes input in the form of a SUN .au file (u-law) and plays it. Does not support SUN ioctl, but does support mixer ioctl (affects first mixer only).
  • /dev/mixer, /dev/mixer1 etc - mixer.

DSP access

DSP access is obtained through three devices: /dev/dspx, /dev/dspWx and /dev/audiox (replace 'x' with a decimal number). The three are functionally identical (they refer to the same physical device) apart from the fact that they have different default formats (which are only set if supported by the device). Only one can be open (and only once) at any one time:
  • /dev/dsp: 8 bit unsigned, 8kHz
  • /dev/dspW: 16 bit signed little endian, 8kHz
  • /dev/audio: mu-Law, 8kHz

Data is 'reasonably buffered'; reading or writing too quickly will cause blocking (the read/write routine will not return until the operation has been performed). Reading or writing too slowly will cause gaps in the noise. At the moment, (25/4/99) the sound drivers do not support non-blocking IO. Not all sound cards support full duplex operation (they may only be opened for read OR write access, not both at the same time).

The following ioctl calls are supported, as well as the mixer ioctl calls (you do not need to open the mixer seperately). The mixer calls will affect the first mixer only. The values shown here can be found in <linux/soundcard.h>. The third ioctl function argument is always a pointer to an integer which contains the value, or which will recieve the value required.

  • SNDCTL_DSP_SETFMT - set sound format:
    • AFMT_MU_LAW - mu-law;
    • AFMT_A_LAW - a-law format
    • AFMT_IMA_ADPCM - 4:1 compressed format where 16 bit samples are represented in 4 bits. Defined by Interactive Multimedia Assosciation.
    • AFMT_U8 - 8 bit unsigned. Presumably also sets bits/sample to 8.
    • AFMT_S8 - 8 bit signed
    • AFMT_S16_LE - 16 bit signed, low byte before high
    • AFMT_S16_BE - 16 bit signed, high byte before low
    • AFMT_U16_LE - 16 bit unsigned, low byte before high
    • AFMT_U16_BE - 16 bit unsigned, high byte before low
    • AFMT_S16_NE - 16 bit signed, uses current machine endianness
    • AFMT_MPEG - MPEG audio format, currently not supported
    • AFMT_QUERY - This does not change the current format, rather it returns the currently used format (return value from ioctl).
    The argument will be returned with the used format, which will be the selected one unless not supported. Note that changing format may also change the number of channels, and sample rate.
  • SNDCTL_DSP_GETFMTS - get supported sound formats (see SETFMT). Returned value is a bit mask; check by ANDing with AFMT_xxx. Occasionally, formats supported by software conversion will not be reported as being supported (the only way to check is to try and set the format).
  • SNDCTL_DSP_STEREO - set number of channels (ie, mono or stereo). The argument is 0 for mono or 1 for stereo. On return, it will be set to the selected mode (not all cards support both). Changing the number of channels may change the sample rate. Note that SNDCTL_DSP_CHANNELS is an alternative to this call.
  • SNDCTL_DSP_CHANNELS - set the number of channels (ie, mono or stereo). This is identical to SNDCTL_DSP_STEREO except the argument and return is 1 for mono operation and 2 for stereo.
  • SNDCTL_DSP_SPEED - set sample rate (in Hz). The closest possible rate will be selected and returned in the argument.
  • SNDCTL_DSP_SYNC - Waits until the last byte written to the device has been played before returning. Argument is ignored.
  • SNDCTL_DSP_RESET - Stops the device (playback/record) immediately
  • SNDCTL_DSP_POST - Informs driver that there is likely to be a delay before more output occurs. This allows the driver to play a partial buffer.
  • SNDCTL_DSP_GETBLKSIZE - Gets the block size (buffer size) considered optimal by the driver. This may be affected by any change to number of channels/sample rate. It is not necessarily the fragment size currently being used (see SNDCTL_DSP_GETISPACE and GETOSPACE).
  • SNDCTL_DSP_GETISPACE / SNDCTL_DSP_GETOSPACE - these calls retrieve information about buffering currently being used for input and output respectively. The argument to ioctl() should be a pointer to type 'audio_buf_info' rather than a pointer to int for these calls. 'audio_buf_info' has the following fields:
    • int fragments; - "number of full fragments that can be read/written without blocking".
    • int fragstotal; - total number of buffer fragments
    • int fragsize; - size of a fragment in bytes
    • int bytes; - number of bytes that can be read/written immediately without blocking
  • SNDCTL_DSP_SETFRAGMENT - Sets the fragment size and maximum number of fragments to be used. The lower 16 bits of the argument controls the fragment size (which will become 2 to the power of the given value) and the upper 16 bits give the maximum number of fragments to be used. Both parts should be treated as signed. This call will fail after any write or read operation, or any ioctl call which retrieves buffering information. It can only be called once per time the device is opened (it must be closed and re-opened before this call can be made again).
  • SOUND_PCM_WRITE_BITS/...READ_BITS - set/get number of bits per sample (8 or 16). Not all cards support both.
  • SOUND_PCM_WRITE_CHANNELS/...READ_CHANNELS - number of channels, 1 = mono, 2 = stereo. Not all cards support stereo. Stereo: left sample written first followed immediately by right sample.
  • SOUND_PCM_WRITE_RATE/...READ_RATE - sample (per channel) rate in Hz. Sound card driver will choose closest possible rate to that given.
  • SOUND_PCM_SYNC - block until present transfers finished
  • SNDCTL_DSP_GETBLKSIZE returns the block size used by the driver for sound data transfers
  • SNDCTL_DSP_GETCAPS - get DSP capabilities as bitmask.
    • DSP_CAP_DUPLEX: duplex card (simultaneous record/play supported)
  • SOUND_PCM_RESET: stops current recording/playback
  • SOUND_PCM_SUBDIVIDE: takes a value 1,2 or 4 and divides the default buffer size by that value to obtain a new buffer size to use.
  • SNDCTL_DSP_SETFRAGMENT: ? see 'experimental.txt'?

Mixer programming

Mixer programming is performed throught the /dev/mixer (/dev/mixer0 etc) device. This device does not support read/write operations, only ioctl calls. As with the DSP, the ioctl third parameter is a pointer to an integer.

If no mixer is supported, the device entry /dev/mixer will still exist, however any ioctl calls will return ENXIO.

  • SOUND_MIXER_READ_DEVMASK returns bitmask showing which devices (channels) are are supported by the mixer.
  • SOUND_MIXER_READ_RECMASK shows which devices can be used as recording sources. The mixer channel symbols below correspond to suitable bitmasks.
  • SOUND_MIXER_READ_RECSRC returns a bitmask showing which devices are currently selected as recording sources.
  • SOUND_MIXER_READ_STEREODEVS shows which devices support stereo sound
  • SOUND_MIXER_READ_CAPS: get capabilities. Bits correspond to:
    • SOUND_CAP_EXCL_INPUT: if set, only one recording source allowed, otherwise multiple rec sources may be used
  • SOUND_MIXER_WRITE_RECSRC: set recording source(s). Not all support more than one source: See SOUND_MIXER_READ_CAPS
The following mixer channels (devices) may exist:
  • SOUND_MIXER_VOLUME (main volume control; not always supported.)
  • SOUND_MIXER_BASS
  • SOUND_MIXER_TREBLE
  • SOUND_MIXER_SYNTH
  • SOUND_MIXER_PCM (controls digital output from dsp, dspW and audio)
  • SOUND_MIXER_SPEAKER (PC speaker)
  • SOUND_MIXER_LINE (line input)
  • SOUND_MIXER_MIC (mic input)
  • SOUND_MIXER_CD (cd audio input)
  • SOUND_MIXER_IMIX (Affects playback volume of "selected recording sources" only when recording is taking place)
  • SOUND_MIXER_ALTPCM (secondary digital output control, such as the SoundBlaster emulation of some sound cards)
  • SOUND_MIXER_RECLEV (master recording level)
  • SOUND_MIXER_LINE1
  • SOUND_MIXER_LINE2 card specific inputs
  • SOUND_MIXER_LINE3

Each device has a volume setting, which can be read/written using the following macros. The setting ranges from 0 to 100 and is scaled by the driver. In the case of stereo devices, the least significant byte is the volume for the left channel, the next byte is the volume for the right channel:

  • macro MIXER_READ() returns IOCTL command to read setting
  • macro MIXER_WRITE(<--->) returns IOCTL command to write setting [eg for use: ioctl(fd, MIXER_READ(SOUND_MIXER_VOLUME), &var)]
const char *SOUND_DEVICE_LABELS[] is an array of descriptions of each mixer channel (device). const char *SOUND_DEVICE_NAMES[] is an array of single word names suitable for command line switches etc. The number of devices can be found from SOUND_MIXER_NRDEVICES.