Ubuntu – How to list/access all the available audio input and output ports/channels of a USB soundcard from a particular PC

alsapython-2.7soundsoundcard

In Windows 7, I used to use pymedia, a python library, to list the available interfaces as well as use them for playing and recording audio. A typical query would look like this:

sound

Now, I'm no longer using Windows 7 as I have migrated to Ubuntu 16.04. So, I used ALSA commands to see the available audio interfaces. The following is the output of the same:

skrowten_hermit@PC-760:~$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: AD1984A Analog [AD1984A Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 2: AD1984A Alt Analog [AD1984A Alt Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Eight [M-Track Eight], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
skrowten_hermit@PC-760:~$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Intel [HDA Intel], device 0: AD1984A Analog [AD1984A Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 2: AD1984A Alt Analog [AD1984A Alt Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Eight [M-Track Eight], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

As we can see, my external soundcard M-Audio is listed as an ALSA card here, which means it is being detected properly. Now, as I read through ALSA related articles, I learnt about devices and then used -L to view the available devices as follows:

skrowten_hermit@PC-760:~$ aplay -L
default
    Playback/recording through the PulseAudio sound server
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
sysdefault:CARD=Intel
    HDA Intel, AD1984A Analog
    Default Audio Device
front:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Front speakers
surround21:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    4.0 Surround output to Front and Rear speakers
surround41:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
dmix:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Direct sample mixing device
dmix:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Direct sample mixing device
dsnoop:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Direct sample snooping device
dsnoop:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Direct sample snooping device
hw:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Direct hardware device without any conversions
hw:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Direct hardware device without any conversions
plughw:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Hardware device with all software conversions
plughw:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Hardware device with all software conversions
sysdefault:CARD=Eight
    M-Track Eight, USB Audio
    Default Audio Device
front:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Front speakers
surround21:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    4.0 Surround output to Front and Rear speakers
surround41:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    IEC958 (S/PDIF) Digital Audio Output
dmix:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Direct sample mixing device
dsnoop:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Direct sample snooping device
hw:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Direct hardware device without any conversions
plughw:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Hardware device with all software conversions
skrowten_hermit@PC-760:~$ arecord -L
default
    Playback/recording through the PulseAudio sound server
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
sysdefault:CARD=Intel
    HDA Intel, AD1984A Analog
    Default Audio Device
front:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Front speakers
surround21:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    4.0 Surround output to Front and Rear speakers
surround41:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
dmix:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Direct sample mixing device
dmix:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Direct sample mixing device
dsnoop:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Direct sample snooping device
dsnoop:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Direct sample snooping device
hw:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Direct hardware device without any conversions
hw:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Direct hardware device without any conversions
plughw:CARD=Intel,DEV=0
    HDA Intel, AD1984A Analog
    Hardware device with all software conversions
plughw:CARD=Intel,DEV=2
    HDA Intel, AD1984A Alt Analog
    Hardware device with all software conversions
sysdefault:CARD=Eight
    M-Track Eight, USB Audio
    Default Audio Device
front:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Front speakers
surround21:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    4.0 Surround output to Front and Rear speakers
surround41:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    IEC958 (S/PDIF) Digital Audio Output
dmix:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Direct sample mixing device
dsnoop:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Direct sample snooping device
hw:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Direct hardware device without any conversions
plughw:CARD=Eight,DEV=0
    M-Track Eight, USB Audio
    Hardware device with all software conversions

The above is a bit different from what I was expecting (I was hoping to get the channel identifiers, but instead ended up getting parameters like sysdefault, front, surround21, dsnoop, hw etc.). My sound card has Eight I/O pairs. So, I was expecting the channels/port identifiers or something like that.

After a bit more digging into the web, I stumbled upon pyAudio and sounddevice python libraries. The former gave the following output:

skrowten_hermit@PC-760:~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyaudio
>>> p = pyaudio.PyAudio()
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
Cannot open PortAudio client
JackShmReadWritePtr1::~JackShmReadWritePtr1 - Init not done for 4294967295, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for 4294967295, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for 4294967295, skipping unlock
>>> for i in range(p.get_device_count()):
...     print p.get_device_info_by_index(i).get('name')
...
HDA Intel: AD1984A Analog (hw:0,0)
HDA Intel: AD1984A Alt Analog (hw:0,2)
M-Track Eight: USB Audio (hw:1,0)
sysdefault
pulse
default
>>> import pyaudio
>>> p = pyaudio.PyAudio()
>>> for i in range(p.get_device_count()):
...     print p.get_device_info_by_index(i)
...
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': 0.008707482993197279, 'maxInputChannels': 2L, 'structVersion': 2L, 'hostApi': 0L, 'index': 0, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'HDA Intel: AD1984A Analog (hw:0,0)', 'defaultHighInputLatency': 0.034829931972789115}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': -1.0, 'defaultLowInputLatency': 0.008707482993197279, 'maxInputChannels': 2L, 'structVersion': 2L, 'hostApi': 0L, 'index': 1, 'defaultHighOutputLatency': -1.0, 'maxOutputChannels': 0L, 'name': u'HDA Intel: AD1984A Alt Analog (hw:0,2)', 'defaultHighInputLatency': 0.034829931972789115}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': 0.008707482993197279, 'maxInputChannels': 8L, 'structVersion': 2L, 'hostApi': 0L, 'index': 2, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 8L, 'name': u'M-Track Eight: USB Audio (hw:1,0)', 'defaultHighInputLatency': 0.034829931972789115}
{'defaultSampleRate': 48000.0, 'defaultLowOutputLatency': 0.021333333333333333, 'defaultLowInputLatency': 0.021333333333333333, 'maxInputChannels': 128L, 'structVersion': 2L, 'hostApi': 0L, 'index': 3, 'defaultHighOutputLatency': 0.021333333333333333, 'maxOutputChannels': 128L, 'name': u'sysdefault', 'defaultHighInputLatency': 0.021333333333333333}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 4, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'front', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 5, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'surround40', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 6, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'surround51', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 7, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 2L, 'name': u'surround71', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': 0.008707482993197279, 'maxInputChannels': 32L, 'structVersion': 2L, 'hostApi': 0L, 'index': 8, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 32L, 'name': u'pulse', 'defaultHighInputLatency': 0.034829931972789115}
{'defaultSampleRate': 48000.0, 'defaultLowOutputLatency': 0.021333333333333333, 'defaultLowInputLatency': -1.0, 'maxInputChannels': 0L, 'structVersion': 2L, 'hostApi': 0L, 'index': 9, 'defaultHighOutputLatency': 0.021333333333333333, 'maxOutputChannels': 2L, 'name': u'dmix', 'defaultHighInputLatency': -1.0}
{'defaultSampleRate': 44100.0, 'defaultLowOutputLatency': 0.008707482993197279, 'defaultLowInputLatency': 0.008707482993197279, 'maxInputChannels': 32L, 'structVersion': 2L, 'hostApi': 0L, 'index': 10, 'defaultHighOutputLatency': 0.034829931972789115, 'maxOutputChannels': 32L, 'name': u'default', 'defaultHighInputLatency': 0.034829931972789115}

The above too was not satisfying enough. A closer look at the enumerated output of the device list reveals that, the one corresponding to 'name': u'M-Track Eight: USB Audio (hw:1,0)' does show that the number of input and output channels are 8, but listed as a single device. Then, next up, sounddevice gave me the following output:

skrowten_hermit@PC-760:~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sounddevice as sd
>>> sd.query_devices()
   0 HDA Intel: AD1984A Analog (hw:0,0), ALSA (2 in, 2 out)
   1 HDA Intel: AD1984A Alt Analog (hw:0,2), ALSA (2 in, 0 out)
   2 M-Track Eight: USB Audio (hw:1,0), ALSA (8 in, 8 out)
   3 sysdefault, ALSA (128 in, 128 out)
   4 front, ALSA (0 in, 2 out)
   5 surround40, ALSA (0 in, 2 out)
   6 surround51, ALSA (0 in, 2 out)
   7 surround71, ALSA (0 in, 2 out)
   8 pulse, ALSA (32 in, 32 out)
   9 dmix, ALSA (0 in, 2 out)
* 10 default, ALSA (32 in, 32 out)

Here too, device 2 shows 8 in, 8 out.

What I don't understand is:

  1. When pyaudio and sounddevice can see my soundcard as having 8 pairs of I/O channels, why aren't they listing them as separate devices?
  2. And that ALSA doesn't even see that at all (which is the basic requirement for using ALSA commands aplay or arecord)?
  3. Or even if my understanding that devices correspond to physical analog channels/ports, where I would connect devices, is correct?
  4. Is this a limitation of the driver?

My requirements in a nutshell:

  1. I should be able to play out audio to (any) input port(s) of my M-Audio M-Track Eight soundcard and record as well as play out audio from (any) output port(s) of my M-Audio M-Track Eight soundcard and play.
    M-Audio M-Track Eight description
  2. I should be able to use ALSA commands to play and record as mentioned above.
  3. I should be able to play and record in separate threads.

How can I achieve this? Can I get a clearer picture of ALSA and its role here? Any drivers available which can satisfy my requirements?


UPDATE:

I created the following ~/.asoundrc from the inputs I recieved:

pcm.!default {
    type plug
    slave {
       pcm "hw:1,0"
    }
}

ctl.!default {
    type hw
    card 1
}

pcm_slave.eightchannels {
    pcm "hw:1,0"
    channels 8
    rate 44100
    buffer_size 4096
    period_size 2048
}

pcm.ch12 {
    type asym
    playback.pcm {
        type dshare
        ipc_key 1111
        slave eightchannels
        bindings [ 0 1 ]
    }
    capture.pcm {
        type dsnoop
        ipc_key 1111
        slave eightchannels
        bindings [ 0 1 ]
    }
    hint.description "M-Audio channels 1,2"
}
pcm.ch34 {
    type asym
    playback.pcm {
        type dshare
        ipc_key 2222
        slave eightchannels
        bindings [ 2 3 ]
    }
    capture.pcm {
        type dsnoop
        ipc_key 2222
        slave eightchannels
        bindings [ 2 3 ]
    }
    hint.description "M-Audio channels 3,4"
}

So, with the above configuration, when I try running aplay, the following is what I receive:

skrowten_hermit@PC-760:~$ aplay -D ch12 -c 1 -r 8000 male_8k.wav
Playing WAVE 'male_8k.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
aplay: set_params:1233: Sample format non available
Available formats:
- S32_LE

Assuming it's a mismatch with the format as indicated, I tried passing the format as argument for aplay as below:

skrowten_hermit@PC-760:~$ aplay -D ch12 -c 1 -r 8000 -f S32_LE male_8k.wav
Warning: format is changed to S16_LE
Playing WAVE 'male_8k.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
aplay: set_params:1233: Sample format non available
Available formats:
- S32_LE

Does this error have something to do with the PCM devices or the .wav file being played?

P.S : The .!defaults were added later. Removing them makes no difference!

Best Answer

The four pairs are not listed as separate devices because they are not separate devices. The M-Track Eight is a single device with eight channels.

It would be possible to create a bunch of virtual software devices that emulate four stereo pairs. To do this, add something like this to /etc/asound.conf or your ~/.asoundrc:

pcm_slave.eightchannels {
    pcm "hw:Eight"
    channels 8
    rate 48000
    buffer_size 8192  # make these sizes smaller for lower latency
    period_size 2048
}

pcm.ch12 {
    type asym
    playback.pcm {
        type dshare
        ipc_key 2222      # some random number, but the same for the same slave
        slave eightchannels
        bindings [ 0 1 ]
    }
    capture.pcm {
        type dsnoop
        ipc_key 2222
        slave eightchannels
        bindings [ 0 1 ]
    }
    hint.description "M-Track channels 1,2"
}
pcm.ch34 {
    type asym
    playback.pcm {
        type dshare
        ipc_key 2222
        slave eightchannels
        bindings [ 2 3 ]
    }
    capture.pcm {
        type dsnoop
        ipc_key 2222
        slave eightchannels
        bindings [ 2 3 ]
    }
    hint.description "M-Track channels 3,4"
}
...
Related Question