[TUTORIAL] RPi as Bluetooth A2DP Reciever


41 posts   Page 1 of 2   1, 2
by uncrocks » Mon Dec 24, 2012 1:37 am
Not sure if there's already a tutorial somewhere for this, but I pieced together several posts/ideas to get this to work.

First, install all needed packages:
Code: Select all
sudo apt-get install bluetooth pulseaudio pulseaudio-module-bluetooth alsa-base alsa-utils blueman pavucontrol


Edit /etc/bluetooth/audio.conf to enable A2DP
Code: Select all
sudo nano /etc/bluetooth/audio.conf
After [General], add:
Code: Select all
Enable=Source,Sink,Media,Socket


Edit /etc/pulse/daemon.conf to allow Pulse to use the bluetooth audio
Code: Select all
sudo nano /etc/pulse/daemon.conf
At the end, add:
Code: Select all
resample-method=trivial


Edit /etc/pulse/system.pa to switch from scheduler to interrupt
Code: Select all
sudo nano /etc/pulse/system.pa
Find:
Code: Select all
load-module module-udev-detect
And change it to:
Code: Select all
load-module module-udev-detect tsched=0


Reboot
Code: Select all
sudo reboot


After reboot, login and start a desktop session:
Code: Select all
startx


Then open Blueman by right clicking the Bluetooth icon in the taskbar then clicking Devices.

Put your phone into discoverable mode, then click Scan in Blueman, and when your phone pops up right click, then click pair.

After you accept the pin on both devices, right click your phone in Blueman and click Trust.

Now loopback the Bluetooth to the audio out (replace XX_XX_XX_XX_XX_XX with your phone's bluetooth MAC, listed in Blueman):
Code: Select all
pactl load-module module-loopback source=bluez_source.XX_XX_XX_XX_XX_XX sink=alsa_output.platform-bcm2835_AUD0.0.analog-stereo rate=44100 adjust_time=0
*note: for now, you'll have to run the above command every time you connect by bluetooth.

Open Pavucontrol:
Code: Select all
pavucontrol


Change the output volume to your desired level.

Enjoy!

Note: You may need to change the audio output depending on where you want the audio sent. If you plan on using the headphone jack, I'd recommend buying a cheap USB soundcard instead (the alsa drivers aren't very good yet).

Still need to be fixed/figured out:
Automatically loopback source to sink when bluetooth connects.
When connect is pressed from trusted phone, RPi automatically accepts the request.

Thanks to:
kmonkey (most of the how-to)
Colin CW (fixing the sampling and scheduling)
Tim Bovelander (finding the correct packages to install)
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am
by redhawk » Tue Dec 25, 2012 1:33 am
Any idea why your list of "apt-get install" packages is causing unnecessary printer drivers to be installed??

Richard S.
User avatar
Posts: 3465
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by uncrocks » Tue Dec 25, 2012 5:04 am
I believe that's because the bluetooth printer drivers are included in the bluetooth package, I don't think they do any harm though.
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am
by MachineShedFred » Mon Jan 07, 2013 1:31 pm
Here's how to get the RPi to route the audio upon pairing with a sound source:

1. create a file if it doesn't exist: /etc/udev/rules.d/99-input.rules
Code: Select all
SUBSYSTEM="input", GROUP="input", MODE="0660"
KERNEL=="input[0-9]*", RUN+="/usr/lib/udev/bluetooth"


2. create the /usr/lib/udev/bluetooth file, with the following contents:
Code: Select all
#!/bin/sh

echo "Executing bluetooth script...|$ACTION|" >> /var/log/bluetooth_dev

ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
if [ "$ACTION" = "add" ]
then
   for dev in $(find /sys/devices/virtual/input/ -name input*)
   do
      if [ -f "$dev/name" ]
      then
         mac=$(cat "$dev/name" | sed 's/:/_/g')
         bluez_dev=bluez_source.$mac
         
         sleep 1
         
         CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev`
         if [ ! -z $CONFIRM ]
         then
            echo "Setting bluez_source to:  $bluez_dev" >> /var/log/bluetooth_dev
            echo pactl load-module module-loopback source=$bluez_dev sink=alsa_output.platform-bcm2835_AUD0.0.analog-stereo rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
            sudo -u pi pactl load-module module-loopback source=$bluez_dev sink=alsa_output.platform-bcm2835_AUD0.0.analog-stereo rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
       fi
      fi
   done
fi


This will trigger a script when a bluetooth input device connection is made, confirm that it adds a sound device, and then route the audio from it to the default output. The 1 second delay is to make sure that this script doesn't execute faster than bluez can add the sound input device in Pulse Audio.

Enjoy!
Posts: 3
Joined: Mon Jan 07, 2013 1:01 pm
by castalla » Mon Jan 07, 2013 3:33 pm
Any chance you could provide a tutorial for the Pi as a A2DP transmitter (to bt speakers)?

I had it working last week, but now it's all collapsed with 'connection refused' 111 errors ....

Googling 111 errors just opens up a huge can of worms!

Using bluetooth, bluez-utlls and alsa.

Cheers
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by uncrocks » Mon Jan 07, 2013 3:39 pm
It should be simple, I'm not on my computer right now, but I'll post steps when I am. :D
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am
by castalla » Mon Jan 07, 2013 4:10 pm
It was - pair, test audio, trust - add pcm.bt as device to asound.conf. Play via aplay -D bt sample.wav. Worked last week. Tried again on new install, same procedure until aplay - returns error 111.

Another issue - physically switching of the bt device crashes wheezy,
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by blackhole » Mon Jan 07, 2013 7:07 pm
Hi MachineShedFred, thanks for your post but it didn't work for me, in fact, i hadn't a /usr/lib/udev path, what distro are you using? Mine is Raspbian wheezy. I got the following messages on screen every time I try to connect my phone
Code: Select all
$ tail --follow /usr/var/log/kern.log
input: XX:XX:XX:XX:XX:XX as /devices/virtual/input/input2
input: XX:XX:XX:XX:XX:XX as /devices/virtual/input/input3
input: XX:XX:XX:XX:XX:XX as /devices/virtual/input/input4

The problem could be that I'm trying to play "Let put my love into you" by ACDC :)
Code: Select all
$ ls /sys/devices/virtual/input
[color=#0000BF]mice[/color]
Posts: 3
Joined: Mon Jan 07, 2013 4:56 pm
by uncrocks » Mon Jan 07, 2013 7:44 pm
I'm pretty sure you should just have to change the source and sink in the loopback command:

Do everything the same up until the pactl load-module command.

List Sources:
Code: Select all
pactl list sources short
Look for the one containing alsa and bcm_2835 (I'm not sure exactly what it is, I don't have my Pi atm).

List Sinks:
Code: Select all
pactl list sinks short
Look for the one containing Bluetooth, or bluez (again, not exactly sure).

Use the earlier command but with your new source and sink:
Code: Select all
pactl load-module module-loopback source=<alsa source> sink=<BT sink> rate=44100 adjust_time=0
*note, you may not need the rate=44100 adjust_time=0

That should work, I don't have my Pi, so I can't test it. Hope this helps :)
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am
by castalla » Mon Jan 07, 2013 9:08 pm
Thanks - I'll give it a try ... may be a few days before I can get round to it.
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by drgeoff » Mon Jan 07, 2013 9:54 pm
MachineShedFred wrote:Here's how to get the RPi to route the audio upon pairing with a sound source:

1. create a file if it doesn't exist: /etc/udev/rules.d/99-input.rules
Code: Select all
SUBSYSTEM="input", GROUP="input", MODE="0660"
KERNEL=="input[0-9]*", RUN+="/usr/lib/udev/bluetooth"



Should that first line be
Code: Select all
SUBSYSTEM=="input", GROUP="input", MODE="0660"

ie a "==" after "SUBSYSTEM"?
Posts: 6539
Joined: Wed Jan 25, 2012 6:39 pm
by castalla » Mon Jan 07, 2013 11:00 pm
I've been reading the above to try to understand (as best as possible given my ability!) what the process is.

I have a couple of questions:

1. What properties should the two files have? Is the bluetooth file made executable?

2. As I understand it, the process starts on detection of a pairing event. What happens if I switch the bt device off?

3. At the moment, I pair using simple-agent, trust using test-device trusted, and then test-audio connect. Is that the same procedure when implementing the above?

I think I'll have to set up a testing image!

cheers
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by drgeoff » Mon Jan 07, 2013 11:24 pm
I have had success with the method given by uncrocks but not with the addon from MachineShedFred. Even after making /usr/lib/udev/bluetooth executable, I still don't get a /var/log/bluetooth_dev file created.
Posts: 6539
Joined: Wed Jan 25, 2012 6:39 pm
by MachineShedFred » Tue Jan 08, 2013 1:28 am
1. Using Raspbian "Wheezy":
Code: Select all
$ uname -a
Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux


2. You're right: the proper contents of the /etc/udev/rules.d/99-input.rules (permissions rw-r--r--):
Code: Select all
SUBSYSTEM=="input", GROUP="input", MODE="0660"
KERNEL=="input[0-9]*", RUN+="/usr/lib/udev/bluetooth"

I retyped it in a hurry in the previous post, this is a copy and paste through SSH this time.

3. Yes, the /usr/lib/udev/bluetooth should have executable privileges. It's a shell script that the udev service executes when it loads the virtual input device.

I had some help with getting this going from a coworker that is much more familiar with the inner workings of udev than I am. If you can't get it going, I'll ask him what part I'm missing and post it tomorrow.
Posts: 3
Joined: Mon Jan 07, 2013 1:01 pm
by MachineShedFred » Tue Jan 08, 2013 1:57 am
Also, you can watch what udev triggers when you connect the bluetooth service from your phone with the udevadm monitor --udev:

Code: Select all
$ sudo udevadm monitor --udev
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing

UDEV  [2499.845822] add      /devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/bluetooth/hci0/hci0:12 (bluetooth)
UDEV  [2501.546449] add      /devices/virtual/input/input1 (input)
UDEV  [2501.562613] add      /devices/virtual/input/input1/event0 (input)

The three "add" lines are what triggers when I tap the bluetooth device on my iPhone to connect it as an audio receiver.

Also, one other thing we discovered: since Pulse Audio is running in user space, you need to make sure that in the script that the pactl load-module runs as the logged in user (the "sudo -u pi" bit). If it runs as root (which udev scripts do) or if you renamed the default "pi" user, it won't be able to load the loopback module.
Posts: 3
Joined: Mon Jan 07, 2013 1:01 pm
by castalla » Tue Jan 08, 2013 1:58 pm
I've finally got squeezelite working via bluetooth: using

Code: Select all
/usr/bin# squeezelite -m ab:cd:ef:12:34:56 -n BLUE -o btheadset -r 441000 -z


I want to start this when the Pi boots up but after the built in squeezelite process gets going.

Where would be the best place to place this command?
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by truehl » Tue Jan 08, 2013 5:12 pm
castalla wrote:I've finally got squeezelite working via bluetooth: using

Code: Select all
/usr/bin# squeezelite -m ab:cd:ef:12:34:56 -n BLUE -o btheadset -r 441000 -z


I want to start this when the Pi boots up but after the built in squeezelite process gets going.

Where would be the best place to place this command?

Which dongle exactly did you use?
truehl
http://www.squeezeplug.de
User avatar
Posts: 642
Joined: Sun Mar 04, 2012 6:47 pm
by castalla » Tue Jan 08, 2013 5:41 pm
This one:

http://www.amazon.co.uk/gp/product/B004 ... 00_s00_i00

It's running well on my cheap 13 euro 'Chinese' speakers!
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by castalla » Tue Jan 08, 2013 6:28 pm
One issue I'm having is that after some time, the whole PI locks up! Could be a deal breaker .... any ideas where I could look for a cause?
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by truehl » Tue Jan 08, 2013 7:08 pm
castalla wrote:This one:

http://www.amazon.co.uk/gp/product/B004 ... 00_s00_i00

It's running well on my cheap 13 euro 'Chinese' speakers!

just ordered, ill take a look!
truehl
http://www.squeezeplug.de
User avatar
Posts: 642
Joined: Sun Mar 04, 2012 6:47 pm
by castalla » Tue Jan 08, 2013 7:27 pm
Back to square-one .... now getting horrendous pulsing sounds on default analog output!

This needs a lot more testing.!!!
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm
by drgeoff » Tue Jan 08, 2013 8:00 pm
MachineShedFred wrote:Also, you can watch what udev triggers when you connect the bluetooth service from your phone with the udevadm monitor --udev:

Code: Select all
$ sudo udevadm monitor --udev
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing

UDEV  [2499.845822] add      /devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/bluetooth/hci0/hci0:12 (bluetooth)
UDEV  [2501.546449] add      /devices/virtual/input/input1 (input)
UDEV  [2501.562613] add      /devices/virtual/input/input1/event0 (input)

The three "add" lines are what triggers when I tap the bluetooth device on my iPhone to connect it as an audio receiver.

I only get the first of these three "add" lines.
(I'm using squeezeplug hard-float v6.01 which is based on Raspian Wheezy.)
Posts: 6539
Joined: Wed Jan 25, 2012 6:39 pm
by blackhole » Wed Jan 09, 2013 1:41 am
Hi drgeoff, you have to previously pair and trust your bluetooth audio source in order to get the other lines.

My problem is different, I get six messages every time I try to connect my Huawei
Code: Select all
add      /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/bluetooth/hci0/hci0:42 (bluetooth)
add      /devices/virtual/input/input3 (input)
add      /devices/virtual/input/input3/event0 (input)
remove      /devices/virtual/input/input3/event0 (input)
remove      /devices/virtual/input/input3 (input)
remove      /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/bluetooth/hci0/hci0:42 (bluetooth)

The input device is added and inmediately removed as I can see with this command:
Code: Select all
watch -n1 -differences ls -l /sys/devices/virtual/input/

Any idea?
Posts: 3
Joined: Mon Jan 07, 2013 4:56 pm
by drgeoff » Wed Jan 09, 2013 11:47 am
blackhole wrote:Hi drgeoff, you have to previously pair and trust your bluetooth audio source in order to get the other lines.

Yes have done the pair and trust stuff. As I said previously it did work with the manual method of uncrocks.

The bluetooth script does start. It writes the first echo to the log file but goes wrong after that because there is nothing in /sys/devices/virtual/input/ except a 'mice' directory.
Posts: 6539
Joined: Wed Jan 25, 2012 6:39 pm
by fredoll » Thu Jan 10, 2013 10:41 am
There is one little error in the udev bluetooth script proposed by
MachineShedFred (Mon Jan 07, 2013 1:31 pm)

Code: Select all
if [ ! -z $CONFIRM ]

Should be
Code: Select all
if [ ! -z "$CONFIRM" ]


Fred
Posts: 166
Joined: Thu Jan 10, 2013 10:30 am