I have configured camillaDSP to start automatically as a service on my rPi4 (bookworm) but it always fails to open the HDMI playback device on startup.
Looking at the logs this seems to be because the ALSA hdmi playback device it is not (yet) available. If I restart the service manually after the boot it then always succeeds.
Unsuccessful service start at boot:
Is there a way to make the camillaDSP service start conditional on the ALSA HDMI device enumeration (preferred) or just to add a delay by trial and error (horrible)?
At the moment my /lib/systemd/system/camilladsp.service just waits for syslog:
Update
Funny how describing the problem focuses the mind... Immediately after posting I found out how to just delay any service start... and it all works as expected and hoped for, but I would still much prefer to avoid ad-hoc delays by using a suitable "After" rule!
If no better (e.g. "After") solution turns up, then here is how to fix it with a delay in the /lib/systemd/system/camilladsp.service:
Looking at the logs this seems to be because the ALSA hdmi playback device it is not (yet) available. If I restart the service manually after the boot it then always succeeds.
Unsuccessful service start at boot:
Successful manual service restart a short time later:2024-01-11 11:40:26.391688 DEBUG [src/alsadevice.rs:334] Available Playback devices: [("hw:Loopback,0,0", "Loopback, ... <<< no mention of vc4hdmi0 !!!
2024-01-11 11:40:26.402195 ERROR [src/bin.rs:286] Playback error: ALSA function 'snd_pcm_open' failed with error 'EINVAL: Invalid argument'
2024-01-11 11:45:35.986926 DEBUG [src/alsadevice.rs:334] Available Playback devices: ... [("hw:vc4hdmi0,0,0", ... <<< vc4hdmi0 available
2024-01-11 11:45:35.991679 DEBUG [src/alsadevice.rs:352] Playback: supported channels, min: 2, max: 8, list: [2, 3, 4, 5, 6, 7, 8]
...
2024-01-11 11:45:35.992523 DEBUG [src/alsadevice.rs:392] Playback device "hdmi:vc4hdmi0,0" successfully opened
Is there a way to make the camillaDSP service start conditional on the ALSA HDMI device enumeration (preferred) or just to add a delay by trial and error (horrible)?
At the moment my /lib/systemd/system/camilladsp.service just waits for syslog:
[Unit]
After=syslog.target
Update
Funny how describing the problem focuses the mind... Immediately after posting I found out how to just delay any service start... and it all works as expected and hoped for, but I would still much prefer to avoid ad-hoc delays by using a suitable "After" rule!
If no better (e.g. "After") solution turns up, then here is how to fix it with a delay in the /lib/systemd/system/camilladsp.service:
[Service]
ExecStartPre=/bin/sleep 5
Last edited:
Typically a udev rule is used for these tasks. Look at https://github.com/HEnquist/camilla...v-rule-to-start-service-when-dac-is-connected - just instead of the USB ID rule for a USB device use a rule for device name - similar to https://askubuntu.com/questions/354612/how-to-run-a-script-when-i-connect-a-device
I assume the os device to target is "/dev/dri/card0"
I'll give this all a try but...
I'll give this all a try but...
- Does this risk starting before "syslog"? (I assume not due to the U in udev)
- Does this guarantee to fix the problem? Is the device visible in ALSA environment as soon as the os device appears, or at least before udev triggers?
Alsa devices are in /dev/snd/cardXX.I assume the os device to target is "/dev/dri/card0"
I am afraid I do not understand, why?Does this risk starting before "syslog"? (I assume not due to the U in udev)
udev is a user-space daemon (today part of systemd) which manages the dev virtual filesystem in /dev, based on uevent messages sent from the kernel and on its rules. See e.g. https://en.wikipedia.org/wiki/Udev + lots of info online.Does this guarantee to fix the problem? Is the device visible in ALSA environment as soon as the os device appears, or at least before udev triggers?
A device is "visible in ALSA environment" when its /dev/snd/... device file is created. "ALSA environment" is just a library alsa-lib (libasound2...), linked to executables using alsa (clients). Clients must enumerate/check for the available devices (via alsalib, of course). If a client wants to know a new device was created (e.g. pulseaudio), it must listen to udev events - https://stackoverflow.com/questions/36975381/alsa-callback-when-new-card-device-is-added .
Using udev rules for actions on newly created/removed/anything devices is the standard method.
Thanks. This is the key to my puzzle: That alsa devices are indeed represented in the file-system! (I couldn't "find" any devices matching the alsa names like "hdmi" "Loopback" etc. so I assumed they were some sort of user-space objects interfaced via the alsa library.)Alsa devices are in /dev/snd/cardXX.
My next puzzle... Which snd devices correspond to the alsa "hdmi0/1" devices?
$ ls -l /dev/snd
total 0
drwxr-xr-x 2 root root 120 Jan 12 00:52 by-path
crw-rw---- 1 root audio 116, 6 Jan 12 00:52 controlC0
crw-rw---- 1 root audio 116, 8 Jan 12 00:52 controlC1
crw-rw---- 1 root audio 116, 10 Jan 12 00:52 controlC2
crw-rw---- 1 root audio 116, 12 Jan 12 00:52 controlC3
crw-rw---- 1 root audio 116, 3 Jan 12 00:52 pcmC0D0c
crw-rw---- 1 root audio 116, 2 Jan 12 00:52 pcmC0D0p
crw-rw---- 1 root audio 116, 5 Jan 12 00:52 pcmC0D1c
crw-rw---- 1 root audio 116, 4 Jan 12 00:52 pcmC0D1p
crw-rw---- 1 root audio 116, 7 Jan 12 00:52 pcmC1D0p
crw-rw---- 1 root audio 116, 9 Jan 12 00:52 pcmC2D0p
crw-rw---- 1 root audio 116, 11 Jan 12 00:52 pcmC3D0p
crw-rw---- 1 root audio 116, 1 Jan 12 00:52 seq
crw-rw---- 1 root audio 116, 33 Jan 12 00:52 timer
See 'aplay -l'My next puzzle... Which snd devices correspond to the alsa "hdmi0/1" devices?
hint - p = playback, c = capture
I have configured camillaDSP to start automatically as a service on my rPi4 (bookworm) but it always fails to open the HDMI playback device on startup.
[..]
[Service]
ExecStartPre=/bin/sleep 5
Hi @oomzay, thank you for your message. I had the same issue, camilladsp was systematically dead after boot, and I had to stop / start it once with systemctl first after each boot. Your solution initially solved my problem (ExecStartPre=/bin/sleep 5 in /lib/systemd/system/camilladsp.service). Thank you to have posted it.
I have dug into the hints proposed by @phofman's with the udev rule, which is even better, but was less obvious.
Here the solution which seems to solve my issue - up to now. I am far from an expert and have made very few tests.
1. "aplay -l" gives me "card 1: PCH [HDA Intel PCH], device 3: HDMI 0 [BenQ GW2780]" (this is for me only obviously)
2. "ls -l /dev/snd" gives me "pcmC1D3p" (above Card 1, Device 3, p for Playback)
3. I've created the file /etc/systemd/system/hdmi-audio.path with the content as follows
[Path]
PathExists=/dev/snd/pcmC1D3p
Unit=camilladsp.service
[Install]
WantedBy=multi-user.target
4. I have activated the dependency mechanism by:
sudo systemctl enable hdmi-audio.path
sudo systemctl start hdmi-audio.path
5. And I have removed @oomzay's "ExecStartPre=/bin/sleep 5" from camilladsp.service
camilladsp now keeps starting when hdmi is present. No need for 5 seconds delay. Very limited test yet, but at least camilladsp becomes operationnal after boot.
Nice solution, congrats.
Card ID is not fixed between reboots. There is no file based on the card name in /dev, but there are symlinks based on path in /dev/snd/by-path - see "ls -l /dev/snd/by-path". IMO the PCI path will be stable for your HDMI output, I would try the corresponding symlink file instead.PathExists=/dev/snd/pcmC1D3p
Thank you @phofman.
I undersand you suggest I replace "PathExists=/dev/snd/pcmC1D3p" by "PathExists=/dev/snd/by-path/pci-0000:00:0e.0" in the /etc/systemd/system/hdmi-audio.path file. Now done. Seems to work, with even less tests. I however have not been able to find out what "pci-0000:00:0e.0" represents, I'll have to dig into this, I'd very much appreciate some pointers here.
daniel@Wyse-5070:~$ ls -l /dev/snd/by-path
total 0
lrwxrwxrwx 1 root root 12 Jan 13 09:23 pci-0000:00:0e.0 -> ../controlC1
lrwxrwxrwx 1 root root 12 Jan 13 09:23 platform-snd_aloop.0 -> ../controlC0
I undersand you suggest I replace "PathExists=/dev/snd/pcmC1D3p" by "PathExists=/dev/snd/by-path/pci-0000:00:0e.0" in the /etc/systemd/system/hdmi-audio.path file. Now done. Seems to work, with even less tests. I however have not been able to find out what "pci-0000:00:0e.0" represents, I'll have to dig into this, I'd very much appreciate some pointers here.
Yes. It means PCI address of the audio device, as listed e.g. by lspci. It's a fairly stable identification, copilot says:I undersand you suggest I replace "PathExists=/dev/snd/pcmC1D3p" by "PathExists=/dev/snd/by-path/pci-0000:00:0e.0"
In the output of thelspci
command, the Bus, Device, and Function numbers are used to uniquely identify each PCI device in the system. Here is what each term means:
1. Bus Number:
- The bus number indicates which PCI bus the device is connected to. A system can have multiple PCI buses, each with its own unique number. The bus number helps to identify which specific bus the device is on.
2. Device Number:
- The device number is used to identify a specific device on a particular PCI bus. Each bus can support up to 32 devices, and each device is assigned a unique number from 0 to 31.
3. Function Number:
- The function number identifies a specific function within a PCI device. Some PCI devices can perform multiple functions, and each function is assigned a unique number from 0 to 7. If a device supports only a single function, the function number is typically 0.
The combination of Bus, Device, and Function numbers forms a unique identifier for each PCI device in the system. This is usually represented in the formatbus:device.function
, for example,00:1f.2
.
### Example
Code:$ lspci 00:1f.2 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 03)
In this example:
00
is the bus number.1f
is the device number.2
is the function number.
This unique identifier helps the system and users to locate and manage specific PCI devices.
Update: the configuration based on @phofman indication above, which I have detailed in message #7 above, is running now for about 3 weeks unchanged on my Dell Wyse headless ubuntu server connected by HDMI to my RX-V1700 Yamaha Receiver. Both second hand here on Ricardo in Switzerland, total aboutt 110€. Works like a charm, HDMI connection is always active when needed, even if the Receiver is not connected to an ouput HDMI screen. I had to add a "DisplayPort to HDMI" cable since the Dell Wyse5070 has no HDMI out - another 8€ or so. Thank you all for the help here.
- Home
- Source & Line
- PC Based
- How to delay camillaDSP service start until the HDMI playback device is available?