Raspberry Pi Bluetooth Speaker

=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 # 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 
 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 and enable bluetooth. This is done by uncommenting the the line and change the btattach to work with Pi 4.
Changes to 
 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 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 
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
Category:ARM
Category:Raspberry
Category:Sound