TTS on Bluetooth speaker via Raspberry Pi

@santirguez I tried last night using a little Bluetooth receiver and also noticed there was about half a second of audio missing at the very beginning. I checked the actual MP3 file and it was fine. Looks like different Bluetooth devices have different behaviours.

How did you insert the silence at the start of the TTS?

@pkozul what I did first is generate a 2 seconds silence file with sox:
sox -n -r 44100 -c 2 silence.wav trim 0.0 2.0

Then in tts_bluetooth_speaker.py, I added in play_media method:

command_silence = "mplayer -ao pulse::bluez_sink.DEVICE_ID -volume 50 DIR/TO/FILE/silence.wav"
and called it just before the ā€œrealā€ command
subprocess.call(command_silence, shell=True)
I know It is quite rudimentary, but for me is working :slight_smile:

@santirguez Good workaround. I will try that too. Might have to add an option to the config so that we can specify the duration of the ā€˜silenceā€™. That way, no need to hard code it. Yeah, bit of a hack, but itā€™s something with Bluetooth that isnā€™t even related to HA. BTW, I tried playing the TTS file on the command line using mplayer, and the same problem - first part of the audio is never played.

I gave this a shot with my echo tonight. I did manage to get it to work with a few hiccups along the way.

  1. I donā€™t use bluetooth tracker, so some of your imports were throwing it off. I submitted a PR here:
    https://github.com/pkozul/ha-tts-bluetooth-speaker/pull/1

  2. I was missing a2dp FW for my BT adapter
    bluetooth hci0: Direct firmware load for brcm/BCM20702A1-0a5c-21e8.hcd failed with error -2
    Which I had to google for to get A2DP to work.

  3. The default profile is ā€œnoneā€, so I had to in /etc/pulse/default.pa set up default profile to a2dp using https://askubuntu.com/questions/69820/how-do-i-set-a-pulseaudio-card-profile-persistently-across-reboots in order to get a sink to show up.

  4. Randomly seems to disconnect from my echo, not really sure why yet. It might be useful to check if connected and if not run a connect from bluetoothctl.

Iā€™m trying to set this up, but having problems.
Iā€™ve gone through the instructions on GitHub to the letter (a few times), but media_player.tts_bluetooth_speaker isnā€™t showing up in Home Assistant under ā€˜Current Entitiesā€™.

Iā€™m able to play a test MP3 file from the Raspberry Pi to the Bluetooth speaker. Also, when Home Assistant starts my speaker says ā€˜pairedā€™, and when I restart the Raspberry Pi/Home Assistant my Bluetooth speaker says ā€˜disconnectedā€™.
So it looks like the connection between the Raspberry Pi and my Bluetooth speaker is working OK.

I placed ā€˜tts_bluetooth_speaker.pyā€™ at

/home/homeassistant/.homeassistant/custom_components/media_player/tts_bluetooth_speaker.py

And hereā€™s the code in Home Assistant:

- platform: tts_bluetooth_speaker
  address: 30:21:5C:69:1D:76
  volume: 0.50

Is there anything else I can try or check to make Home Assistant see my bluetooth speaker as a media player?

@jono. Hi there. What you have appears OK. Does anything show up in the HA logs?

You can check the log file for using this command (in your HA directory):

grep tts_bluetooth home-assistant.log

Below is what mine shows.

2017-07-14 13:10:19 INFO (MainThread) [homeassistant.loader] Loaded media_player.tts_bluetooth_speaker from custom_components.media_player.tts_bluetooth_speaker
2017-07-14 13:10:20 INFO (MainThread) [homeassistant.components.media_player] Setting up media_player.tts_bluetooth_speaker

This is how is added my Bluetooth speaker:

media_player: 
  - platform: tts_bluetooth_speaker
    name: Thompson
    address: 20:15:05:15:77:F5
    volume: 1.0

And this is how it appears in HA:

Thanks for the help. This is the output of the log:

2017-07-14 12:42:46 ERROR (MainThread) [homeassistant.loader] Error loading custom_components.media_player.tts_bluetooth_speaker. Make sure all dependencies are installed
  File "/home/homeassistant/.homeassistant/custom_components/media_player/tts_bluetooth_speaker.py", line 16, in <module>
2017-07-14 12:42:46 ERROR (MainThread) [homeassistant.loader] Unable to find component media_player.tts_bluetooth_speaker

Looking at line 16 of tts_bluetooth_speaker.py says:

from ..device_tracker import bluetooth_tracker


I hadnā€™t added that file as I wasnā€™t wanting to use device tracker for this (I didnā€™t realise adding this was required). I added the file and itā€™s now working :slight_smile:

When I test it in Developer Tools > Services it sort of works, but the first part of the word is cut off. Instead of saying ā€˜Helloā€™ it says ā€˜loā€™

Yep, this was reported earlier in the thread. There is a way to insert a bit of silence before the actual audio. Try that and see if it helps.

I donā€™t believe this is a problem with HA. Even on the command line I noticed that the first part of the file was not being played.

Thanks, just looking at that.

Iā€™ve created the ā€˜silence.wavā€™ file, but I donā€™t fully understand how to the change the code in ā€˜tts_bluetooth_speaker.pyā€™ from the post above :grin:


And chance of showing the code I can paste into the file?
Iā€™ve placed the .wav file in

/home/homeassistant/.homeassistant/custom_components/media_player/

Hi @jono. Working on a newer version that will contain this. Will keep you postedā€¦

1 Like

Ah, great. Thanks!

@jono Can you try the latest file from GitHub?

custom_components/media_player/tts_bluetooth_speaker.py

All you need to do then in your media player config is specify the duration of silence you want before and/or after the ā€˜realā€™ audio. These new options pre_silence_duration and post_silence_duration are optional (obviously they default to 0 otherwise).

  - platform: tts_bluetooth_speaker
    name: Thompson
    address: 20:15:05:15:77:F5
    volume: 1.0
    pre_silence_duration: 1       # No. of seconds of silence before the TTS (default = 0)
    post_silence_duration: 0.5    # No. of seconds of silence before the TTS (default = 0)

Let me know how it goes.

Regarding the Bluetooth speakers that skip the first second or two of audioā€¦

In my code from earlier today, I used sox and its pad option to add some silence (padding) to the start of the file, and/or end of the file (depending on whether you enable these options).

When I downloaded the resulting MP3 file to my laptop, it played fine and the padded silence was in there. But on the Raspberry Pi, there was still some missing audio at the beginning of the file when played back. My only guess is that my Bluetooth speaker only starts producing sound after it detects some real noise (i.e. something audible), regardless of the inserted silence that precedes it. By the time the Bluetooth speaker wakes up, the first second of ā€˜realā€™ audio is missed.

So, with the latest version, I am using a different technique. Instead of using pad, the code now uses synth brownnoise to insert some hissy noise, which is at such a low volume that I cannot even hear it (uses a gain of -50). This has made a difference. That low level hiss causes my Bluetooth speaker to wake up immediately, and so when the ā€˜realā€™ audio kicks in about a second later, it plays fine, in all its entirety.

Let me know if you try this latest version, and if it does the job OK.

3 Likes

Creative workaround, bud.

Iā€™ve been testing this for the last hour or so, but still having problems.

If I add the lines to the code to add the silence the messages sent through TTS to my bluetooth speaker donā€™t work at all, and sometimes show errors in Home Assistant depending on what I add for the duration.

If I add 1 second then tts doesnā€™t work at all through the bluetooth speaker

pre_silence_duration: 1


If I add 1.5 then tts doesn't work at all and it shows this error in Home Assistant

pre_silence_duration: 1.5


(Same if I add post silence)

post_silence_duration: 0.5


If I remove the code to add silence then the sound works, but it still cut off of course.

Hereā€™s my current config:

- platform: tts_bluetooth_speaker
  name: "Silver Bluetooth Speaker"
  address: 30:21:5C:69:1D:76
  volume: 0.5
  pre_silence_duration: 1.5
  post_silence_duration: 0.5

@jono OK issue has been fixed. I forgot to change the allowable range for the new options. The options now support anywhere from 0 to 60 seconds.

Also, make sure you have these two apps installed:

sudo apt-get install sox libsox-fmt-mp3
1 Like

Thatā€™s it, that works fine now! :+1:
Thanks a lot!

1 Like

@jono Great to hear. I have updated the doco to ensure that installing SoX is mentioned in the first step of the getting started guide.

BTW, how many seconds of pre-silence have you configured for your speaker? Can you hear the brown noise before the ā€˜realā€™ audio starts to play?

Iā€™ve done a few tests with the amount of silence added.

Iā€™m currently using 0.5 secs pre-silence and no post-slience, and itā€™s now working perfectly. And no, I canā€™t hear any ā€˜brown noiseā€™

Great, I think these settings will be different for various Bluetooth devices.

In my case, this seems to work:

    pre_silence_duration: 0.1
    post_silence_duration: 0.1

Good thing is people can tweak it until they find what works.