uncrocks
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am

[TUTORIAL] RPi as Bluetooth A2DP Reciever

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)

User avatar
redhawk
Posts: 3465
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.

uncrocks
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.

MachineShedFred
Posts: 3
Joined: Mon Jan 07, 2013 1:01 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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!

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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

uncrocks
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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,

blackhole
Posts: 3
Joined: Mon Jan 07, 2013 4:56 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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]

uncrocks
Posts: 10
Joined: Mon Dec 10, 2012 4:14 am

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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 :)

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.

drgeoff
Posts: 13818
Joined: Wed Jan 25, 2012 6:39 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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"?
Quis custodiet ipsos custodes?

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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

drgeoff
Posts: 13818
Joined: Wed Jan 25, 2012 6:39 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.
Quis custodiet ipsos custodes?

MachineShedFred
Posts: 3
Joined: Mon Jan 07, 2013 1:01 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.

MachineShedFred
Posts: 3
Joined: Mon Jan 07, 2013 1:01 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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?

User avatar
truehl
Posts: 642
Joined: Sun Mar 04, 2012 6:47 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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!

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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?

User avatar
truehl
Posts: 642
Joined: Sun Mar 04, 2012 6:47 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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

castalla
Posts: 558
Joined: Thu Jul 19, 2012 3:46 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.!!!

drgeoff
Posts: 13818
Joined: Wed Jan 25, 2012 6:39 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.)
Quis custodiet ipsos custodes?

blackhole
Posts: 3
Joined: Mon Jan 07, 2013 4:56 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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?

drgeoff
Posts: 13818
Joined: Wed Jan 25, 2012 6:39 pm

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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.
Quis custodiet ipsos custodes?

fredoll
Posts: 228
Joined: Thu Jan 10, 2013 10:30 am

Re: [TUTORIAL] RPi as Bluetooth A2DP Reciever

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

Return to “Media centres”