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.

Tags:

23 Responses to “Audio output selection under Linux on i.MX6”

  1. ericn November 6, 2012 3:59 pm #

    On more recent versions of gstreamer, the alsasink element expects the device
    to be specified using the plughw keyword.

          ~/$ #  play file 0mi2.wav on sgtl5000
          ~/$ gst-launch filesrc location=/root/mp3/0mi2.wav \
                        ! wavparse ! alsasink device=plughw:0,0
          ~/$ #  play file 0mi2.wav on HDMI
          ~/$ gst-launch filesrc location=/root/mp3/0mi2.wav \
                        ! wavparse ! alsasink device=plughw:1,0
    
    • Louis Koziarz January 29, 2013 1:14 pm #

      Eric,

      Have you noticed strange output on the headphone jack of the 6Q SABRE Lite board when powering up?

      When I have earbuds plugged into this port and power on, there’s a howl that comes off the SGTL5000 until the kernel has a chance to initialize the chip.

      Thanks,
      Louis

  2. Francois May 7, 2013 7:23 am #

    When I look in /proc/asound/cards, on my sabreLite, I see that :

    # cat /proc/asound/cards
     0 [sgtl5000audio  ]:  - sgtl5000-audio
                          sgtl5000-audio
     1 [imxhdmisoc     ]:  - imx-hdmi-soc
                          imx-hdmi-soc
    

    When I try the audiotest on the SGTL5000 it works but It doesn’t work on hdmi, I have this message

    # gst-launch audiotestsrc ! alsasink device='hw:1,0'
    Setting pipeline to PAUSED ...
    ERROR: Pipeline doesn't want to pause.
    ERROR: from element /GstPipeline:pipeline0/GstAlsaSink:alsasink0: Could not open audio device for playback.
    Additional debug info:
    gstalsasink.c(694): gst_alsasink_open (): /GstPipeline:pipeline0/GstAlsaSink:alsasink0:
    Playback open error on device 'hw:1,0': No such file or directory
    Setting pipeline to NULL ...
    Freeing pipeline ...
    

    How can I solve this problem ?

  3. Francois May 7, 2013 11:20 pm #

    It doesn’t work too.
    It works with plughw:0,0, but not with plughw:1,0

    # gst-launch audiotestsrc ! alsasink device=’plughw:1,0′
    Setting pipeline to PAUSED …
    ERROR: Pipeline doesn’t want to pause.
    ERROR: from element /GstPipeline:pipeline0/GstAlsaSink:alsasink0: Could not open audio device for playback.
    Additional debug info:
    gstalsasink.c(694): gst_alsasink_open (): /GstPipeline:pipeline0/GstAlsaSink:alsasink0:
    Playback open error on device ‘plughw:1,0′: No such file or directory
    Setting pipeline to NULL …
    Freeing pipeline …

  4. Vasan December 20, 2013 2:39 am #

    Hi Eric,

    Does the SL have SGTL jack sense detection support (both plugging in and plugging out) available?

    Thanks

    • ericn December 20, 2013 7:18 am #

      Hi Vasan,

      Unfortunately, no. It doesn’t appear that the SGTL supports this, and we don’t have a GPIO connected which allows this.

  5. Viktor January 6, 2014 11:32 am #

    Hi Eric,

    I am trying to plug a high-end DAC into the USB port of the Nitrogen6_Lite. This doesn’t seem to be working. In the /proc/asound/cards I still see only the SGTL5000 device. Is there a way to tell the system that there is another audio device?
    And another related question: what are the caracteristics of the HDMI audio? I dont see the HDMA audio device in the /proc/asound/cards because I don’t have anything plugged it. But if I am to purchase an HDMI audio extractor, will the audio on the HDMI channel be of high quality?
    I am playing lossless sound with 24 bit precision at192kHz sampling rate. The SGTL5000 chip can only reproduce 44.1kHz, so the driver is downsampling. So I want to get the full audio quality from the board. At the moment I see 2 solutions – using external DAC or using HDMI extractor. The HDMI extractor is a cheaper solution and also would probably work, while the DAC is more expensive and might not work in foreseable future (as it’s not working at the present). But in order to use the HDMI I want to be sure that it will send the bit-perfect sound. How can I verify that this would be the case?

    • ericn January 6, 2014 12:33 pm #

      Hi Viktor,

      To use an external (USB) DAC, you’ll need to get the driver and compile the associated module. We limit the number of drivers to the core needed to test the hardware in our default configurations and images.

      Using the HDMI audio channel without video will also likely be a challenge because the clocking for it is driven (derived from) the video clock.

  6. Viktor January 6, 2014 1:14 pm #

    Hi Eric,
    Thank you for the fast response.
    So, in the examples above (in the main text) when you show how to play audio on the HDMI channel, that presumes that there is a video device plugged in and a video signal is being sent to it. In other words, even if I have some device plugged to the HDMI port (e.g. an audio extractor) it will not work unless I am also sending the video there. Presumably that could be just the desktop, but still there has to be some video.
    Please correct me if I am wrong.
    Regarding the driver for USB DAC – do I have to add the driver to the kernel and recompile it, or that could be a driver which get’s installed later? Where to find more information about this?
    Also, is the USB bus on the Nitrogen fast enough to support 192 kHz audio?
    Generally I already have an external DAC driven by a Raspberry Pi and by a Cubie board, but the first one is not fast enought for 192kHz audio and the second can play the audio, but cannot drive the GUI in the same time.
    The Nitrogen board has enough power to play high end audio and present a beautiful GUI in the same time and therefore makes a natural choice for my project. Plus I am already familiar with the device and have made some progress in getting the other components (like touchscreen) to work. I would like to create a product based on the Nitrogen board (I could look into the 4 core board too, if it would do the job).

    • ericn January 6, 2014 1:27 pm #

      Hi Viktor,

      1.) HDMI requirement: The primary requirement is that the HDMI output clock be configured. It doesn’t have to actually display anything (it could be a secondary and blank display), but it will need to negotiate a video mode using EDID, so you’d need an I2C ROM connected to the EDID pins somehow. IOW, it’s a hassle.

      2.) Kernel driver for external DAC: Yes. You’ll need to find a DAC with a driver supported by the kernel (or add one to the kernel sources), then select it using ‘menuconfig’ and re-compile the kernel. The driver itself can be either compiled into the kernel (uImage) or loaded from a .ko file.

      3.) USB Bandwidth: The USB Host and OTG port both support high-speed (480Mbps) mode, so you should have plenty of bandwidth for even 5.1 32-bit 192k audio. This is true of the Solo, Dual-Lite, and of course, Quad-core versions of Nitrogen6X.

  7. Andre February 18, 2014 10:07 pm #

    Hi Eric,
    I have the IMX6 it came with android and by default there is no audio on the HDMI output, and
    nano or vi is not there to edit init.freescale.rc
    I had tried this command
    root@nitrogen6x:/ # setprop ro.HDMI_AUDIO_OUTPUT 0
    root@nitrogen6x:/ # setprop ro.HDMI_AUDIO_OUTPUT 1
    root@nitrogen6x:/ # wl1271: unloaded
    cat /proc/asound/cards
    0 [sgtl5000audio ]: sgtl5000-audio – sgtl5000-audio
    sgtl5000-audio
    1 [imxhdmisoc ]: imx-hdmi-soc – imx-hdmi-soc
    imx-hdmi-soc

    what would you recommend to get audio out of HDMI?

    thanks,

  8. Andre February 18, 2014 10:24 pm #

    the audio works if I play a movie and pause it and type
    setprop sys.hdmi 1
    but after I reboot the board it stops working, so I have to do the same while I play the movie and I pause it

    • ericn February 19, 2014 7:18 am #

      Right. The setprop command isn’t persistent.

      I think that you can change this in build.prop, though as you mentioned, there’s no editor installed.

      We typically use adb pull and adb push.

      Note that you’ll need to remount /system as read-write:

      # mount -o remount,rw /system
      
  9. Mario April 4, 2014 8:38 am #

    Hello,

    I would like to know what are the audio input and output formats supported (I mean natively supported by the DAC). Where can I find this information?

    Thanks!
    Regards,
    Mario

    • ericn April 4, 2014 9:45 am #

      Hi Mario,

      The data sheet for the SGTL5000 is available here.

      The driver sources are in the sound/soc/ tree.

  10. viking.sun@live.com August 5, 2014 1:34 am #

    Dear Ericn,

    I have sabrelite and the os is the tiny Debian which is about 160MB. It basically has no driver for either sound device. The kernel is compiled so that alsa will be a module. However, do I still need to install a driver for sgtl5000?

    You mentioned “the driver sources are in the sound/soc tree”. What does that mean? How do I make use of it? (where is it? /lib/modules/3.15.6-armv7-x5/kernel/sound/soc?)

    Thanks a lot!

    Wei

  11. viking.sun@live.com August 5, 2014 1:54 am #

    root@arm:/lib/modules/3.15.6-armv7-x5/kernel/sound/soc/codecs# ls
    snd-soc-alc5632.ko snd-soc-sgtl5000.ko snd-soc-twl6040.ko
    snd-soc-dmic.ko snd-soc-tlv320aic23-i2c.ko snd-soc-wm8753.ko
    snd-soc-hdmi-codec.ko snd-soc-tlv320aic23.ko snd-soc-wm8903.ko
    snd-soc-max98090.ko snd-soc-tlv320aic3x.ko snd-soc-wm8962.ko
    snd-soc-mc13783.ko snd-soc-tpa6130a2.ko
    snd-soc-rt5640.ko snd-soc-twl4030.ko

    root@arm # modprobe snd-soc-sgtl5000

    Then nothing happens…

    Comments and suggestions, please.

    Wei

    • Laci Tele August 5, 2014 4:23 am #

      Dear Viking,

      What kind of kernel do you use ?
      I assume that you want to try a patched mainstream kernel from somewhere here :
      http://rcn-ee.net/deb/trusty-armhf/
      Those kernels are not supported by Boundary, and those kernels don’t support our cards.(at least not precisely but partially)
      I’m sorry I can’t tell you what could be the problem, because we don’t use those kernels.

      Boundary’s kernels can be found in our github :
      https://github.com/boundarydevices/linux-imx6
      Recommended branches for the public are :
      boundary-imx_3.0.35_4.1.0
      boundary-imx_3.0.35_4.1.0-gpu4.6.9p13
      boundary-imx_3.10.17_1.0.0_ga

      And the procedure, how to built them can be found in this post :
      http://boundarydevices.com/cross-compiling-kernels-2014-edition/

      Try our 3.10.17_1.0.0_ga kernel and your sgtl5000 will work for sure.
      Regards,
      Laci
      PS: Eric is passing his vacation at the moment, in Europe, he can’t answer.

      • viking.sun@live.com August 5, 2014 6:27 pm #

        Dear Laci,

        Thanks a lot!

        I follow the instruction on the following website.
        http://eewiki.net/display/linuxonarm/i.MX6x+SABRE+Lite
        Not sure if it is produced by boundarydevices.

        Basically, I want a very small rootfs which boots from RAM. I can compile/use the kernel you showed me. But can I still the tiny debian filesystem and copy the module folders to /lib folder? What then?

        The filesystems provided by boundarydevices are generally quite large, and is not likely to run on 1G RAM.

        Regards,
        Wei

        • Laci Tele August 8, 2014 3:34 am #

          Dear Wei,

          “Not sure if it is produced by boundarydevices”

          No, this is not Boundary software. This is why I can’t help, I don’t know that system at all.
          Check the filenames, and the bootscript (uEnv.txt file), maybe you missed something.
          When you use zImage you have to start it with bootz command, when you use uImage you have to start it with bootm command.
          Have you tried to ask for help on that page ? Maybe they will help.

          If you are looking for a minimal linux, I can tell you that probably we will release something like that, very soon, because it seems people are looking for it.
          Laci

  12. viking.sun@live.com August 6, 2014 6:34 pm #

    I replace the kernel image, and the system does not boot any more. A bit sad……

    Any hint, please?
    Wei

  13. Kishore October 30, 2014 4:53 am #

    Hi,

    Can someone plese help me in tracking Audo out on IMx6 AI development board.

    Where is the audio out for IMX6 Sabre AI development board and CPU board.

    Thanks

    Regards

    K.K

Leave a Reply