You are not logged in.

#1 2012-10-20 17:49:07

s0l1dsnak3123
Member
From: Scotland
Registered: 2008-06-26
Posts: 70
Website

[Solved] Bluetooth A2DP source to pulseaudio OR ALSA

Edit

So, I'm happy to say that I have it working to some degree!

I wasn't happy with the default bluez tools, but I managed to find a useful set of tools which seemed to work better: http://gitorious.org/bluez-tools/bluez-tools/

I compiled and make'd them, then created the following startup script to set up everything in the order it is needed for the next part to work: https://gist.github.com/c990e397388bd4399a15

I made a file called bluetoothPin in the home directory with the following in it:

<My phone's MAC (without the angle brackets)> <A Pin Number>

The bt-agent command in the startup.sh script uses that file to authorise connections. I aim to modify it to allow any connection to connect with the same pin, I'll get into that later.

For the actual streaming, I installed qt so I could get the qdbus binary, then I followed the instructions here: http://ubuntuforums.org/showthread.php? … st10492742

That code worked, so I modified it a little so that it would wait for a connection, then make the connection, then wait for a new connection on disconnect: https://gist.github.com/8e32a9cf786995c00f2f

It's not perfect; things get a bit iffy when you try to pair and then connect a device without rebooting the pi: It disconnects gracefully, and it pairs correctly, but pulse doesn't seem to re-add it to its list, so it's no longer identified by my script. Also I haven't figured out how to pair any device against the same pin code yet. Any help with that would be awesome!


---


Hi there,

I'm trying to build a bluetooth audio receiver server for my car! I have a raspberry pi with arch installed on it, bluez set up and configured (I can pair my phone with it through the bluez-simple-agent, although I think I'll have to write my own pairing daemon to auto-pair anything that attempts to connect).

Baby steps though: I've got bluez all set up as I mentioned earlier, but pulse doesn't seem to "see" the bluetooth connection. I'm not sure exactly what information you guys need to help me, but I've tried to add everything I could think of:

[root@alarmpi ~]# tail /var/log/messages.log
Oct 20 18:25:22 alarmpi bluetoothd[112]: bluetoothd[112]: Endpoint registered: sender=:1.4 path=/MediaEndpoint/A2DPSource
Oct 20 18:25:22 alarmpi bluetoothd[112]: bluetoothd[112]: Endpoint registered: sender=:1.4 path=/MediaEndpoint/A2DPSink
Oct 20 18:25:22 alarmpi bluetoothd[112]: Endpoint registered: sender=:1.4 path=/MediaEndpoint/HFPAG
Oct 20 18:25:22 alarmpi bluetoothd[112]: Endpoint registered: sender=:1.4 path=/MediaEndpoint/HFPHS
Oct 20 18:25:22 alarmpi bluetoothd[112]: Endpoint registered: sender=:1.4 path=/MediaEndpoint/A2DPSource
Oct 20 18:25:22 alarmpi bluetoothd[112]: Endpoint registered: sender=:1.4 path=/MediaEndpoint/A2DPSink
Oct 20 18:25:22 alarmpi pulseaudio[165]: [pulseaudio] server-lookup.c: Unable to contact D-Bus: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
Oct 20 18:25:22 alarmpi pulseaudio[165]: [pulseaudio] main.c: Unable to contact D-Bus: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
Oct 20 18:39:57 alarmpi systemd[1]: Starting Cleanup of Temporary Directories...
Oct 20 18:39:57 alarmpi systemd[1]: Started Cleanup of Temporary Directories.
[root@alarmpi ~]# 

This is interesting... to me it looks like bluetoothd is registering with pulse here.

[root@alarmpi ~]# pactl list
Module #0
	Name: module-device-restore
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Automatically restore the volume/mute state of devices"
		module.version = "2.1"

Module #1
	Name: module-stream-restore
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Automatically restore the volume/mute/device state of streams"
		module.version = "2.1"

Module #2
	Name: module-card-restore
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Automatically restore profile of cards"
		module.version = "2.1"

Module #3
	Name: module-augment-properties
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Augment the property sets of streams with additional static information"
		module.version = "2.1"

Module #4
	Name: module-alsa-card
	Argument: device_id="0" name="platform-bcm2835_AUD0.0" card_name="alsa_card.platform-bcm2835_AUD0.0" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes card_properties="module-udev-detect.discovered=1"
	Usage counter: 0
	Properties:
		module.author = "Lennart Poettering"
		module.description = "ALSA Card"
		module.version = "2.1"

Module #5
	Name: module-udev-detect
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Detect available audio hardware and load matching drivers"
		module.version = "2.1"

Module #6
	Name: module-bluetooth-discover
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Joao Paulo Rechi Vita"
		module.description = "Detect available bluetooth audio devices and load bluetooth audio drivers"
		module.version = "2.1"

Module #7
	Name: module-esound-protocol-unix
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "ESOUND protocol (UNIX sockets)"
		module.version = "2.1"

Module #8
	Name: module-native-protocol-unix
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Native protocol (UNIX sockets)"
		module.version = "2.1"

Module #9
	Name: module-default-device-restore
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Automatically restore the default sink and source"
		module.version = "2.1"

Module #10
	Name: module-rescue-streams
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "When a sink/source is removed, try to move their streams to the default sink/source"
		module.version = "2.1"

Module #11
	Name: module-always-sink
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Colin Guthrie"
		module.description = "Always keeps at least one sink loaded even if it's a null one"
		module.version = "2.1"

Module #12
	Name: module-intended-roles
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Automatically set device of streams based of intended roles of devices"
		module.version = "2.1"

Module #13
	Name: module-suspend-on-idle
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "When a sink/source is idle for too long, suspend it"
		module.version = "2.1"

Module #14
	Name: module-console-kit
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Create a client for each ConsoleKit session of this user"
		module.version = "2.1"

Module #15
	Name: module-systemd-login
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Create a client for each login session of this user"
		module.version = "2.1"

Module #16
	Name: module-position-event-sounds
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Position event sounds between L and R depending on the position on screen of the widget triggering them."
		module.version = "2.1"

Module #17
	Name: module-role-cork
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Lennart Poettering"
		module.description = "Mute & cork streams with certain roles while others exist"
		module.version = "2.1"

Module #18
	Name: module-filter-heuristics
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Colin Guthrie"
		module.description = "Detect when various filters are desirable"
		module.version = "2.1"

Module #19
	Name: module-filter-apply
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Colin Guthrie"
		module.description = "Load filter sinks automatically when needed"
		module.version = "2.1"

Module #20
	Name: module-dbus-protocol
	Argument: 
	Usage counter: n/a
	Properties:
		module.author = "Tanu Kaskinen"
		module.description = "D-Bus interface"
		module.version = "2.1"

Module #21
	Name: module-switch-on-port-available
	Argument: 
	Usage counter: n/a
	Properties:
		

Sink #0
	State: SUSPENDED
	Name: alsa_output.platform-bcm2835_AUD0.0.analog-stereo
	Description: bcm2835 ALSA Analog Stereo
	Driver: module-alsa-card.c
	Sample Specification: s16le 2ch 44100Hz
	Channel Map: front-left,front-right
	Owner Module: 4
	Mute: no
	Volume: 0:  86% 1:  86%
	        0: -4.00 dB 1: -4.00 dB
	        balance 0.00
	Base Volume:  86%
	             -4.00 dB
	Monitor Source: alsa_output.platform-bcm2835_AUD0.0.analog-stereo.monitor
	Latency: 0 usec, configured 0 usec
	Flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY 
	Properties:
		alsa.resolution_bits = "16"
		device.api = "alsa"
		device.class = "sound"
		alsa.class = "generic"
		alsa.subclass = "generic-mix"
		alsa.name = "bcm2835 ALSA"
		alsa.id = "bcm2835 ALSA"
		alsa.subdevice = "0"
		alsa.subdevice_name = "subdevice #0"
		alsa.device = "0"
		alsa.card = "0"
		alsa.card_name = "bcm2835 ALSA"
		alsa.long_card_name = "bcm2835 ALSA"
		alsa.driver_name = "snd_bcm2835"
		device.bus_path = "platform-bcm2835_AUD0.0"
		sysfs.path = "/devices/platform/bcm2835_AUD0.0/sound/card0"
		device.string = "hw:0"
		device.buffering.buffer_size = "17632"
		device.buffering.fragment_size = "4416"
		device.access_mode = "serial"
		device.profile.name = "analog-stereo"
		device.profile.description = "Analog Stereo"
		device.description = "bcm2835 ALSA Analog Stereo"
		alsa.mixer_name = "Broadcom Mixer"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card"
	Ports:
		analog-output: Analog Output (priority: 9900)
	Active Port: analog-output
	Formats:
		pcm

Source #0
	State: SUSPENDED
	Name: alsa_output.platform-bcm2835_AUD0.0.analog-stereo.monitor
	Description: Monitor of bcm2835 ALSA Analog Stereo
	Driver: module-alsa-card.c
	Sample Specification: s16le 2ch 44100Hz
	Channel Map: front-left,front-right
	Owner Module: 4
	Mute: no
	Volume: 0: 100% 1: 100%
	        0: 0.00 dB 1: 0.00 dB
	        balance 0.00
	Base Volume: 100%
	             0.00 dB
	Monitor of Sink: alsa_output.platform-bcm2835_AUD0.0.analog-stereo
	Latency: 0 usec, configured 0 usec
	Flags: DECIBEL_VOLUME LATENCY 
	Properties:
		device.description = "Monitor of bcm2835 ALSA Analog Stereo"
		device.class = "monitor"
		alsa.card = "0"
		alsa.card_name = "bcm2835 ALSA"
		alsa.long_card_name = "bcm2835 ALSA"
		alsa.driver_name = "snd_bcm2835"
		device.bus_path = "platform-bcm2835_AUD0.0"
		sysfs.path = "/devices/platform/bcm2835_AUD0.0/sound/card0"
		device.string = "0"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card"
	Formats:
		pcm

Client #0
	Driver: module-systemd-login.c
	Owner Module: 15
	Properties:
		application.name = "Login Session c1"
		systemd-login.session = "c1"

Client #2
	Driver: protocol-native.c
	Owner Module: 8
	Properties:
		application.name = "pactl"
		native-protocol.peer = "UNIX socket client"
		native-protocol.version = "26"
		application.process.id = "253"
		application.process.user = "root"
		application.process.host = "alarmpi"
		application.process.binary = "pactl"
		application.language = "C"
		application.process.machine_id = "5c49cb5bf08724338eb09a6900092bb0"

Card #0
	Name: alsa_card.platform-bcm2835_AUD0.0
	Driver: module-alsa-card.c
	Owner Module: 4
	Properties:
		alsa.card = "0"
		alsa.card_name = "bcm2835 ALSA"
		alsa.long_card_name = "bcm2835 ALSA"
		alsa.driver_name = "snd_bcm2835"
		device.bus_path = "platform-bcm2835_AUD0.0"
		sysfs.path = "/devices/platform/bcm2835_AUD0.0/sound/card0"
		device.string = "0"
		device.description = "bcm2835 ALSA"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card"
	Profiles:
		output:analog-mono: Analog Mono Output (sinks: 1, sources: 0, priority. 100)
		output:analog-stereo: Analog Stereo Output (sinks: 1, sources: 0, priority. 6000)
		off: Off (sinks: 0, sources: 0, priority. 0)
	Active Profile: output:analog-stereo
	Ports:
		analog-output: Analog Output (priority: 9900)
			Part of profile(s): output:analog-mono, output:analog-stereo
[root@alarmpi ~]# cat /etc/bluetooth/audio.conf 
# Configuration file for the audio service

# This section contains options which are not specific to any
# particular interface
[General]

Enable=Source

# Switch to master role for incoming connections (defaults to true)
#Master=true

# If we want to disable support for specific services
# Defaults to supporting all implemented services
#Disable=Gateway,Source,Socket

# SCO routing. Either PCM or HCI (in which case audio is routed to/from ALSA)
# Defaults to HCI
#SCORouting=PCM

# Automatically connect both A2DP and HFP/HSP profiles for incoming
# connections. Some headsets that support both profiles will only connect the
# other one automatically so the default setting of true is usually a good
# idea.
#AutoConnect=true

# Headset interface specific options (i.e. options which affect how the audio
# service interacts with remote headset devices)
[Headset]

# Set to true to support HFP, false means only HSP is supported
# Defaults to true
HFP=true

# Maximum number of connected HSP/HFP devices per adapter. Defaults to 1
MaxConnected=1

# Set to true to enable use of fast connectable mode (faster page scanning)
# for HFP when incoming call starts. Default settings are restored after
# call is answered or rejected. Page scan interval is much shorter and page
# scan type changed to interlaced. Such allows faster connection initiated
# by a headset.
FastConnectable=false

# Just an example of potential config options for the other interfaces
#[A2DP]
SBCSources=1
MPEG12Sources=0
[root@alarmpi ~]# cat /etc/asound.conf 
# Use PulseAudio by default
pcm.!default {
  type pulse
  fallback "sysdefault"
  hint {
    show on
    description "Default ALSA Output (currently PulseAudio Sound Server)"
  }
}

ctl.!default {
  type pulse
  fallback "sysdefault"
}

# vim:set ft=alsaconf:

---

About my project in general:

I want to be able to do the following:

- Give pulseaudio access to the bluetooth device, and use the A2DP protocol to receive the audio. From my research, it is possible, but I'm not sure how.
- Open up bluez so that I can pair any device by connecting with "1234" for the auth, then it will automatically check for A2DP and give that information to pulse

The idea being that any bluetooth device can pair without any interaction from the raspberry pi, and then pulse will have access to all of the devices which are playing music.

1] Is this even possible?
2] Can I use alsa instead as it seems it'd be easier/lighter to manage?
3] Are there any documents other than arch's bluetooth and pulse wikis that I can read to help me figure this out?

Last edited by s0l1dsnak3123 (2012-10-20 23:53:01)

Offline

Board footer

Powered by FluxBB