Set default audio output device

Hello,

I have recently set up a Raspberry Pi 4 with the Picroft stable 2020-09-07 enclosure. I have successfully completed some initial tests with a ReSpeaker 4-Mic array as the audio input and a portable bluetooh speaker using the aux-in.

I have now set up the speaker as a bluetooth speaker using the tutorial from Fixed: Connect Bluetooth Headphones with your Raspberry PI and I can successfully play audio through bluetooth with

$ aplay -D bluealsa /usr/share/sounds/alsa/Front_Center.wav

I was quite pleased with this, as I’m aware that bluetooth can be just a tad bit finicky.

The challenge I’m having is how to set it up as the default audio output device, so that all output, including Mycroft’s, is sent there.

To be clear, I don’t think this is Picroft specific and I could have posted on other forums, but as I’m using the Picroft enclosure, I thought this was a reasonable place to start. For instance, I also have this problem with the only other piece of software I have installed - Spotifyd. I regularly work with Linux, but audio and bluetooth are two areas that I haven’t delved in.

My search results have been suggesting different contents for my /home/pi/.asoundrc but I haven’t been successful so far.

I’ve checked Audio Troubleshooting - Mycroft AI but the results are confusing:

“pactl info” returns “analog-stereo” as my sink:

(.venv) pi@picroft:~ $ pactl info
Server String: /run/user/1000/pulse/native
Library Protocol Version: 32
Server Protocol Version: 32
Is Local: yes
Client Index: 32
Tile Size: 65496
User Name: pi
Host Name: picroft
Server Name: pulseaudio
Server Version: 12.2
Default Sample Specification: s16le 2ch 44100Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.platform-bcm2835_audio.analog-stereo
Default Source: alsa_input.platform-soc_sound.multichannel-input
Cookie: b5ae:31a9

“pactl list sinks short” only returns that option:

(.venv) pi@picroft:~ $ pactl list sinks short
0 alsa_output.platform-bcm2835_audio.analog-stereo module-alsa-card.c s16le 2ch 44100Hz SUSPENDED

However, if I run “alsamixer”, I select “F6: Select sound card”, it only lists “(default)”, “bcm2835 Headphones” and “seed-4mic-voicecard”. However, I can also select “enter device name” and type “bluealsa”. I can see the 4 levels of my bluetooth speaker “A2DP”, “SCO”, capture “SCO” and “Battery”:

Below are the steps I have completed as part of my bluetooth audio setup.

Does anybody have any suggestions to redirect the default audio output to the bluealsa device? Thank you.

usermod -G bluetooth -a pi
# Pulseaudio is already installed
apt-get install bluealsa
nano /lib/systemd/system/bluetooth.service

# Replace
# ExecStart=/usr/lib/bluetooth/bluetoothd

# With
# ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap

nano /lib/systemd/system/bthelper@.service

# Replace
#Type=simple
#ExecStart=/usr/bin/bthelper %I

# With
#Type=simple
#ExecStartPre=/bin/sleep 2
#ExecStart=/usr/bin/bthelper %I

bluetoothctl

# Within the new prompt
#power on
#agent on
#default-agent
#scan on
#pair F4:4E:FD:88:7A:47
#trust F4:4E:FD:88:7A:47
#connect F4:4E:FD:88:7A:47

# To reconnect manually
#bluetoothctl connect F4:4E:FD:88:7A:47

nano /etc/rc.local

# Replace
#fi
#
#exit 0

# With
#fi
#
##Reconnect to bluetooth speaker
#bluetoothctl connect F4:4E:FD:88:7A:47
#
#exit 0

# I can then play if I can output to Alsa device bluealsa
#aplay -D bluealsa:DEV=F4:4E:FD:88:7A:47,PROFILE=a2dp /usr/share/sounds/alsa/Front_Center.wav

nano /home/pi/.asoundrc

#Add
#defaults.bluealsa.interface "hci0"
#defaults.bluealsa.device "F4:4E:FD:88:7A:47"
#defaults.bluealsa.profile "a2dp"
#defaults.bluealsa.delay 10000

# I can then play without specifying bluealsa parameters
#aplay -D bluealsa /usr/share/sounds/alsa/Front_Center.wav

I’ve been doing some more digging up and I’ve found that my /etc/asound.conf is a symbolic link to /etc/voicecard/asound_4mic.conf which, critically, gets recreated on system restart. That appears related to the ReSpeaker 4-Mic array that I’m using as my microphone. Its contents are:

# If 555555 or 666666 is used by other processes, use another one

# use samplerate to resample as speexdsp resample is bad
defaults.pcm.rate_converter "samplerate"

pcm.!default {
    type asym
    playback.pcm "playback"
    capture.pcm "ac108"
}

pcm.playback {
    type plug
    slave.pcm "hw:ALSA"
}

# pcm.dmixed {
#     type dmix
#     slave.pcm "hw:0,0"
#     ipc_key 555555
# }

pcm.ac108 {
    type plug
    slave.pcm "hw:seeed4micvoicec"
}

# pcm.multiapps {
#     type dsnoop
#     ac108-slavepcm "hw:1,0"
#     ipc_key 666666
# }

I’ve managed to make some progress; Mycroft still doesn’t output to the Pulseaudio fallback sink, despite I’ve tried deleting the stream-restore database after setting the new fallback, but one step at a time.

Following are my notes on the process so far. They may help other users trying to set some bluetooth speakers as their default audio device, and someone may have some suggestions as to Mycroft still refuses to play along.

The Picroft enclosure is set up to use Pulseaudio and Mycroft needs it
The audio chain used to be:

  • Bluez => Alsa

But with newer Bluez versions it is (A):

  • Bluez => Pulseaudio => Alsa

Or alternatively (B):

  • Bluez => Bluealsa => Alsa

If you need Pulseaudio, you are better off by using A, unless you need some advanced functionality from Bluealsa
I’ve ended up using B by accident, but then making it my fallback Pulseaudio sink as I need Pulseaudio

  • Bluez => Pulseaudio => Bluealsa => Alsa

Bluez => Bluealsa => Alsa information from:

  • peppe8o. com/fixed-connect-bluetooth-headphones-with-your-raspberry-pi/
  • github. com/Arkq/bluez-alsa/wiki/Using-the-bluealsa-ALSA-pcm-plugin

usermod -G bluetooth -a pi
apt-get install bluealsa
nano /lib/systemd/system/bluetooth.service

Replace

ExecStart=/usr/lib/bluetooth/bluetoothd

With

ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap

nano /lib/systemd/system/bthelper@.service

Replace

Type=simple
ExecStart=/usr/bin/bthelper %I

With

Type=simple
ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/bthelper %I

bluetoothctl

Within the new prompt

power on
agent on
default-agent
scan on
pair your_bt_device_address
trust your_bt_device_address
connect your_bt_device_address

To reconnect manually

bluetoothctl connect your_bt_device_address

Trusted devices reconnect automatically anyway

I can then play if I output to “bluealsa” Bluealsa Alsa device

aplay -D bluealsa:your_bt_device_address,PROFILE=a2dp /usr/share/sounds/alsa/Front_Center.wav

User specific Alsa configuration is stored in ~/.asoundrc
System wide configuration is stored in /etc/asound.conf
But on my system this a soft link that points to /etc/voicecard/asound_4mic.conf and gets recreated on restart!
I could have just added the parameters for device “bluealsa”

defaults.bluealsa.device “your_bt_device_address”
defaults.bluealsa.profile “a2dp”
defaults.bluealsa.delay 10000

But instead I’ve created a “bt-speakers” Bluealsa Alsa PCM device and made it the default for playback

cp /etc/voicecard/asound_4mic.conf /etc/voicecard/asound_4mic.conf.bak
nano /etc/voicecard/asound_4mic.conf

Replace

pcm.!default {
type asym
playback.pcm “playback”
capture.pcm “ac108”
}

With

pcm.!default {
type asym
playback.pcm “bt-speakers-alsa”
capture.pcm “ac108”
}

Add

pcm.bt-speakers-alsa {
type plug
slave.pcm {
type bluealsa
device “your_bt_device_address”
profile “a2dp”
delay 12000
}
}

I can then play without specifying bluealsa parameters

aplay -D bt-speakers-alsa /usr/share/sounds/alsa/Front_Center.wav

This would be sufficient for an Alsa system, but I need to make it the fallback Pulseaudio sink
Bluez => Pulseaudio => Bluealsa => Alsa information from:

  • github. com/Arkq/bluez-alsa/wiki/PulseAudio-integration

Download:

  • 21-bluealsa-raw.conf
  • bluepulse.bash
  • bluepulse.service

Create a new “bluealsa-raw” raw Bluealsa Alsa PCM device, as processing will be completed by Pulseaudio

mv 21-bluealsa-raw.conf /etc/alsa/conf.d
chown root:root /etc/alsa/conf.d/21-bluealsa-raw.conf

Create a Pulseaudio sink

MODULE=$(pactl load-module module-alsa-sink device=‘bluealsa_raw:DEV=your_bt_device_address,PROFILE=a2dp’ fragments=‘1’ fragment_size=‘960’ sink_name=bt-speakers sink_properties=“device.description=‘Bluetooth\ speakers’”)

To remove the sink

pactl unload-module $MODULE

Info from:

  • www.freedesktop. org/wiki/Software/PulseAudio/Documentation/User/DefaultDevice/

Make it the fallback sink

pactl set-default-sink 1

I can then play without specifying anything!

aplay /usr/share/sounds/alsa/Front_Center.wav

I haven’t managed to automate adding and removing sinks and sources with the following
I would also need to add making it the fallback sink
Install gawk

apt -y install gawk
mv bluepulse.bash /usr/local/bin
chown root:root /usr/local/bin/bluepulse.bash
chmod 755 /usr/local/bin/bluepulse.bash
mv bluepulse.service /etc/systemd/user
chown root:root /etc/systemd/user/bluepulse.service
chmod 755 /etc/systemd/user/bluepulse.service

Run as pi

systemctl --user enable bluepulse.service

As a workaround, add them to Mycroft startup

nano /home/pi/custom_setup.sh

Add

#Bluetooth speakers
bluetoothctl connect your_bt_device_address
MODULE=$(pactl load-module module-alsa-sink device=‘bluealsa_raw:your_bt_device_address,PROFILE=a2dp’ fragments=‘1’ fragment_size=‘960’ sink_name=bt-speakers sink_properties=“device.description=‘Bluetooth\ speakers’”)
pactl set-default-sink 1

(I’m aware that I had to trick the parser into not identifying my links, but the alternative was to not to quote my sources, which I thought was worse)