Raspberry Pi Bluetooth Speaker: Difference between revisions

From Alpine Linux
(How to make a Raspberry Pi Bluetooth speaker)
 
m (→‎Bluetooth: Use more pkg template.)
 
(39 intermediate revisions by 7 users not shown)
Line 1: Line 1:
=How To Build a 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.
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=
=Before You Start=
Line 7: Line 7:
* A Raspberry Pi
* A Raspberry Pi
* 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)
* A speaker
* Sound card and speaker(s)
* Optionally, a sound card


=Doing Something Title=
=Article Completion=
Write the steps of how to do something in this section.
# Test everything
If possible, show an example first, then tell your readers the steps.
# Turn every background task into a service
Break this procedure into separate procedures to avoid more than
# More investigation on Bluetooth pairing
about 7-9 steps per procedure.


INSERT GREAT EXAMPLE HERE
=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+).


#Answer the following three questions, at least in your head.
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.
##What do I explain how to do?
 
##How do I do that?
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.
##What do HOWTO readers already know about doing that?
 
#Write up a good example. This ensures you can do it.
Enable writing to the boot media:
#Write up the steps to do it.
 
#Write the background info/prerequisites readers need.
  mount /media/mmcblk0p1 -o rw,remount
#Write the summary.
 
#Clean up your work.
Then, either enable the on board sound:
#Revise, revise, revise.
 
  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 [[ALSA|these instructions]] to enable ALSA. In summary:
 
  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
 
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|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 {{pkg|bluez|arch=a*}}
  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 {{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:
 
  rc-update add bluetooth
 
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 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 {{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. 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: [https://www.kynetics.com/docs/2018/pairing_agents_bluez/ Pairing Agents in BlueZ stack]
[https://stackoverflow.com/questions/59214524/since-bluez-5-48-iphones-require-pairing-when-connecting-on-a-ble-gap-periphera Since Bluez 5.48, iPhones require pairing when connecting on a BLE GAP peripheral, why?]
[https://gist.github.com/mill1000/74c7473ee3b4a5b13f6325e9994ff84c 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 &
 
[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=
If you ought to point your readers to related information
Raspberry Pi's blog on [https://www.raspberrypi.org/blog/how-to-play-sound-and-make-noise-with-your-raspberry-pi/ How to play sound and make noise with your Raspberry P]
they no doubt need but that does not fit in your HOWTO, add links here.
 
There are lots of speaker and amplifier options:
* Raspberry Pi's [https://www.raspberrypi.org/blog/iqaudio-is-now-raspberry-pi/ IQaudIO boards]
* 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]
 
[[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

  1. Test everything
  2. Turn every background task into a service
  3. 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

... # rpi bluetooth ttyAMA0 root:tty 660 @btattach -B /dev/ttyAMA0 -P bcm -S 3000000 & ...

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: