openassistant / oa-core

Open Assistant Core
http://openassistant.org
GNU General Public License v3.0
293 stars 77 forks source link

Challenges with ALSA / Raspberry Pi OS #45

Open a-theriault opened 3 years ago

a-theriault commented 3 years ago

Description OA can't find hardware to output audio to with some configurations of ALSA and modern versions of Raspberry PI OS.

Reproduction Steps to reproduce the behavior:

  1. install OA onto a fresh Raspberry PI install
  2. Verify audio plays regularly within the OS (e.g. using aplay )
  3. run OA and say the "boot mind" command.

An error may generate, or no error and no audio out.

Expected behavior The r2d2 wav file should be heard through the HDMI or 3.5mm jack.

*(Note: ALSA and Raspberry Pi OS (RPiOS) have nothing to do with Open Assistant, and these notes are out of scope for the software. I'm leaving them here not to torment the developers (sorry) but to provide some help if this is someone's use case)

ALSA Specific Issues

It's incredibly difficult to give advice on a single solve for this section, since there are infinite combinations of things that can misfire here, but a quick checklist:

Configuring these is its own topic, is reasonably covered elsewhere on the web, and will take some trial and error. You'll want to use the -l switch on aplay and arecord to identify your hardware, and then set up your .asoundrc file to something like:

pcm.!default {
  type asym
  capture.pcm "mic"
  playback.pcm "speaker"
}
pcm.mic {
  type plug
  slave {
    pcm "hw:2,0"
  }
}
pcm.speaker {
  type plug
  slave {
    pcm "hw:1,0"
  } 
}

You will need to change the "hw,#,#" sections for speaker and mic to the card# and device# that you want to use. You can use aplay -l and arecord -l to get that information.

It's recommended to install alsa-utils as an opening step if you don't have them already. Try searching for help with alsamixer, amixer and .asoundrc specifically if you suspect the problem is a configuration issue.

Note that adjusting anything in alsamixer and amixer only affects the session, and will reset on reboot. More information on that - while Ubuntu-specific, it should apply here as well.

Raspberry Pi OS issues

A quick list of things to try:

Try installing gst for python to help python apps get sound output configured:

sudo apt install python3-gst-1.0

If you get an error on boot: "failed to open vchiq instance," make sure your user has permissions to access the audio group if you aren't using the default "pi" user:

sudo usermod -a -G audio <username>

and if you're playing through HDMI, add the video group for good measure:

sudo usermod -a -G video <username>

test the first, resort to the latter as needed.

Next, you may want to try the raspi-config utility, there are a few quirks here, and it's recommended to set this first, as it seems to be one of the contributing factors to the dreaded ".asoundrc is overwritten" problems that I've seen ALSA users complain about on RPiOS specifically.

Do this first, making sure that the default output is set to the jack you want (HDMI or Headphones). I have seen issues where even after setting this, the device will bounce back and favor HDMI aggressively. the /etc/share/alsa/alsa.conf file may be a last-resort if you want to be a bit brutish about it. You can also try configuring your monitor resolutions from the CEA configuration to DMT. It was suggested that DMT is targeted at monitors (vs CEA at televisions), but I haven't personally seen this affect the aggressiveness with which RPiOS and ALSA seem to favor HDMI-out over the 3.5mm jack.

Lastly, OA makes use of playsound library, which in turn makes use of gstreamer. Here's where some very specific trouble can start. Gstreamer, espeak, ALSA and RPiOS as a combination are, in my experience, something of a moving target. It's not really clear what (if anything) should change in OA to address this, since there are multiple libraries for alsa support under python, it's a narrow use case when considering the overall support matrix, and from what I've seen the conventions change frequently)

RPiOS in particular configures its audio I/O a bit unconventionally here (I'm paraphrasing comments gathered around the web, I really have no idea), specifically around its naming conventions for devices.

I've had luck just going with earlier versions of RPiOS that didn't seem to have the Gstreamer + ALSA quirks out of the box. I've also had luck just circumventing the "play()" command entirely in the minds' files (boot.py and root.py specifically).

One option I landed on for a fixed-scope project was to open up oa-core/oa/modules/mind/minds/boot.py and play audio with aplay directly, adding the following lines:

from subprocess import check_call

check_call(["aplay", "-Dhw1,0", "/path/to/oa-core/oa/modules/mind/minds/sounds/r2d2.wav"])

You will need to use the aplay -l command to check the card and device number you want to output sound with, and adjust the "-Dhw" portion of the command above to reflect your card#, device#. Also double-check the path.

Even then, I got some quiet audio - another common issue I've seen with ALSA+RPiOS and the 3.5mm jack.

After an hour or so of fiddling (I'm not very proficient in python, and very much less so in ALSA-related issues), I had success jacking the sound up with amixer just before the aplay command, e.g.

from subprocess import check_call
check_call(["amixer", "set", "PCM", "pvolume", "100%"])
check_call(["aplay", "-Dhw1,0", "/path/to/oa-core/oa/modules/mind/minds/sounds/r2d2.wav"])

Note that "PCM" and "pvolume" in the above are almost certainly NOT what you're going to have as device names - the comment above about RPiOS being unconventional with device names applies here. It could be argued by the RPiOS folks that ALSA doesn't really supply a clear recommendation on convention or standard either. ¯_(ツ)_/¯

Candidly, anyone who's reached this stage is in the territory of a very specific last-resort. Read up on the amixer CLI for more info on identifying your device.

Also note that "100%" here will max your volume. It's recommended to test with alsamixer first (or turn your speakers way down) to make sure this is what you want.

I would recommend immediately closing this issue unless an active solve is being worked on - I did want to park it somewhere in the hopes it helps someone in a search. Hope some or all of the above helps someone facing similar difficulty :)

joshuashort commented 2 years ago

I'm still hesitant to close this -- it really deserves a place somewhere. Sorry it wasn't acknowledged earlier, but this is a rich and detailed dive into something that might seem like an OA problem (and kind of is) but isn't.