ALSA and devices, the return

Many months have past since I last tryed to snap my app, but it seems that I still cannot retrieve the list of connected devices, as reported by ALSA.

So I’ve made a small test case, available here : alsa-test

Here’s a copy of snap/snapcraft.yaml :

name: alsa-test
base: core18 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: alsa-test
description: |
  A snap to test alsa integration

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
  alsa-test:
    command: alsa-test
    environment:
      ALSA_CONFIG_PATH: /snap/$SNAPCRAFT_PROJECT_NAME/current/usr/share/alsa

parts:
  alsa-test:
    plugin: make
    source: src/
    artifacts: 
      - alsa-test
    build-packages:
      - g++
    after:
      - alsa

  alsa:
    plugin: nil
    source: https://github.com/diddledan/snapcraft-alsa.git
    override-pull: |
      cat > alsa.conf <<EOF
      pcm.!default {
        type pulse
        fallback "sysdefault"
        hint {
          show on
          description "Default ALSA Output (currently PulseAudio Sound Server)"
        }
      }
      ctl.!default {
        type pulse
        fallback "sysdefault"
      }
      EOF
    override-build: |
      install -m644 -D -t $SNAPCRAFT_PART_INSTALL/etc alsa.conf
    build-packages:
      - libasound2-dev
    stage-packages:
      - libasound2
      - libasound2-plugins

Now, if I build and run this directly, it produces the correct output. On my machine :

$ cd src
$ make
g++    -c -o alsa-test.o alsa-test.cpp
g++ -o alsa-test alsa-test.cpp -lasound
$ ./alsa-test
card_name: HDA Intel PCH, card_id: PCH
card_name: HDA NVidia, card_id: NVidia
card_name: USB Device 0x46d:0x805, card_id: U0x46d0x805
card_name: USB AUDIO  CODEC, card_id: CODEC
card_name: Plantronics Headset, card_id: Headset
Found 5 cards
$ cd ..

But when I run it from the snap, I get errors :

$ sudo snap install alsa-test_0.1_amd64.snap --devmode
alsa-test 0.1 installed
$ type alsa-test
alsa-test is /snap/bin/alsa-test
$ alsa-test 
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL hw:0
Can't open card 0: No such file or directory
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL hw:1
Can't open card 1: No such file or directory
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL hw:2
Can't open card 2: No such file or directory
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL hw:3
Can't open card 3: No such file or directory
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL hw:4
Can't open card 4: No such file or directory
Found 0 cards

I don’t know if I’m doing something wrong or if what I want to do is even possible within a snap.

Any help would be appreciated.

Thanks !

As you’ve defined base: core18 you get the extra benefit of the layouts support being enabled. With layouts you can do this to simplify things a bit - known to work with Audacity:

name: alsa-test
base: core18 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: alsa-test
description: |
  A snap to test alsa integration

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
  alsa-test:
    command: alsa-test

layout:
  /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib:
    bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib
  /etc/asound.conf:
    bind-file: $SNAP/etc/alsa.conf
  /usr/share/alsa/alsa.conf:
    bind-file: $SNAP/usr/share/alsa/alsa.conf

parts:
  alsa-test:
    plugin: make
    source: src/
    artifacts: 
      - alsa-test
    build-packages:
      - g++
    after:
      - alsa

  alsa:
    plugin: nil
    source: https://github.com/diddledan/snapcraft-alsa.git
    override-pull: |
      cat > alsa.conf <<EOF
      pcm.!default {
        type pulse
        fallback "sysdefault"
        hint {
          show on
          description "Default ALSA Output (currently PulseAudio Sound Server)"
        }
      }
      ctl.!default {
        type pulse
        fallback "sysdefault"
      }
      EOF
    override-build: |
      install -m644 -D -t $SNAPCRAFT_PART_INSTALL/etc alsa.conf
    build-packages:
      - libasound2-dev
    stage-packages:
      - libasound2
      - libasound2-plugins
1 Like

I think I figured it out for you.

What I did was run alsa-test under strace: snap run --strace alsa-test.

The problem with your snap is that ALSA_CONFIG_PATH needs to point to the alsa.conf file, not to the directory that contains it.

With just that change,

$ alsa-test
card_name: HDA Intel PCH, card_id: PCH
Found 1 cards

Edit: furthermore, if you add the alsa plug to the app, so that it looks like

  alsa-test:
    command: alsa-test
    plugs:
      - alsa
    environment:
      ALSA_CONFIG_PATH: /snap/$SNAPCRAFT_PROJECT_NAME/current/usr/share/alsa/alsa.conf

you can then switch it to confinement: strict, install it, connect the alsa interface (it’s not auto-connected by default; do snap connect alsa-test:alsa), and then it works as well.

1 Like

I wonder if the new extensions feature is the solution of this kind of problem?

Thanks !

I was able to try @chipaca 's first suggestion before archive.ubuntu.com went M.I.A., and it seems to work.

Once the archive is back online - or if I can figure out how to tell multipass to use a mirror - I’ll snapcraft clean and rebuild the whole thing in strict mode, and include @lucyllewy 's overlay suggestion.

I’ll report back with the results.

Ok, thank you all, it’s working perfectly fine now, even in strict mode, using the three modifications that were suggested !

Cheers !

2 Likes