python · raspberry pi

Hot-wording on a Raspberry PI – “Computer! Do my bidding!”

logo

Picovoice.ai

There is a great video for getting started:

I’ve distilled the commands out for you…

First pull out the repository – this took a long time for me… its BIG (4.2G at the time of this writing):

git clone https://github.com/Picovoice/Porcupine.git

Now that you have the repo.  There are a good number of hotword models to choose from.  Look in:

~/Porcupine/resources/keyword_files/raspberrypi

On my system:

americano_raspberrypi.ppn       caterpillar_raspberrypi.ppn       francesca_raspberrypi.ppn         picovoice_raspberrypi.ppn       terminator_raspberrypi.ppn
americano_raspberrypi_tiny.ppn caterpillar_raspberrypi_tiny.ppn francesca_raspberrypi_tiny.ppn picovoice_raspberrypi_tiny.ppn terminator_raspberrypi_tiny.ppn
avocado_raspberrypi.ppn christina_raspberrypi.ppn grapefruit_raspberrypi.ppn pineapple_raspberrypi.ppn vancouver_raspberrypi.ppn
avocado_raspberrypi_tiny.ppn christina_raspberrypi_tiny.ppn grapefruit_raspberrypi_tiny.ppn pineapple_raspberrypi_tiny.ppn vancouver_raspberrypi_tiny.ppn
blueberry_raspberrypi.ppn dragonfly_raspberrypi.ppn grasshopper_raspberrypi.ppn porcupine_raspberrypi.ppn
blueberry_raspberrypi_tiny.ppn dragonfly_raspberrypi_tiny.ppn grasshopper_raspberrypi_tiny.ppn porcupine_raspberrypi_tiny.ppn
bumblebee_raspberrypi.ppn flamingo_raspberrypi.ppn iguana_raspberrypi.ppn raspberry_raspberrypi.ppn
bumblebee_raspberrypi_tiny.ppn flamingo_raspberrypi_tiny.ppn iguana_raspberrypi_tiny.ppn raspberry_raspberrypi_tiny.ppn

Which means I can use these words as my “hotword”:

americano
avocado
blueberry
bumblebee
caterpillar
christina
dragonfly
flamingo
francescagrapefruit
grasshopper
iguana
picovoice
pineapple
porcupine
raspberry
terminator
vancouver

Let’s try “avocado“.  That’s kinda fun.  Now… next thing you’ll need is someway to get audio into the pi.  I like these dongles from Adafruit:

usbaudio

Ok… now if you need a mic. I’m also a fan of these:

Ok, plug those in, and make sure they are working. A tool I like to use for recording a test audio sample, run this, then say “terminator” a couple of times:

arecord -D plughw:CARD=Device,DEV=0 test.wav

That should create an audio file called “test.wav” that you can play back to hear your sound quality:

aplay -D plughw:CARD=Device,DEV=0 test.wav

Picovoice doesn’t need awesome sound quality, its pretty danged robust. So… lets give it a whirl… but hold-on you need some python pre-reqs:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential libssl-dev libffi-dev python-dev
sudo apt-get install python-pip
sudo pip install enum34
# These two steps take a long time on the little pi
sudo pip install numpy
pip install -U numpy
sudo pip install sndfile
sudo apt-get install python-pyaudio python3-pyaudio
sudo pip install soundfile
mkdir soundstuffs
cd soundstuffs
wget http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.28.tar.gz
tar xvf libsndfile-1.0.28.tar.gz
cd libsndfile-1.0.28
./configure
make
sudo make install
ldconfig

Phew! Keep going…

Training your own model… no not now… later…

To train your own model – you need to use a bigger computer.  Something like a mac or a PC.  Sadly, they don’t provide the tools on the PI.  

To tell porcupine to train on the word of your choosing.  In this example “computer” is the word:

cd Procupine
tools/optimizer/linux/x86_64/pv_porcupine_optimizer -r resources/ -p linux -o . -w "computer"

Let’s try it out!!!

The instructions I’m cribbing from are found here.

First, change directory into the Porcupine repo:

cd Porcupine

Then run the wake word command:

python demo/python/porcupine_demo.py --keyword_file_paths resources/keyword_files/raspberrypi/avocado_raspberrypi.ppn --library_path ./lib/raspberry-pi/cortex-a53/libpv_porcupine.so

Ok, it probably blew up with something like “Invalid Sample Rate”:

IOError: [Errno -9997] Invalid sample rate

That’s because the sample rate of your hardware is locked to something this software can’t handle.  You need something more flexible between you and the microphone.  

Alsa to the rescue!

Alsa has a default software layer sink that allows you to sample at any rate you need, and it just magically works.  To get at that magic, you have to create this new device.  So, create an “.asoundrc” file in your home directory, and put this in it:

pcm.!default {     
  capture.pcm "usb_mic"
}

pcm.usb_mic {
  type plug
  slave {
    pcm "hw:1,0"
  }
}

That configuration instructs Alsa to create the new device and call it “usb_mic”…. and make it default.

Now, run the command from before but with a command that lets you see the mics:

python ./demo/python/porcupine_demo.py --show_audio_devices_info

Take a look at the list… you should now see your new device:

'index': '0', 'name': 'bcm2835 ALSA: - (hw:0,0)', 'defaultSampleRate': '44100.0', 'maxInputChannels': '0'
'index': '1', 'name': 'bcm2835 ALSA: IEC958/HDMI (hw:0,1)', 'defaultSampleRate': '44100.0', 'maxInputChannels': '0'
'index': '2', 'name': 'USB Audio Device: - (hw:1,0)', 'defaultSampleRate': '44100.0', 'maxInputChannels': '1'
'index': '3', 'name': 'sysdefault', 'defaultSampleRate': '44100.0', 'maxInputChannels': '0'
'index': '4', 'name': 'usb_mic', 'defaultSampleRate': '44100.0', 'maxInputChannels': '128'
'index': '5', 'name': 'dmix', 'defaultSampleRate': '48000.0', 'maxInputChannels': '0'
'index': '6', 'name': 'default', 'defaultSampleRate': '44100.0', 'maxInputChannels': '32'

That “usb_mic” is the one you just created!  Now instruct Porcupine to use it with the command line parameter:

python demo/python/porcupine_demo.py --keyword_file_paths resources/keyword_files/raspberrypi/avocado_raspberrypi.ppn --library_path ./lib/raspberry-pi/cortex-a53/libpv_porcupine.so --input_audio_device_index 4

Avocado!

Huzzah!  You should now be ready to start recognizing your hotword requests.  Say “Avocado” a couple of times.  The should start coming out at the end of the trace like this (detected keyword):

Screen Shot 2019-02-20 at 7.20.57 AM.png

Onward!  Now that you can be heard…

There are lots of things you can do.  For the lazy – simply run this process from your other programs… monitor stdout for that phrase and Voila!  You know when your software has been summoned!

Look for another article on using this in your NodeJS application… I just have to figure that out first… 😉

Some other articles you might like…

Wizard’s Fire!!!

[FIXED!!!] Turn on a lamp with a gesture – Image Processing! Machine learning!

Lessons on PI 6: Playing Audio on a Raspberry PI

The complete guide to enabling speech recognition on an RPI3… in NodeJS

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.