September 5, 2012

Audio output selection under Linux on i.MX6

Our i.MX6 boards (Sabre Lite and Nitrogen6X) are the first boards we’ve produced with completely separate output channels (HDMI and SGTL5000), and we’ve been mostly ignoring the question of how to configure this until now.

Under Ubuntu, the “Sound” control panel applet allows you to choose between the two outputs.

Under Android, there’s a setting in init.freescale.rc that we’ve been setting to force output over the SGTL5000:
    # hdmi audio output
    setprop ro.HDMI_AUDIO_OUTPUT 0
But how and where do you make the decision under Linux? This is a question we’ve mostly ignored, but now have some answers to share.

First of all, if you look in /proc/asound/cards, you’ll see that the SGTL5000 is card number 0 and the HDMI audio channel is card number 1:
root@freescale ~$ cat /proc/asound/cards
 0 [sgtl5000audio  ]: sgtl5000-audio - sgtl5000-audio
                      sgtl5000-audio
 1 [imxhdmisoc     ]: imx-hdmi-soc - imx-hdmi-soc
                      imx-hdmi-soc


If you’re using aplay, you can use the -c flag on some Linux releases:
# to play on the SGTL5000
~$ aplay -c 0 Blackbird.wav
# to play on the HDMI audio channel
~$ aplay -c 1 Blackbird.wav


On other Linux releases (including 12.09-GA), the -c option is the number of channels, and you’ll need to use -D to specify the device like so:
# to play on the SGTL5000
~$ aplay -D hw:0,0 Blackbird.wav
# to play on the HDMI audio channel
~$ aplay -D hw:1,0 Blackbird.wav


If you’re using gstreamer, you can use this card numbering to tell the alsasink element which card to use:
# play on SGTL5000
~$ gst-launch filesrc location=BlackBird2.mp3 ! 
   queue max-size-time=0 ! mfw_mp3decoder ! 
   audioconvert ! 'audio/x-raw-int, channels=2' ! 
   alsasink device='hw:0,0'
# play on HDMI
~$ gst-launch filesrc location=BlackBird2.mp3 ! 
   queue max-size-time=0 ! mfw_mp3decoder ! 
   audioconvert ! 'audio/x-raw-int, channels=2' ! 
   alsasink device='hw:1,0'

Finally, for a poor-man’s surround-sound, you can output to both channels by introducing a tee:
~/$ gst-launch filesrc location=BlackBird2.wav  ! wavparse 
               ! tee name=both 
               ! queue ! autoaudiosink both. 
               ! queue ! audioconvert ! alsasink device="hw:1,0"

There’s a lot more to this story, but we hope this gets you pointed in the right direction.