I've been experimenting with bluetooth and squeezelite on Alpine Linux.
I'm going to use this thread to document my misadventures. My initial
goal was to take the Wyse 3030LT (N06D) pictured and have the onboard
audio jack at the front, the Apple USB DAC at the rear, and bluetooth
headphones all playing the same audio from squeezelite.  Further, I
wanted to be able to pair my phone and play audio from the phone source
(eg. Amazon Prime Music) over the same outputs without interfering with
squeezelite.

I was able to accomplish that so I will document what I have so far in
case it's of any interest. This may already be well documented here on
the forum but I haven't really looked, so forgive me if this is all
repeated info.

I tried many different variations of the alsa /etc/asound.conf some
worked, some didn't. The one I have below will likely change, I'm not
really convinced yet of the right approach to take. I know pCP is
supporting bluetooth now and I've read the main thread on it but I
haven't installed it or looked at any of the scripts to see how they are
handling it. It would be cool to get some feedback from Paul and team on
that, or feedback in general from anyone! I had a asound.conf that
didn't use the Loopback device at all but something was telling me I
needed to feed everything through the loopback and have a separate
alsaloop process for each device. As I said above, not convinced this is
the way to go. I also had a sort of working solution with two local
squeezebox processes in a sync group but that felt pretty ugly and I
ditched it fairly quickly.

The basic idea here is that the default playback device is the Loopback
and stereo audio is duplicated across multiple Loopback channels. Each
alsaloop instance gets the same audio from a different Loopback output
and feeds a different hardware output. The bt-pair.sh script is my
clunky solution to managing pairing of new devices though still very
much a work in progress. The script uses a LMS response on the status of
the local squeezelite player and greps for certain words to decide
whether to kick off the pairing process or exit. So to initiate, you
select your player in LMS and play a track I added to the library that
has "bluetooth-player" in the track name. Then you power off the player
from LMS, which fires the script and both criteria are met: the correct
track title and power state, then you pair from the phone.

I'm going to skip all the standard Alpine setup steps I take and just
focus on the squeezelite/bluetooth/alsa stuff.  I added the following
packages:

alsa-utils
bluez-alsa
squeezelite

linux-lts-5.4.49-r0.apk
- I had to rebuild the kernel to enable the snd-aloop module.  This
should be enabled in future stock Alpine kernels, see:
https://gitlab.alpinelinux.org/alpine/aports/-/issues/11699

Configure things to run at boot:

rc-update add squeezelite
rc-update add alsa 
rc-update add bluealsa
rc-update add local

I'm using the following squeezelite options set in
/etc/conf.d/squeezelite:

Code:
--------------------
    SL_OPTS="-n Desk -S /home/sodface/bt-pair.sh"
--------------------


More on the -S option later:

Code:
--------------------
    -S <Power Script>   Absolute path to script to launch on power commands 
from LMS
--------------------


Added the following line to the /etc/init.d/bluealsa startup script:

Code:
--------------------
    
  command_args="-S -p a2dp-source -p a2dp-sink"
  
--------------------


Using the following settings in /etc/bluetooth/main.conf

Code:
--------------------
    
  Name = Desk
  AlwaysPairable = true
  AutoEnable = true
  
--------------------


Added snd-aloop to /etc/modules:

Code:
--------------------
    
  af_packet
  ipv6
  snd-aloop
  
--------------------


Created a local startup script in /etc/local.d/ with the following
commands:

Code:
--------------------
    
  bluetoothctl discoverable off
  bluealsa-aplay 00:00:00:00:00:00 &
  alsaloop -C hw:Loopback,1,0 -P hw:A,0 -t 500000 &
  alsaloop -C hw:Loopback,1,1 -P hw:PCH,0 -t 500000 &
  alsaloop -C hw:Loopback,1,2 -P "btheadset" -t 1100000 &
  
--------------------


Contents of /etc/asound.conf

Code:
--------------------
    
  pcm.!default plug:aloopx
  
  ctl.!default {
  type hw
  card PCH 
  }
  
  pcm.aloopx {
  type route;
  slave.pcm {
  type multi;
  slaves.a.pcm "aloop0";
  slaves.b.pcm "aloop1";
  slaves.c.pcm "aloop2";
  slaves.d.pcm "aloop3";
  slaves.a.channels 2;
  slaves.b.channels 2;
  slaves.c.channels 2;
  slaves.d.channels 2;
  bindings.0.slave a;
  bindings.0.channel 0;
  bindings.1.slave a;
  bindings.1.channel 1;
  
  bindings.2.slave b;
  bindings.2.channel 0;
  bindings.3.slave b;
  bindings.3.channel 1;
  
  bindings.4.slave c;  
  bindings.4.channel 0;
  bindings.5.slave c;  
  bindings.5.channel 1;
  
  bindings.6.slave d;
  bindings.6.channel 0;
  bindings.7.slave d;
  bindings.7.channel 1;
  }
  
  ttable.0.0 1;
  ttable.1.1 1;
  
  ttable.0.2 1;
  ttable.1.3 1;
  
  ttable.0.4 1;
  ttable.1.5 1;
  
  ttable.0.6 1;
  ttable.1.7 1;
  }
  
  pcm.aloop0 {
  type dmix
  ipc_key 1024
  slave {
  pcm "hw:Loopback,0,0"
  period_time 0
  period_size 2048
  buffer_size 65536
  buffer_time 0
  periods 128
  rate 48000
  channels 2
  }
  bindings {
  0 0
  1 1
  }
  }
  
  pcm.aloop1 {
  type dmix
  ipc_key 2048
  slave {
  pcm "hw:Loopback,0,1"
  period_time 0
  period_size 2048
  buffer_size 65536
  buffer_time 0
  periods 128
  rate 48000
  channels 2
  }
  bindings {
  0 0
  1 1
  }
  }
  
  pcm.aloop2 {                 
  type dmix                 
  ipc_key 4096              
  slave {                   
  pcm "hw:Loopback,0,2"          
  period_time 0         
  period_size 2048       
  buffer_size 65536   
  buffer_time 0       
  periods 128         
  rate 48000          
  channels 2          
  }                      
  bindings {             
  0 0
  1 1
  }                      
  }
  
  pcm.aloop3 {                 
  type dmix                 
  ipc_key 8092              
  slave {                   
  pcm "hw:Loopback,0,3" 
  period_time 0        
  period_size 2048     
  buffer_size 65536    
  buffer_time 0        
  periods 128          
  rate 48000           
  channels 2           
  }                       
  bindings {              
  0 0                  
  1 1                  
  }                       
  }
  
  # Bluetooth headset
  pcm.btheadset {
  type plug 
  slave.pcm {
  type bluealsa
  device "20:9B:A5:5B:B7:A9"
  profile "a2dp"
  }
  hint {
  show on
  description "VMODA Crossfade Bluetooth Headset"
  }
  }
  
  ctl.aloopx {
  type hw
  card "Loopback"
  }
  
--------------------


Contents of the bt-pair.sh script that is fired on squeezelite power
on/off commands:


Code:
--------------------
    
  #!/bin/sh
  
  uptime=$(cat /proc/uptime | cut -d'.' -f1)
  
  if [ ${uptime} -le 60 ]
  then
  exit
  fi
  
  lmsip=$(netstat -tn | grep 3483 | tr -s ' ' | cut -d ' ' -f5 | cut -d ':' -f1)
  iface=$(arp -an | grep ${lmsip} | tr -s ' ' | cut -d' ' -f7)
  read mac < /sys/class/net/${iface}/address
  btplayer="bluetooth-player"
  
  post=$(cat <<END_HEREDOC
  POST /jsonrpc.js HTTP/1.1
  HOST: ${lmsip}:9000
  Content-Type: application/json; charset=utf-8
  Content-Length: 97
  
  
{"id":1,"method":"slim.request","params":["${mac}",["status","-","1","tags:acgltys"]]}
  END_HEREDOC
  )
  
  if ! (echo -e "${post}"; sleep .2) | nc ${lmsip} 9000 | grep "${btplayer}" | 
grep -q '"power":0'
  then
  exit
  fi
  
  i=0
  
  bluetoothctl discoverable on
  
  while [ $i -le 30 ]
  do
  prepair=$(bluetoothctl paired-devices | cut -d' ' -f2)
  sleep 2
  newpair=$(bluetoothctl paired-devices | cut -d' ' -f2)
  newdev=$(printf "${prepair}\n${newpair}\n" | sort | uniq -u)
  if [ "${newdev}" ]
  then
  echo "${newdev}"
  bluetoothctl trust ${newdev}
  bluetoothctl connect ${newdev}
  break
  else
  i=$(( $i +1 ))
  fi
  done
  
  bluetoothctl discoverable off
  
--------------------


+-------------------------------------------------------------------+
|Filename: IMG_20200630_163325891-rs.jpg                            |
|Download: http://forums.slimdevices.com/attachment.php?attachmentid=30926|
+-------------------------------------------------------------------+

------------------------------------------------------------------------
sodface's Profile: http://forums.slimdevices.com/member.php?userid=19057
View this thread: http://forums.slimdevices.com/showthread.php?t=112536

_______________________________________________
unix mailing list
unix@lists.slimdevices.com
http://lists.slimdevices.com/mailman/listinfo/unix

Reply via email to