Raspberry Pi Bluetooth Speaker: Difference between revisions
m (→Bluetooth: Use more pkg template.) |
|||
(21 intermediate revisions by 7 users not shown) | |||
Line 8: | Line 8: | ||
* A Bluetooth USB dongle (if your Pi doesn’t have Bluetooth on board) | * A Bluetooth USB dongle (if your Pi doesn’t have Bluetooth on board) | ||
* Sound card and speaker(s) | * Sound card and speaker(s) | ||
=Article Completion= | |||
# Test everything | |||
# Turn every background task into a service | |||
# More investigation on Bluetooth pairing | |||
=Getting the Speaker(s) Working= | =Getting the Speaker(s) Working= | ||
To get the best results, you'll need an dedicated audio add-on board and matching speakers. Higher end passive speakers need a proper amplifier (e.g. HiFiBerry Amp2 or IQaudIO IQaudIO DigiAMP+). | |||
I' | I've used the whole range of IQaudio audio boards with different speakers and headphones. I'd also recommend a dedicated USB Bluetooth dongle (don't get the cheapest versions of these). It is possible to test by using the on-board Bluetooth and the on-board audio with headphones but because of dropped packets, the audio quality isn't great. | ||
Once the | Once the speakers and audio card are connected to the Raspberry Pi, it's time to install a fresh version of Alpine Linux. The armv7 version from the [https://alpinelinux.org/downloads/ Downloads] page works on almost all Pis. This Wiki has several articles about installing Alpine on a Raspberry Pi. | ||
Enable writing to the boot media: | Enable writing to the boot media: | ||
Line 20: | Line 25: | ||
mount /media/mmcblk0p1 -o rw,remount | mount /media/mmcblk0p1 -o rw,remount | ||
Then either enable the on board sound: | Then, either enable the on board sound: | ||
echo "dtparam=audio=on" >> /media/mmcblk0p1/usercfg.txt | echo "dtparam=audio=on" >> /media/mmcblk0p1/usercfg.txt | ||
or your | or your sound card (e.g. IQaudIO): | ||
echo "dtoverlay=iqaudio-dacplus,unmute_amp" >> /media/mmcblk0p1/usercfg.txt | echo "dtoverlay=iqaudio-dacplus,unmute_amp" >> /media/mmcblk0p1/usercfg.txt | ||
reboot. | |||
Follow [ | Follow [[ALSA|these instructions]] to enable ALSA. In summary: | ||
apk add alsa-utils alsa-utils-doc alsa-lib alsaconf # the required software for sound | apk add {{pkg|alsa-utils|arch=a*}} {{pkg|alsa-utils-doc|arch=a*}} {{pkg|alsa-lib|arch=a*}} {{pkg|alsaconf|arch=a*}} # the required software for sound | ||
aplay -l # should display a List of PLAYBACK Hardware Devices | aplay -l # should display a List of PLAYBACK Hardware Devices | ||
Line 48: | Line 53: | ||
Subdevice #6: subdevice #6 | Subdevice #6: subdevice #6 | ||
Before you play anything from your speakers, I | Before you play anything from your speakers, I recommend turnong down the volume. | ||
amixer | amixer | ||
displays a list of "simple controls" | displays a list of "simple controls." For my headphones and the on-board sound, the output looks like this: | ||
Simple mixer control 'Headphone',0 | Simple mixer control 'Headphone',0 | ||
Line 60: | Line 65: | ||
Mono: Playback 0 [96%] [0.00dB] [on] | Mono: Playback 0 [96%] [0.00dB] [on] | ||
In this case there is only 1 control, 'Headphone', so I issue this command to lower the maximum volume to a comfortable level (50% | In this case, there is only 1 control, 'Headphone', so I issue this command to lower the maximum volume to a comfortable level. (50%) | ||
amixer sset Headphone 50% | amixer sset Headphone 50% | ||
The IQaudIO DAC that I use has a much | The IQaudIO DAC that I use has a much larger set of controls. I issued this command to set the volume: | ||
amixer sset 'Digital' 50 # quotes may be required if there are spaces in the control name | amixer sset 'Digital' 50 # quotes may be required if there are spaces in the control name | ||
Note | Note: there can be several interlinked controls, some of which are muted by defualt. ALSA (and other audio software on Linux) is notoriously under-documented, try `man amixer` for more information. Sometimes it is easier to use a more visual control to change the configuration: | ||
alsamixer | alsamixer | ||
Line 76: | Line 81: | ||
speaker-test -t wav -c 2 | speaker-test -t wav -c 2 | ||
Then you should hear "Front Left, Front Right" repeating from your chosen speakers. Now it's time to setup Bluetooth. Don't forget to save your changes (lbu commit) | Then you should hear "Front Left, Front Right" repeating from your chosen speakers. Now it's time to setup Bluetooth. Don't forget to save your changes (lbu commit). | ||
=Bluetooth= | =Bluetooth= | ||
I used [ | I used [[Raspberry Pi 3 - Setting Up Bluetooth|Raspberry Pi 3 - Setting Up Bluetooth]] as a reference with some slight modifications as I am using a Pi 4. | ||
Raspberry Pi 4 | Raspberry Pi 4 | ||
apk add bluez | apk add {{pkg|bluez|arch=a*}} | ||
btattach -B /dev/ttyAMA0 -P bcm -S 3000000 & | btattach -B /dev/ttyAMA0 -P bcm -S 3000000 & | ||
# btattach -B /dev/ttyAMA0 -P bcm -S 115200 -N & # Pi 3 - not tested by me | # btattach -B /dev/ttyAMA0 -P bcm -S 115200 -N & # Pi 3 - not tested by me | ||
rc-service bluetooth start | rc-service bluetooth start | ||
edit | edit {{Path|/etc/mdev.conf}} and enable bluetooth. This is done by uncommenting the the line and change the <code>btattach</code> to work with Pi 4. | ||
{{cat|/etc/mdev.conf|<nowiki>... | |||
# rpi bluetooth | |||
ttyAMA0 root:tty 660 @btattach -B /dev/ttyAMA0 -P bcm -S 3000000 & | |||
...</nowiki>}} | |||
Changes to {{Path|/etc/bluetooth/main.conf}} | |||
Name = Pi-Bluetooth-Speaker # This is what you'll see when connecting | |||
Class = 0x41C # Adding audio playback and recording to this Bluetooth device | |||
DiscoverableTimeout = 0 # Always discoverable | |||
AlwaysPairable = true # Always pairable | |||
PairableTimeout = 0 # no time limit | |||
AutoEnable=true # starts Bluetooth when Linux 'sees' the Bluetooth device at boot | |||
Ensure that Bluetooth is started at boot: | |||
Ensure that | |||
rc-update add bluetooth | rc-update add bluetooth | ||
Bluetooth's state, including paired devices, in held in | Bluetooth's state, including paired devices, in held in {{Path|/var/lib/bluetooth}} so you'll need to add this to `lbu` state: | ||
lbu include /var/lib/bluetooth | lbu include /var/lib/bluetooth | ||
lbu commit && reboot | lbu commit && reboot | ||
Manual device pairing | |||
bluetoothctl | |||
[bluetooth]# discoverable on | |||
[agent] Confirm passkey 627133 (yes/no): yes | |||
[agent] Authorize service 0000110e-0000-1000-8000-00805f9b34fb (yes/no): yes | |||
Device pairing: | Device pairing: | ||
apk add python3 py3-dbus py3-gobject3 | apk add {{pkg|python3|arch=a*}} {{pkg|py3-dbus|arch=a*}} {{pkg|py3-gobject3|arch=a*}} | ||
Getting this to work currently involves running the bluez-simple-agent after having edited it to always return sucessful. | Getting this to work currently involves running the bluez-simple-agent after having edited it to always return sucessful. You'll need to comment out some lines (by adding "#" at the beginning): | ||
vi /usr/bin/bluez-simple-agent | |||
#import bluezutils | |||
print("RequestConfirmation (%s, %06d)" % (device, passkey)) | |||
#confirm = ask("Confirm passkey (yes/no): ") | def RequestConfirmation(self, device, passkey): | ||
#if (confirm == "yes"): | #print("RequestConfirmation (%s, %06d)" % (device, passkey)) | ||
set_trusted(device) | #confirm = ask("Confirm passkey (yes/no): ") | ||
return | #if (confirm == "yes"): | ||
set_trusted(device) | |||
return | |||
#raise Rejected("Passkey doesn't match") | #raise Rejected("Passkey doesn't match") | ||
And then running the revised agent in the background: | And then running the revised agent in the background, and pair your devices: | ||
bluez-simple-agent & | bluez-simple-agent & | ||
lbu include /usr/bin/bluez-simple-agent | |||
lbu commit | |||
Notes: [https://www.kynetics.com/docs/2018/pairing_agents_bluez/ Pairing Agents in BlueZ stack] | Notes: [https://www.kynetics.com/docs/2018/pairing_agents_bluez/ Pairing Agents in BlueZ stack] | ||
Line 141: | Line 155: | ||
=bluez-alsa= | =bluez-alsa= | ||
At the time of writing this article, bluez-alsa is only found in the community repositories, so you need to edit your repository list: | |||
vi /etc/apk/repositories | vi /etc/apk/repositories | ||
remove the | remove the "#" from the community repository, mine is: | ||
https://uk.alpinelinux.org/alpine/v3.14/community | |||
This is the final stretch. We've got bluetooth working and now we want to link bluetooth to the speakers | This is the final stretch. We've got bluetooth working and now we want to link bluetooth to the speakers | ||
apk add bluez-alsa | apk add bluez-alsa bluez-alsa-utils | ||
bluealsa - | rc-update add bluealsa | ||
rc-service start bluealsa | |||
bluealsa-aplay & | bluealsa-aplay & | ||
[https://github.com/Arkq/bluez-alsa Bluetooth Audio ALSA Backend] | |||
[https://github.com/Arkq/bluez-alsa/tree/master/doc bluez-alsa doc] | |||
[https://manpages.debian.org/unstable/bluez-alsa-utils/bluealsa.8.en.html man bluealsa] | |||
[https://manpages.debian.org/unstable/bluez-alsa-utils/bluealsa-aplay.1.en.html man bluealsa-aplay] | |||
[https://panther.kapsi.fi/posts/2018-11-17_linux_bluetooth_audio Bluetooth audio in Linux: ALSA and LDAC] | |||
=See Also= | =See Also= | ||
Line 180: | Line 183: | ||
* Pimoroni's [https://shop.pimoroni.com/products/audio-amp-shim-3w-mono-amp Audio Amp SHIM (3W Mono Amp)] and [https://shop.pimoroni.com/products/mini-speaker-4-3w Mini Speaker 4Ω (3W)] | * Pimoroni's [https://shop.pimoroni.com/products/audio-amp-shim-3w-mono-amp Audio Amp SHIM (3W Mono Amp)] and [https://shop.pimoroni.com/products/mini-speaker-4-3w Mini Speaker 4Ω (3W)] | ||
* The Pi Hut offers this [https://thepihut.com/products/adafruit-i2s-3w-stereo-speaker-bonnet-for-raspberry-pi Adafruit I2S 3W Stereo Speaker Bonnet for Raspberry Pi (Mini Kit)] and the [https://thepihut.com/products/stereo-enclosed-speaker-set-3w-4-ohm Stereo Enclosed Speaker Set - 3W 4 Ohm] | * The Pi Hut offers this [https://thepihut.com/products/adafruit-i2s-3w-stereo-speaker-bonnet-for-raspberry-pi Adafruit I2S 3W Stereo Speaker Bonnet for Raspberry Pi (Mini Kit)] and the [https://thepihut.com/products/stereo-enclosed-speaker-set-3w-4-ohm Stereo Enclosed Speaker Set - 3W 4 Ohm] | ||
[[Category:ARM]] | |||
[[Category:Raspberry]] | |||
[[Category:Sound]] |
Latest revision as of 13:22, 10 January 2024
How To Build a Raspberry Pi Bluetooth Speaker
This articles describes how to build a Bluetooth speaker. This article is being actively written. Currently it is full of bugs but will provide some useful pointers.
Before You Start
You’ll need:
- A Raspberry Pi
- A Bluetooth USB dongle (if your Pi doesn’t have Bluetooth on board)
- Sound card and speaker(s)
Article Completion
- Test everything
- Turn every background task into a service
- More investigation on Bluetooth pairing
Getting the Speaker(s) Working
To get the best results, you'll need an dedicated audio add-on board and matching speakers. Higher end passive speakers need a proper amplifier (e.g. HiFiBerry Amp2 or IQaudIO IQaudIO DigiAMP+).
I've used the whole range of IQaudio audio boards with different speakers and headphones. I'd also recommend a dedicated USB Bluetooth dongle (don't get the cheapest versions of these). It is possible to test by using the on-board Bluetooth and the on-board audio with headphones but because of dropped packets, the audio quality isn't great.
Once the speakers and audio card are connected to the Raspberry Pi, it's time to install a fresh version of Alpine Linux. The armv7 version from the Downloads page works on almost all Pis. This Wiki has several articles about installing Alpine on a Raspberry Pi.
Enable writing to the boot media:
mount /media/mmcblk0p1 -o rw,remount
Then, either enable the on board sound:
echo "dtparam=audio=on" >> /media/mmcblk0p1/usercfg.txt
or your sound card (e.g. IQaudIO):
echo "dtoverlay=iqaudio-dacplus,unmute_amp" >> /media/mmcblk0p1/usercfg.txt
reboot.
Follow these instructions to enable ALSA. In summary:
apk add alsa-utils alsa-utils-doc alsa-lib alsaconf # the required software for sound aplay -l # should display a List of PLAYBACK Hardware Devices
In my case my list is:
**** List of PLAYBACK Hardware Devices **** card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones] Subdevices: 8/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6
Before you play anything from your speakers, I recommend turnong down the volume.
amixer
displays a list of "simple controls." For my headphones and the on-board sound, the output looks like this:
Simple mixer control 'Headphone',0 Capabilities: pvolume pvolume-joined pswitch pswitch-joined Playback channels: Mono Limits: Playback -10239 - 400 Mono: Playback 0 [96%] [0.00dB] [on]
In this case, there is only 1 control, 'Headphone', so I issue this command to lower the maximum volume to a comfortable level. (50%)
amixer sset Headphone 50%
The IQaudIO DAC that I use has a much larger set of controls. I issued this command to set the volume:
amixer sset 'Digital' 50 # quotes may be required if there are spaces in the control name
Note: there can be several interlinked controls, some of which are muted by defualt. ALSA (and other audio software on Linux) is notoriously under-documented, try `man amixer` for more information. Sometimes it is easier to use a more visual control to change the configuration:
alsamixer
Finally, if you issue this command:
speaker-test -t wav -c 2
Then you should hear "Front Left, Front Right" repeating from your chosen speakers. Now it's time to setup Bluetooth. Don't forget to save your changes (lbu commit).
Bluetooth
I used Raspberry Pi 3 - Setting Up Bluetooth as a reference with some slight modifications as I am using a Pi 4.
Raspberry Pi 4
apk add bluez
btattach -B /dev/ttyAMA0 -P bcm -S 3000000 &
# btattach -B /dev/ttyAMA0 -P bcm -S 115200 -N & # Pi 3 - not tested by me
rc-service bluetooth start
edit /etc/mdev.conf and enable bluetooth. This is done by uncommenting the the line and change the btattach
to work with Pi 4.
Contents of /etc/mdev.conf
Changes to /etc/bluetooth/main.conf
Name = Pi-Bluetooth-Speaker # This is what you'll see when connecting Class = 0x41C # Adding audio playback and recording to this Bluetooth device DiscoverableTimeout = 0 # Always discoverable AlwaysPairable = true # Always pairable PairableTimeout = 0 # no time limit AutoEnable=true # starts Bluetooth when Linux 'sees' the Bluetooth device at boot
Ensure that Bluetooth is started at boot:
rc-update add bluetooth
Bluetooth's state, including paired devices, in held in /var/lib/bluetooth so you'll need to add this to `lbu` state:
lbu include /var/lib/bluetooth lbu commit && reboot
Manual device pairing
bluetoothctl
[bluetooth]# discoverable on [agent] Confirm passkey 627133 (yes/no): yes [agent] Authorize service 0000110e-0000-1000-8000-00805f9b34fb (yes/no): yes
Device pairing:
apk add python3 py3-dbus py3-gobject3
Getting this to work currently involves running the bluez-simple-agent after having edited it to always return sucessful. You'll need to comment out some lines (by adding "#" at the beginning):
vi /usr/bin/bluez-simple-agent
#import bluezutils
def RequestConfirmation(self, device, passkey): #print("RequestConfirmation (%s, %06d)" % (device, passkey)) #confirm = ask("Confirm passkey (yes/no): ") #if (confirm == "yes"): set_trusted(device) return #raise Rejected("Passkey doesn't match")
And then running the revised agent in the background, and pair your devices:
bluez-simple-agent & lbu include /usr/bin/bluez-simple-agent lbu commit
Notes: Pairing Agents in BlueZ stack Since Bluez 5.48, iPhones require pairing when connecting on a BLE GAP peripheral, why? Headless A2DP Audio Streaming on Raspbian Stretch
bluez-alsa
At the time of writing this article, bluez-alsa is only found in the community repositories, so you need to edit your repository list:
vi /etc/apk/repositories
remove the "#" from the community repository, mine is:
https://uk.alpinelinux.org/alpine/v3.14/community
This is the final stretch. We've got bluetooth working and now we want to link bluetooth to the speakers
apk add bluez-alsa bluez-alsa-utils rc-update add bluealsa rc-service start bluealsa bluealsa-aplay &
Bluetooth Audio ALSA Backend bluez-alsa doc man bluealsa man bluealsa-aplay Bluetooth audio in Linux: ALSA and LDAC
See Also
Raspberry Pi's blog on How to play sound and make noise with your Raspberry P
There are lots of speaker and amplifier options:
- Raspberry Pi's IQaudIO boards
- Pimoroni's Audio Amp SHIM (3W Mono Amp) and Mini Speaker 4Ω (3W)
- The Pi Hut offers this Adafruit I2S 3W Stereo Speaker Bonnet for Raspberry Pi (Mini Kit) and the Stereo Enclosed Speaker Set - 3W 4 Ohm