Has been arduous, difficult, frustrating and tricky but finally and after two weeks we made it!! Our Beaglebone Black with Archlinux is able to reproduce sounds recorded from an USB microphone on a Bluetooth speaker aaaand is not just that, it is able to "auto-connect" after power up too... We made this possible with Bluez 5, Alsa, Pulseaudio 5 and a lot of try and error. So come on, be my guest and start reading the whole process.
We will start as always updating our system and then checking if our Bluetooth dongle and our USB Microphone are detected and loaded by Linux, you shouldn´t have any problems if you use the ones we recommended in HERE.
pacman -Syyu
lsusb
lsmod
Afer this we are going to install Bluez (Bluetooth protocol stack), Alsa (Audio devices handling) and Pulseaudio (Audio rerouting) latest versions and some utils. Pulseaudio should not be necessary but Bluez 5 is not supported by Alsa so if we want to use a Bluetooth Speaker we need to install it or jump down to the legacy methods with Bluez 4. Even more, if you want to use a Bluetooth Headset you won´t be able to do it with this latest Bluez 5, it is not supported yet!! Take a look in HERE for more information. Seems that Bluez 5 is not as good as it should be but we are here to install latest versions and for sure it will be improved by their developers. Let´s install then:
pacman -S bluez bluez-utils bluez-libs alsa-utils pulseaudio-alsa
Now we will start Bluetooth service and will enable it at boot time.
systemctl start bluetooth
systemctl enable bluetooth
We are ready to start, scan and pair our bluetooth speaker! I´m using a Creative D200, others should behave similar...! (or not...). We will start pulseadio service on first place and then we are going to use the 'bluetoothctl' utility that is going to help us on make the pair process simple.
pulseaudio --start -v
bluetoothctl
power on
agent on
default-agent
scan on (put your device on discovery mode before doing this!)
pair 00:02:3C:26:FC:A6 (change this to your own MAC founded after scan command)
0000 (your PIN code in here!)
trust 00:02:3C:26:FC:A6
scan off
exit
If you find any problem (probably on first launch you won´t find any device) please reboot! At this point you should be paired with your bluetooth speaker but if you reboot your link will be lost and will have to connect manually again. To do that you have two different options. Pair your device again through 'bluetoothctl' utility or pair it 'manually'. Let´s check how to do it 'manually', as we made it before, we will launch pulseaudio service on first place:
pulseaudio --start -v
Now we will check on the Sinks list which is our 'bluez.path', should be something like this: "/org/bluez/hci0/dev_00_02_3C_26_FC_A6"
pactl list sinks
And finally we will power bluetooth up and will connect to it through Dbus system daemon:
hciconfig hci0 up
dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/hci0/dev_00_02_3C_26_FC_A6 org.bluez.Device1.Connect
Ok, we are connected now but this is not fun enough! We want to make it automatically on boot time right? Let´s do it then... :-)
On first place we need to create a Pulseaudio Service file:
nano /usr/lib/systemd/system/pulseaudio.service
And now write this on it:
[Unit]
Description=PulseAudio Sound System
After=dbus.target sound.target
[Service]
ExecStart=/usr/bin/pulseaudio --system --disallow-exit -v
[Install]
WantedBy=multi-user.target
After Pulseaudio service we will create the Bluetooth service when we will powered it up and pair it:
nano /usr/lib/systemd/system/bluespk.service
Write this on it:
[Unit]
Description=Connect Bluetooth Speaker
After=dbus.target bluetooth.target
[Service]
ExecStart=/usr/lib/systemd/scripts/bluespk.sh
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
As you see the tricky stuff will be written on a bash shell so let´s create it!:
nano /usr/lib/systemd/scripts/bluespk.sh
Type this:
#!/bin/bash
hciconfig hci0 up
dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/hci0/dev_00_02_3C_26_FC_A6 org.bluez.Device1.Connect
We need to give execution properties to our new fancy files:
chmod +x /usr/lib/systemd/scripts/bluespk.sh
chmod +x /usr/lib/systemd/system/bluespk.service
chmod +x /usr/lib/systemd/system/pulseaudio.service
And now enable and start our services:
systemctl enable pulseaudio.service
systemctl start pulseaudio.service
systemctl enable bluespk.service
systemctl start bluespk.service
Due to Pulseaudio is not intended to be executed on boot time, we have to make it run on 'system' mode instead of running it on 'start' mode when we run it manually. Because of this 'system mode' we have to create and modify more files! Come on, we are reaching our goal... On first place we will change DBus policy:
nano /etc/dbus-1/system.d/pulseaudio.conf
Write this:
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="pulse">
<allow own="org.pulseaudio.Server"/>
<allow send_destination="org.pulseaudio.Server"/>
<allow receive_sender="org.pulseaudio.Server"/>
<allow send_destination="org.bluez"/>
<allow send_interface="org.bluez.Manager"/>
</policy>
</busconfig>
Now open up Pulseaudio daemon configuration to modify it:
nano /etc/pulse/daemon.conf
Uncomment these lines:
allow-module-loading = yes
load-default-script-file = yes
default-script-file = /etc/pulse/default.pa
And now we will create the 'pulse' user and group, and add it to the audio group:
useradd pulse
groupadd pulse-access
usermod -a -G audio pulse
We will add as much users as we want to the pulse group, in our case just the 'root' user:
usermod -a -G pulse-access root
And finally we are going to define a Home to pulse user.
usermod --home /var/run/pulse pulse
mkdir -p /var/run/pulse
chown -R pulse: /var/run/pulse
That´s all, we made it, reboot and check the magic! If everything went OK your bluetooth speaker should be autoconnected to your Beaglebone Black! Take a look on these links for more information: 1, 2, 3, 4. We made it possible thanks to them! If something is failing try to find it out with this command:
journalctl -b
We are now in position to record and play some audio. We will check Audio levels first, we can do this with 'alsamixer' GUI easily or manually with 'amixer'. Let´s check our current Mixer levels:
amixer contents
If you are using our recommended devices you will have a similar Mixer configuration, so in order to set up our Playkbak volume to 100% and our recording volume to 40% (maximum for our Microphone in order to not distort) these are the commands:
amixer cset numid=2,iface=MIXER,name='Capture Switch' on
amixer cset numid=1,iface=MIXER,name='Capture Volume' 26281
amixer cset numid=4,iface=MIXER,name='Master Playback Switch' on
amixer cset numid=3,iface=MIXER,name='Master Playback Volume' 65536,65536
In order to force which will be our recording device we need to check his name with:
pactl list
or through Alsa detected devices:
arecord -L
In our case we will extract the information given by pactl sources device string. Now, clear your voice and begin to record some funny stuff during 5 seconds with a Signed 16 bit Little Endian sampling rate at 48000Hz:
arecord -d 5 -f S16_LE -r 48000 -c 1 -D hw:1 -t wav test.wav
And finally let´s Play it on our sink device (get this string from 'pactl' command under sink name)!
paplay -d bluez_sink.00_02_3C_26_FC_A6 --format=s16le --channels=1 --rate=48000 --file-format=wav test.wav
If you ear some noise, try setting up a lower recording volume. If this doesn´t help consider to use a better power supply or even a external-powered USB Hub.
That´s all! A little step for the Mankind but a great one for us! And remember: Keep calm and Beaglebone! :)
No comments :
Post a Comment