Programming and Using Linux Sound - in depth - Chapter 5 ALSA

Chapter 5 ALSA

 

ALSA (last modified v0.9)

  • Resources
  • User space tools
  • Programming ALSA
  • Mixing audio
  • Writing an ALSA device driver
  • Conclusion

 

 

Upto: Table of Contents of full book "Linux Sound"

ALSA

      ALSA is a low-level interface to the sound cards. If you are building your      own sound server system, or writing device drivers, then you would be       interested in ALSA.       It sits at the bottom of most of the current Linux systems so to understand      them you may need to understand aspects of ALSA.      Otherwise, you are probably not interested so should move on.   

Resources

User space tools

alsamixer

alsamixer runs within a terminal window and allows      you to select sound cards and controls interfaces on those cards.      It looks like     

amixer is a command line applications with similar functions.   

      Compared to the general mixer functions described in      the Basic chapter      , the mixer functions are quite limited:     

  •   Setting the playback and capture volumes on output and input channels
  •   Muting or unmuting a card

      The document      Sound configuration on Raspberry Pi with ALSA      by Stephen C Phillips      is applicable      to all other ALSA systems and not just the Raspberry Pi.   

alsactl

      Simple control programs for ALSA configurations.   

speaker-test

      This command allows you to test which outputs go where.       For e.g. 5 channel sound, running     

	
speaker-test -t wav -c 5
	
      

      will produce on my default sound card the text and audio of     

	
speaker-test 1.0.25

Playback device is default
Stream parameters are 48000Hz, S16_LE, 5 channels
WAV file(s)
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 39 to 419430
Period size range from 12 to 139810
Using max buffer size 419428
Periods = 4
was set period_size = 104857
was set buffer_size = 419428
 0 - Front Left
 1 - Front Right
 2 - Rear Left
 3 - Rear Right
 4 - Center
Time per period = 12.948378
	
      

      It will also play the phrases "Front Left" etc to the relevant spekaer.   

aplay/arecord

      Play a file or record to a file. To play the microphone to the speaker,     

	
arecord -r 44100 --buffer-size=128 | aplay --buffer-size=128
	
      

Identifying ALSA cards

      The simplest ways are to run aplay and      arecord with the '-l' option:     

  • arecord -l
    	    
    **** List of CAPTURE Hardware Devices ****
    card 0: PCH [HDA Intel PCH], device 0: STAC92xx Analog [STAC92xx Analog]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    card 2: Pro [SB X-Fi Surround 5.1 Pro], device 0: USB Audio [USB Audio]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    	    
    	  
  • aplay -l
    	    
    **** List of PLAYBACK Hardware Devices ****
    card 0: PCH [HDA Intel PCH], device 0: STAC92xx Analog [STAC92xx Analog]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    card 1: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    card 1: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    card 1: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    card 2: Pro [SB X-Fi Surround 5.1 Pro], device 0: USB Audio [USB Audio]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    card 2: Pro [SB X-Fi Surround 5.1 Pro], device 1: USB Audio [USB Audio #1]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    	    
    	  

Device names

      The cards are often given names such as "hw:0" or "hw:2.2"      in programs such as qjackctl (see the chapter on Jack).      The term "hw" refers to hardware devices. The major number refers to the      card number, the minor number to the device number.      The name of the device is in [...] brackets.   

      Devices may also be known by aliases.      The command aplay -L lists device aliases.      For example, the "hdmi" alias is defined on my system in      the configuration file /etc/asound.conf

	
pcm.hdmi0 {
        type hw
        card 1
        device 3 }

pcm.hdmi1 {
        type hw
        card 1
        device 7 }

pcm.hdmi2 {
        type hw
        card 1
        device 8 }
	
      

      so that "hdmi:0" is really "hw:1,3": card 1, device 3.   

      Other aliases may be defined to cover a range of devices, parameterised by      card and device. For example,      /usr/share/alsa/pcm/surround40.conf defines     

	
pcm.!surround40 {
        @args [ CARD DEV ]
        @args.CARD {
                type string
                default {
                        @func getenv
                        vars [
                                ALSA_SURROUND40_CARD
                                ALSA_PCM_CARD
                                ALSA_CARD
                        ]
                        default {
                                @func refer
                                name defaults.pcm.surround40.card
                        }
                }
        }
        @args.DEV {
                type integer
                default {
                        @func igetenv
                        vars [
                                ALSA_SURROUND40_DEVICE
                        ]
                        default {
                                @func refer
                                name defaults.pcm.surround40.device
                        }
                }
        }
        ...
}
	
      

      defines for example "surround40:CARD=PCH,DEV=0" as an alias for hw:0,0      on my system (PCH is card 0).   

      I don't know an easy programmatic way to go from "card 1, device 3" to "hdmi:0".   

  •   The output from aplay -L on my system is     
    	
    default
        Default
    sysdefault:CARD=PCH
        HDA Intel PCH, STAC92xx Analog
        Default Audio Device
    front:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        Front speakers
    surround40:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        4.0 Surround output to Front and Rear speakers
    surround41:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        4.1 Surround output to Front, Rear and Subwoofer speakers
    surround50:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        5.0 Surround output to Front, Center and Rear speakers
    surround51:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        5.1 Surround output to Front, Center, Rear and Subwoofer speakers
    surround71:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
    hdmi:CARD=NVidia,DEV=0
        HDA NVidia, HDMI 0
        HDMI Audio Output
    hdmi:CARD=NVidia,DEV=1
        HDA NVidia, HDMI 1
        HDMI Audio Output
    hdmi:CARD=NVidia,DEV=2
        HDA NVidia, HDMI 2
        HDMI Audio Output
    sysdefault:CARD=Pro
        SB X-Fi Surround 5.1 Pro, USB Audio
        Default Audio Device
    front:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        Front speakers
    surround40:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        4.0 Surround output to Front and Rear speakers
    surround41:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        4.1 Surround output to Front, Rear and Subwoofer speakers
    surround50:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        5.0 Surround output to Front, Center and Rear speakers
    surround51:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        5.1 Surround output to Front, Center, Rear and Subwoofer speakers
    surround71:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
    iec958:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        IEC958 (S/PDIF) Digital Audio Output
    	
          
  •   The output from arecord -L is  
    	    
    default
        Default
    sysdefault:CARD=PCH
        HDA Intel PCH, STAC92xx Analog
        Default Audio Device
    front:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        Front speakers
    surround40:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        4.0 Surround output to Front and Rear speakers
    surround41:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        4.1 Surround output to Front, Rear and Subwoofer speakers
    surround50:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        5.0 Surround output to Front, Center and Rear speakers
    surround51:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        5.1 Surround output to Front, Center, Rear and Subwoofer speakers
    surround71:CARD=PCH,DEV=0
        HDA Intel PCH, STAC92xx Analog
        7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
    sysdefault:CARD=Pro
        SB X-Fi Surround 5.1 Pro, USB Audio
        Default Audio Device
    front:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        Front speakers
    surround40:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        4.0 Surround output to Front and Rear speakers
    surround41:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        4.1 Surround output to Front, Rear and Subwoofer speakers
    surround50:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        5.0 Surround output to Front, Center and Rear speakers
    surround51:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        5.1 Surround output to Front, Center, Rear and Subwoofer speakers
    surround71:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
    iec958:CARD=Pro,DEV=0
        SB X-Fi Surround 5.1 Pro, USB Audio
        IEC958 (S/PDIF) Digital Audio Output
    	    
    	  

ALSA configuration files

      This tutorial by Volker Schatz explains what is going on in ALSA      configuration files and looks really good:      A close look at ALSA     

      We just note one thing: the default ALSA device is "hw:0". This is      hard-coded into ALSA. But it can be overridden in configuration files.      This is done for example by PulseAudio - see next chapter.   

alsa-info

      This will collect information about your system and save it in a file.      It is a shell script that gives an enormous amount of information.      Here is a heavily elided subset of the information:     

	
upload=true&script=true&cardinfo=
!!################################
!!ALSA Information Script v 0.4.60
!!################################

!!Script ran on: Tue Jun 12 04:50:22 UTC 2012


!!Linux Distribution
!!------------------

Fedora release 16 (Verne) Fedora release 16 (Verne) Fedora release 16 (Verne) Fedora release 16 (Verne)

...

!!ALSA Version
!!------------

Driver version:     1.0.24
Library version:    1.0.25
Utilities version:  1.0.25


!!Loaded ALSA modules
!!-------------------

snd_hda_intel
snd_hda_intel


!!Sound Servers on this system
!!----------------------------

Pulseaudio:
      Installed - Yes (/usr/bin/pulseaudio)
      Running - Yes

Jack:
      Installed - Yes (/usr/bin/jackd)
      Running - No


!!Soundcards recognised by ALSA
!!-----------------------------

 0 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xe6e60000 irq 47
 1 [NVidia         ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xe5080000 irq 17


!!PCI Soundcards installed in the system
!!--------------------------------------

00:1b.0 Audio device: Intel Corporation 6 Series/C200 Series Chipset Family High Definition Audio Controller (rev 04)
01:00.1 Audio device: nVidia Corporation HDMI Audio stub (rev a1)


...

!!HDA-Intel Codec information
!!---------------------------

...

Default PCM:
    rates [0x5e0]: 44100 48000 88200 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM

Node 0x0a [Pin Complex] wcaps 0x400583: Stereo Amp-In
  Control: name="Mic Jack Mode", index=0, device=0
    ControlAmp: chs=0, dir=In, idx=0, ofs=0
  Control: name="Mic Capture Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=0, ofs=0
  Control: name="Mic Jack", index=0, device=0
  Amp-In caps: N/A
  Amp-In vals:  [0x01 0x01]
  Pincap 0x0001173c: IN OUT HP EAPD Detect
    Vref caps: HIZ 50 GRD 80
  EAPD 0x2: EAPD
  Pin Default 0x03a11020: [Jack] Mic at Ext Left
    Conn = 1/8, Color = Black
    DefAssociation = 0x2, Sequence = 0x0
  Pin-ctls: 0x24: IN VREF_80
  Unsolicited: tag=03, enabled=1
  Power: setting=D0, actual=D0
  Connection: 3
     0x13* 0x14 0x1c



!!ALSA configuration files
!!------------------------

!!System wide config file (/etc/asound.conf)

#
# Place your global alsa-lib configuration here...
#

@hooks [
	{
		func load
		files [
			"/etc/alsa/pulse-default.conf"
		]
		errors false
	}
]

pcm.hdmi0 {
        type hw
        card 1
        device 3 }

pcm.hdmi1 {
        type hw
        card 1
        device 7 }

pcm.hdmi2 {
        type hw
        card 1
        device 8 }


!!Aplay/Arecord output
!!------------

APLAY

**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: STAC92xx Analog [STAC92xx Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

ARECORD

**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: STAC92xx Analog [STAC92xx Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

!!Amixer output
!!-------------

!!-------Mixer controls for card 0 [PCH]

Card hw:0 'PCH'/'HDA Intel PCH at 0xe6e60000 irq 47'
  Mixer name	: 'IDT 92HD90BXX'
  Components	: 'HDA:111d76e7,10280494,00100102'
  Controls      : 19
  Simple ctrls  : 10
Simple mixer control 'Master',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined penum
  Playback channels: Mono
  Limits: Playback 0 - 64
  Mono: Playback 62 [97%] [-1.50dB] [on]
Simple mixer control 'Headphone',0
  Capabilities: pvolume pswitch penum
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 64
  Mono:
  Front Left: Playback 64 [100%] [0.00dB] [on]
  Front Right: Playback 64 [100%] [0.00dB] [on]
Simple mixer control 'PCM',0
  Capabilities: pvolume penum
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 255
  Mono:
  Front Left: Playback 254 [100%] [0.20dB]
  Front Right: Playback 254 [100%] [0.20dB]
Simple mixer control 'Front',0
  Capabilities: pvolume pswitch penum
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 64
  Mono:
  Front Left: Playback 64 [100%] [0.00dB] [on]
  Front Right: Playback 64 [100%] [0.00dB] [on]
Simple mixer control 'Mic',0
  Capabilities: cvolume penum
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 3
  Front Left: Capture 1 [33%] [10.00dB]
  Front Right: Capture 1 [33%] [10.00dB]
Simple mixer control 'Mic Jack Mode',0
  Capabilities: enum
  Items: 'Mic In' 'Line In'
  Item0: 'Mic In'
Simple mixer control 'Beep',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined penum
  Playback channels: Mono
  Limits: Playback 0 - 3
  Mono: Playback 1 [33%] [-12.00dB] [on]
Simple mixer control 'Capture',0
  Capabilities: cvolume cswitch penum
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 46
  Front Left: Capture 46 [100%] [30.00dB] [on]
  Front Right: Capture 46 [100%] [30.00dB] [on]
Simple mixer control 'Dock Mic',0
  Capabilities: cvolume penum
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 3
  Front Left: Capture 0 [0%] [0.00dB]
  Front Right: Capture 0 [0%] [0.00dB]
Simple mixer control 'Internal Mic',0
  Capabilities: cvolume penum
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 3
  Front Left: Capture 0 [0%] [0.00dB]
  Front Right: Capture 0 [0%] [0.00dB]

!!-------Mixer controls for card 1 [NVidia]

Card hw:1 'NVidia'/'HDA NVidia at 0xe5080000 irq 17'
  Mixer name	: 'Nvidia GPU 1c HDMI/DP'
  Components	: 'HDA:10de001c,10281494,00100100'
  Controls      : 18
  Simple ctrls  : 3
Simple mixer control 'IEC958',0
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'IEC958',1
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [off]
Simple mixer control 'IEC958',2
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [off]


!!Alsactl output
!!-------------

--startcollapse--
state.PCH {
	control.1 {
		iface MIXER
		name 'Front Playback Volume'
		value.0 64
		value.1 64
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 64'
			dbmin -4800
			dbmax 0
			dbvalue.0 0
			dbvalue.1 0
		}
	}
...
	
      

Programming ALSA

      There are several tutorials, including      A Tutorial on Using the ALSA Audio API            by Paul Davis (who is the lead on Jack).   

      An overview of the API is at      PCM (digital audio) interface      .      The ALSA API is large and complex. It is not clear to me how it all hangs together      or what part to use where. Jeff Tranter      Introduction to Sound Programming with ALSA      states     

The ALSA API can be broken down into the major interfaces it supports:

  •     Control interface: a general-purpose facility for managing registers of     sound cards and querying the available devices.  
  •     PCM interface: the interface for managing digital audio capture and playback.     [...]  it is the one most     commonly used for digital audio applications.  
  •     Raw MIDI interface: supports MIDI (Musical Instrument Digital Interface),     a standard for electronic musical instruments. This API provides access to a     MIDI bus on a sound card. The raw interface works directly with the MIDI events,     and the programmer is responsible for managing the protocol and timing.  
  •     Timer interface: provides access to timing hardware on sound cards used for     synchronizing sound events.  
  •     Sequencer interface: a higher-level interface for MIDI programming and sound     synthesis than the raw MIDI interface. It handles much of the MIDI protocol and timing.  
  •     Mixer interface: controls the devices on sound cards that route signals and control     volume levels. It is built on top of the control interface.  

Hardware device information

      Finding information about hardware cards and devices is a multi-step operation.      The hardware cards first have to be identified. This is done using the      Control interface            functions. The ones used are     

	
snd_card_next
snd_ctl_open
snd_ctl_pcm_next_device
snd_ctl_card_info_get_id
snd_ctl_card_info_get_name
	
      

      Cards are identified by an integer from zero upwards. The next      card number is found using snd_card_next, and the first card      is found using a seed value of -1. The card is then opened using its ALSA      name such as hw:0, hw:1, etc by snd_ctl_open which fills in a      handle value. In turn, this handle is used to fill in card      information using snd_ctl_card_info and fields are extracted      from that using functions such as snd_ctl_card_info_get_name.      In the program that follows, this gives information such as     

	
card 0: PCH [HDA Intel PCH]
	
      

      For further information you need to switch to the PCM functions for the card.      The function linking the control and PCM interfaces is snd_ctl_pcm_info      which fills in a structure of type snd_pcm_info_t with PCM-related      information. Unfortunately, this function is documented neither in the Control      Interface nor the PCM interface sections of the ALSA documentation but is instead in the Files section      under control.c            The structure  snd_pcm_info_t is barely documented in the      PCM Interface      section, and only has  a few fields of interest.      (see here for the structure). These fields are accessed using the PCM functions      snd_pcm_info_get_id and snd_pcm_info_get_name.   

      The main value of the  snd_pcm_info_t structure is that it is the principal      parameter into the functions of the       PCM Stream      .      In particular this allows you to get devices and subdevices and information about them.   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值