BaReinhard / Super-Simple-Raspberry-Pi-Audio-Receiver-Install

Super Easy installation to make your Raspberry Pi an Audio Receiver
GNU Affero General Public License v3.0
491 stars 88 forks source link

No sound due to bluetooth device not showing up in /sys/devices/virtual/input/ #101

Open gith-account opened 6 years ago

gith-account commented 6 years ago

Hi,

I have a bluetooth audio transmitter which connects to the Raspberry Pi fine but does not show up in /sys/devices/virtual/input/. Therefore, the condition of the udev rule "KERNEL=="input[0-9]*", RUN+="/usr/local/bin/bluez-udev" is not met, bluez-udev not executed and the bluetooth source ultimately not linked to the audio output sink.

I can link the source to the sink manually:

$ sudo pactl load-module module-loopback source=bluez_source.XX_XX_XX_XX_XX_XX sink=alsa_output.1.analog-stereo

and get all the required information to do that, though:

$ sudo pactl list cards

Card #1
    Name: bluez_card.XX_XX_XX_XX_XX_XX
    Driver: module-bluez5-device.c
    Owner Module: 01
    Properties:
        device.description = "Transmitter"
    device.string = "XX:XX:XX:XX:XX:XX"
    device.api = "bluez"
    device.class = "sound"
    device.bus = "bluetooth"
    device.form_factor = "hifi"
    bluez.path = "/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX"
    bluez.class = "0x080428"
    bluez.alias = "Transmitter"
    device.icon_name = "audio-card-bluetooth"
Profiles:
    a2dp_source: High Fidelity Capture (A2DP Source) (sinks: 0, sources: 1, priority: 10, available: yes)
    off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: a2dp_source
Ports:
    hifi-output: HiFi (priority: 0, latency offset: 0 usec, not available)
    hifi-input: HiFi (priority: 0, latency offset: 0 usec)
        Part of profile(s): a2dp_source

$ sudo pactl list sources short

0   alsa_output.1.analog-stereo.monitor module-alsa-sink.c  s16le 2ch 44100Hz   SUSPENDED
1   alsa_input.1.analog-mono    module-alsa-source.c    s16le 1ch 44100Hz   SUSPENDED
4   bluez_source.XX_XX_XX_XX_XX_XX  module-bluez5-device.c  s16le 2ch 48000Hz   SUSPENDED

$ sudo pactl list sinks short

0   alsa_output.1.analog-stereo module-alsa-sink.c  s16le 2ch 44100Hz   SUSPENDED

Has anyone else experienced something like this? Any elegant way to trigger the execution of bluez-udev and pass the name of the source with this device?

BaReinhard commented 6 years ago

How is this Bluetooth card connected? Via Bluetooth as well? What is the product name and do you have a link to it? I’d like to possibly get my hands on one to debug.

gith-account commented 6 years ago

The bluetooth audio transmitter is this one: https://feintech.eu/feinbeam-txrx-bluetooth-sender-empfaenger

Possibly a rebranded Taotronics TT-BA08: https://www.taotronics.com/taotronics-tt-ba08-bluetooth-4.1-transmitter-receiver-aptX-music-adapter-b.html

The transmitter is connected to the Raspberry Pi via bluetooth and works fine except for the fact that it does not show up in /sys/devices/virtual/input/ and thus fails to trigger the execution of bluez-udev.

audio source > [3.5mm jack] > bluetooth transmitter > [bluetooth] > Raspberry Pi > [USB] -> soundcard > [3.5mm jack] > amplifier/speakers

BaReinhard commented 6 years ago

Hmm, interesting I haven't ever used a transmitter, only a receiver. I'd have to look more into this, never had experience with issues triggering the udev rule.

BaReinhard commented 6 years ago

You can try running Raspbian Stretch, and look at issue #102 . It's possible that the newer OS has fixed some of these issues. However, I do believe that this is a hardware issue, as I haven't had a problem with Android or iOS bluetooth transmitters.

gith-account commented 6 years ago

By listening to the kernel uevents

$ sudo udevadm monitor --udev

UDEV  [1034.558162] add      /devices/platform/soc/20980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/bluetooth/hci0/hci0:72 (bluetooth)

UDEV  [1034.558162] add      /devices/platform/soc/20980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/bluetooth/hci0/hci0:72 (bluetooth)

I figured out that I can create a working udev rule for the transmitter:

SUBSYSTEM=="bluetooth", GROUP="bluetooth", MODE="0660"
KERNEL=="hci0:[0-9]*", RUN+="/usr/local/bin/bluez-udev"

However, the way $name and $bt_name are determined in /usr/local/bin/bluez-udev does not work with the transmitter.

I can get the transmitter's MAC address like this, though:

$ sudo pactl list cards | grep -o 'Name:.*' | cut -d '.' -f2

So I pointed the udev rule to a slightly modified bluez-udev-hci for testing purposes

SUBSYSTEM=="bluetooth", GROUP="bluetooth", MODE="0660"
KERNEL=="hci0:[0-9]*", RUN+="/usr/local/bin/bluez-udev-hci"

and gave it a try:

#!/bin/bash
audio_sink=0
name=$(pactl list cards | grep -o 'Name:.*' | cut -d '.' -f2)

#exit if not a BT address
if [[ ! $name =~ ^([0-9A-F]{2}[_:-]){5}([0-9A-F]{2})$ ]]; then exit 0;  fi

#bt_name=`grep Name /var/lib/bluetooth/*/$name/info | awk -F'=' '{print $2}'`

#sudo pkill arecord     # Uncomment for Audio Line Input
audio_source=bluez_source.$(sed 's/:/_/g' <<< $name)

action=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
logger "Action: $action"
if [ "$action" = "add" ]; then
    logger "[$(basename $0)] Bluetooth device is being added [$name]"
    logger "[$(basename $0)] Patching $audio_source into ALSA sink #$audio_sink"
    #hciconfig hci0 noscan
    bluetoothctl << EOT
discoverable off
EOT
    amixer cset numid=3 1
    amixer cset numid=3 50%
    #espeak -s 160 -k 1 "Device, $name Connected"
    /usr/local/bin/say.sh "Device, $name Connected"
    amixer cset numid=3 90%
    sleep 1
    pactl set-sink-volume 0 65537
    pactl set-source-volume $audio_source 90%

    # loop back this source to the default sink
    handle=$(pactl load-module module-loopback source=$audio_source sink=$audio_sink)
    logger "[$(basename $0)] PulseAudio module-loopback returned handle [$handle]"
    logger "$name"

fi
if [ "$action" = "remove" ]; then
    logger "[$(basename $0)] Bluetooth device is being removed [$name]"
    #hciconfig hci0 pscan
    bluetoothctl << EOT
discoverable on
EOT
    # remove any loopback modules assigned to this source
    # only required for USB sound cards, which PulseAudio will not automatically remove
    for handle in $(pactl list short modules | grep module-loopback | grep source=$audio_source | cut -f 1); do
        logger "[$(basename $0)] Unloading module-loopback with handle [$handle]"
        pactl unload-module $handle
    done

    #arecord -D plughw:1 -f dat | aplay -D plughw:1 -f dat&     # Uncomment for Audio Line Input
    sleep 5
    amixer cset numid=3 80%
    #espeak -s 160 -k 1 "Device, $name Disconnected"
    /usr/local/bin/say.sh "Device, $name Disconnected"
    amixer cset numid=3 80%
fi

But the script fails. The name variable remains empty. This does not seem to work:

name=$(pactl list cards | grep -o 'Name:.*' | cut -d '.' -f2)

When I hardcode the transmitters MAC address into the script it runs fine:

name="XX_XX_XX_XX_XX_XX"

I tried different things (e.g., make udev run the script as user pulse or pi) to no avail and ultimately fail to understand why the code line to retrieve the MAC address does not work when the script is executed by udev. Later in the script there are similar invocations of pactl that seem to cause no trouble:

handle=$(pactl load-module module-loopback source=$audio_source sink=$audio_sink)
...
for handle in $(pactl list short modules | grep module-loopback | grep source=$audio_source  | cut -f 1); do
...

Any ideas?

JeremyIglehart commented 6 years ago

@gith-account Thank you so much for your post - you helped me get to where I needed to be.

I can see that this doesn't really address the issue you're working on. I actually like where you were going with this better. Let me see if I can work with your script a little.

If the command sudo pactl list sources short gives me this:

$ sudo pactl list sources short
1   alsa_output.platform-soc_sound.analog-stereo.monitor    module-alsa-card.c  s16le 2ch 44100Hz   IDLE
2   bluez_source.XX_XX_XX_XX_XX_XX.a2dp_source  module-bluez5-device.c  s16le 2ch 44100Hz   RUNNING

And sudo pactl list sinks short gives me:

$ sudo pactl list sinks short
1   alsa_output.platform-soc_sound.analog-stereo    module-alsa-card.c  s16le 2ch 44100Hz   SUSPENDED

I just used awk to solve my problem:

sudo pactl load-module module-loopback source=$(sudo pactl list sources short | awk 'NR==2 {print $2}') sink=$(sudo pactl list sinks short | awk '{print $2}')

(Keep in mind, before this was working some of the I had a different status, not IDLE and RUNNING but SUSPENDED and IDLE I think - anyways, this works for me now.)

I'm not sure if the order of this will ever change. And how to get this to happen automatically is beyond me at this point. But at least I can make it happen :)

Hope this helps maybe somebody out there.

Thanks, Jeremy

JeremyIglehart commented 6 years ago

I FINALLY FOUND THE ANSWER FOR MY PROBLEM!!!!

For some reason my bluetooth wasn't automatically connecting. Now it's working. All I have to do is run:

sudo nano /etc/pulse/system.pa
load-module module-bluetooth-policy

at the end of that file.

Found the answer here: https://www.raspberrypi.org/forums/viewtopic.php?t=161770#p1049111

BaReinhard commented 6 years ago

@JeremyIglehart glad you found the solution! I thought I had loaded bluetooth policy module in system.pa, but that could have been for another project.

@gith-account I recall having a similar issue a while back but can't seem to remember what I did differently. I am unsure if it was even for this project or using ubuntu-mate. You may have to find another way to parse the MAC address.

I believe I solved it in a somewhat hacky way since I only have 1 bt device connected at any given time I looked in the /var/lib/bluetooth/ dir for MAC address and used that for the name. However, this may cause issues when you have, say a bt kb connected. I am unsure if past connected devices will still show up here or not, but you could always clear the dir on connection end as well.

Lauszus commented 6 years ago

The fix in https://github.com/BaReinhard/Super-Simple-Raspberry-Pi-Audio-Receiver-Install/issues/101#issuecomment-366551115 worked for me as well. I'm using a Pi Zero W running Stretch.