Year of the Voice - Chapter 4: Wake words

Wake word being detected and sound playin from the speaker.
How do I activate an LED for the start event and switch it off once its done.
Visual indication that the wakeword was detected and not just sound.
Also, what event to use to switch and led on while piper is speaking?
Thanks

1 Like

I’ve tested openwakeword with both the Jabra 410 speakerphone and the Avaya B109 attached to the RPi4. Both appear to work well.

1 Like

I had… but I noticed, it was somehow random…

Sometimes, the external ressource could not be loaded during the compilation - and then I got errors.
When I tried it again, after a few minutes, it was working well…

Yep, I tried again a few days later and all went smoothly. Odd.

Also, your error shows an issue with strapping pins.
I remember, that I read something about this in one of the release notes recently…

I just looked at that PR which states that GPIO4 should actually be 5, but GPIO4 or GPIO5 aren’t used in the config for the ESP-box so I don’t know why it would throw that error, unless the code has been updated to remove either of those.

You can try this:

esphome:
  name: esp32-voice
  friendly_name: esp32-voice
  on_boot:
     - priority: -100
       then:
         - wait_until: api.connected
         - delay: 1s
         - if:
             condition:
               switch.is_on: use_wake_word
             then:
               - voice_assistant.start_continuous:

esp32:
  board: lolin32_lite
  framework:
    type: esp-idf
    version: recommended

# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Mic-Speaker"
    password: "9vYvAFzzPjuc"

i2s_audio:
  i2s_lrclk_pin: GPIO2
  i2s_bclk_pin: GPIO14

microphone:
  - platform: i2s_audio
    id: mic
    adc_type: external
    i2s_din_pin: GPIO15
    pdm: false

speaker:
  - platform: i2s_audio
    id: big_speaker
    dac_type: external
    i2s_dout_pin: GPIO25
    mode: mono

voice_assistant:
  microphone: mic
  use_wake_word: false
  noise_suppression_level: 2
  auto_gain: 31dBFS
  volume_multiplier: 2.0
  speaker: big_speaker
  id: assist

switch:
  - platform: template
    name: Use wake word
    id: use_wake_word
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    entity_category: config
    on_turn_on:
      - lambda: id(assist).set_use_wake_word(true);
      - if:
          condition:
            not:
              - voice_assistant.is_running
          then:
            - voice_assistant.start_continuous
    on_turn_off:
      - voice_assistant.stop
      - lambda: id(assist).set_use_wake_word(false);
1 Like

I currently have a wake word in training which you might be interested in. It’ll be in my fork of the wake work repo ready for a PR to the main repo once it completes.

Give my a little while for the file to be in that folder :slight_smile:

4 Likes

For the possibility of a Raspberry Pi satellite, it is also possible for a Raspberry Pi Zero 2 W
Or is it possible to only have Raspberry Pi 4?

Hi Don,

May I ask how did you get your raspberry Pi to integrate with Home Assistant, I have followed Synesthesiam GIT instructions (GitHub - synesthesiam/homeassistant-satellite: Streaming audio satellite for Home Assistant) , but it don’t seem to be connected to home assistant after creating the token and then run the script as settings in Voice Assistant (select pipeline, and debug) - Run Audio with Wake Word Detection is still greyed out - so what makes the connection, adding this as a device in home assistant is not an option?

Thanks in advance.

I have a few windows laptops spread around the house for viewing security camera feeds. Anyway I can use laptop mic/speaker as voice satellites?

Good day.
In this chapter it is written that it is possible to create voice satellites using the RPi.
I just bought a new ZERO 2W and I’m looking for a procedure to turn it into a satellite.
I run HA on RPi4 with SSD and hassos.
I found a link here in the chapter GitHub - synesthesiam/homeassistant-satellite: Streaming audio satellite for Home Assistant.
Unfortunately, I don’t know how to use it.
Would someone please be patient enough to help me turn the RPi Zero into a 2W satellite for my HA on the RPi4, or please provide a link to a step-by-step tutorial.

Many thanks in advance to anyone who lends a helping hand.
J.

The git hub is here for a test you just install and play with the test code.

GitHub - dscripka/openWakeWord: An open-source audio wake word (or phrase) detection framework with a focus on performance and simplicity. as its a pretty simple bit of Python.
I am not sure though if it runs on a Pi3 or its derivative Zero2, due to load though.
Would be good for someone to test.

You can the pip package sounddevice as

def sd_callback(rec, frames, time, status):
   frame = rec

   # Get predictions for the frame
   prediction = model.predict(frame)

# Start streaming from microphone
with sd.InputStream(channels=num_channels,
                    samplerate=sample_rate,
                    blocksize=int(sample_rate * rec_duration),
                    callback=sd_callback):
    threading.Event().wait()

A bit simplistic but gives you the base if you can hack a bit of Python code
I am just having a look myself and you can use https://github.com/dscripka/openWakeWord/blob/main/examples/detect_from_microphone.py

HI !

Just use changing state for porcupine1, openwakeword or snowboy

Tried it on a Pi Zero2 and works well with minimal load.

I couldn’t get the example to run and swapped to a callback with sounddevice code hack here.

# Copyright 2022 David Scripka. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Imports
import sounddevice as sd
import numpy as np
from openwakeword.model import Model
import argparse
import threading

# Parse input arguments
parser=argparse.ArgumentParser()
parser.add_argument(
    "--chunk_size",
    help="How much audio (in number of samples) to predict on at once",
    type=int,
    default=1280,
    required=False
)
parser.add_argument(
    "--model_path",
    help="The path of a specific model to load",
    type=str,
    default="",
    required=False
)
parser.add_argument(
    "--inference_framework",
    help="The inference framework to use (either 'onnx' or 'tflite'",
    type=str,
    default='tflite',
    required=False
)

args=parser.parse_args()

CHANNELS = 1
RATE = 16000
CHUNK = args.chunk_size
sd.default.samplerate = RATE
sd.default.channels = CHANNELS
sd.default.dtype= ('int16', 'int16')

def sd_callback(rec, frames, time, status):
    audio = np.frombuffer(rec, dtype=np.int16)
    prediction = owwModel.predict(audio)

    # Column titles
    n_spaces = 16
    output_string_header = """
        Model Name         | Score | Wakeword Status
        --------------------------------------
        """

    for mdl in owwModel.prediction_buffer.keys():
        # Add scores in formatted table
        scores = list(owwModel.prediction_buffer[mdl])
        curr_score = format(scores[-1], '.20f').replace("-", "")

        output_string_header += f"""{mdl}{" "*(n_spaces - len(mdl))}   | {curr_score[0:5]} | {"--"+" "*20 if scores[-1] <= 0.5 else "Wakeword Detected!"}
        """

    # Print results table
    print("\033[F"*(4*n_models+1))
    print(output_string_header, "                             ", end='\r')

# Load pre-trained openwakeword models
if args.model_path != "":
    owwModel = Model(wakeword_models=[args.model_path], inference_framework=args.inference_framework)
else:
    owwModel = Model(inference_framework=args.inference_framework)

n_models = len(owwModel.models.keys())

# Start streaming from microphone
with sd.InputStream(channels=CHANNELS,
                    samplerate=RATE,
                    blocksize=int(CHUNK),
                    callback=sd_callback):
    threading.Event().wait()

Just create a /etc/asound.conf


pcm.!default {
    type asym
    playback.pcm "plughw:0"
    capture.pcm  "plughw:0"
}

As that will create a plug device which basically autoconverts to the format you want.
hw:0 is the card and really always create a plughw:device than direct hw:device as it makes things so much easier.

The onnx model also runs but with a bit more load so the default is likely the way to go.

1 Like

Hello everyone. Thank you for all your hard work to make this happened( voice assist and wake word). I am not a programmer and don’t know how to create a custom wake word, maybe someone will create and share with me and the others who is interesting in this type of wake word . My idea is to use a Capitan Morgan bottle with esp32 board , mic and speaker inside for Voice Assist, to blend with my BAR collection. And I would like to use a wake word like : HEY CAPTAIN or HEY MORGAN or maybe AHOY( like a pirates ). My esp 32 board is up and running and I am in the process of empty :slight_smile: my rum bottle and build a voice assist. Thank you in advanced.

3 Likes

I saw that one, thank you and I use his terminator word to try ow it’s work. And it’s working great, but I have no idea how to create one with my own wake word. I read an instruction, but so far is not what I am capable to do by myself. Thank you again

Instructions: Create your own wake word - Home Assistant

3 Likes