Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

snowboy

Kitt-AI87Apache-2.01.3.1TypeScript support: included

Snowboy is a customizable hotword detection engine

readme

Snowboy Hotword Detection

by KITT.AI.

Home Page

Full Documentation and FAQ

Discussion Group (or send email to snowboy-discussion@kitt.ai)

Commercial application FAQ

Version: 1.3.0 (2/19/2018)

Alexa support

Snowboy now brings hands-free experience to the Alexa AVS sample app on Raspberry Pi! See more info below regarding the performance and how you can use other hotword models.

Performance

The performance of hotword detection usually depends on the actual environment, e.g., is it used with a quality microphone, is it used on the street, in a kitchen, or is there any background noise, etc. So we feel it is best for the users to evaluate it in their real environment. For the evaluation purpose, we have prepared an Android app which can be installed and run out of box: SnowboyAlexaDemo.apk (please uninstall any previous versions first if you have installed this app before).

Personal model

# Please replace YOUR_PERSONAL_MODEL.pmdl with the personal model you just
# created, and $ALEXA_AVS_SAMPLE_APP_PATH with the actual path where you
# cloned the Alexa AVS sample app repository.
cp YOUR_PERSONAL_MODEL.pmdl $ALEXA_AVS_SAMPLE_APP_PATH/samples/wakeWordAgent/ext/resources/alexa.umdl
# Please replace $ALEXA_AVS_SAMPLE_APP_PATH with the actual path where you
# cloned the Alexa AVS sample app repository.
cd $ALEXA_AVS_SAMPLE_APP_PATH/samples/wakeWordAgent/src/

# Modify KittAiSnowboyWakeWordEngine.cpp and update SENSITIVITY at line 28.
# Modify KittAiSnowboyWakeWordEngine.cpp and set APPLY_FRONTEND to false at
# line 30.
make
  • Run the wake word agent with engine set to kitt_ai!

Universal model

# Please replace YOUR_UNIVERSAL_MODEL.umdl with the personal model you just
# created, and $ALEXA_AVS_SAMPLE_APP_PATH with the actual path where you
# cloned the Alexa AVS sample app repository.
cp YOUR_UNIVERSAL_MODEL.umdl $ALEXA_AVS_SAMPLE_APP_PATH/samples/wakeWordAgent/ext/resources/alexa.umdl
# Please replace $ALEXA_AVS_SAMPLE_APP_PATH with the actual path where you
# cloned the Alexa AVS sample app repository.
cd $ALEXA_AVS_SAMPLE_APP_PATH/samples/wakeWordAgent/src/

# Modify KittAiSnowboyWakeWordEngine.cpp and update SENSITIVITY at line 28.
make
  • Run the wake word agent with engine set to kitt_ai!

Hotword as a Service

Snowboy now offers Hotword as a Service through the https://snowboy.kitt.ai/api/v1/train/ endpoint. Check out the Full Documentation and example Python/Bash script (other language contributions are very welcome).

As a quick start, POST to https://snowboy.kitt.ai/api/v1/train:

{
    "name": "a word",
    "language": "en",
    "age_group": "10_19",
    "gender": "F",
    "microphone": "mic type",
    "token": "<your auth token>",
    "voice_samples": [
        {wave: "<base64 encoded wave data>"},
        {wave: "<base64 encoded wave data>"},
        {wave: "<base64 encoded wave data>"}
    ]
}

then you'll get a trained personal model in return!

Introduction

Snowboy is a customizable hotword detection engine for you to create your own hotword like "OK Google" or "Alexa". It is powered by deep neural networks and has the following properties:

  • highly customizable: you can freely define your own magic phrase here – let it be “open sesame”, “garage door open”, or “hello dreamhouse”, you name it.

  • always listening but protects your privacy: Snowboy does not use Internet and does not stream your voice to the cloud.

  • light-weight and embedded: it even runs on a Raspberry Pi and consumes less than 10% CPU on the weakest Pi (single-core 700MHz ARMv6).

  • Apache licensed!

Currently Snowboy supports (look into the lib folder):

  • all versions of Raspberry Pi (with Raspbian based on Debian Jessie 8.0)
  • 64bit Mac OS X
  • 64bit Ubuntu 14.04
  • iOS
  • Android
  • ARM64 (aarch64, Ubuntu 16.04)

It ships in the form of a C++ library with language-dependent wrappers generated by SWIG. We welcome wrappers for new languages -- feel free to send a pull request!

Currently we have built wrappers for:

  • C/C++
  • Java/Android
  • Go (thanks to @brentnd and @deadprogram)
  • Node (thanks to @evancohen and @nekuz0r)
  • Perl (thanks to @iboguslavsky)
  • Python2/Python3
  • iOS/Swift3 (thanks to @grimlockrocks)
  • iOS/Object-C (thanks to @patrickjquinn)

If you want support on other hardware/OS, please send your request to snowboy@kitt.ai

Note: Snowboy does not support Windows yet. Please build Snowboy on *nix platforms.

Pricing for Snowboy models

Hackers: free

  • Personal use
  • Community support

Business: please contact us at snowboy@kitt.ai

  • Personal use
  • Commercial license
  • Technical support

Pretrained universal models

We provide pretrained universal models for testing purpose. When you test those models, bear in mind that they may not be optimized for your specific device or environment.

Here is the list of the models, and the parameters that you have to use for them:

  • resources/alexa/alexa-avs-sample-app/alexa.umdl: Universal model for the hotword "Alexa" optimized for Alexa AVS sample app. Set SetSensitivity to 0.6, and set ApplyFrontend to true. This is so far the best "Alexa" model we released publicly, when ApplyFrontend is set to true.
  • resources/models/snowboy.umdl: Universal model for the hotword "Snowboy". Set SetSensitivity to 0.5 and ApplyFrontend to false.
  • resources/models/jarvis.umdl: Universal model for the hotword "Jarvis" (https://snowboy.kitt.ai/hotword/29). It has two different models for the hotword Jarvis, so you have to use two sensitivites. Set sensitivities to "0.8,0.80" and ApplyFrontend to true.
  • resources/models/smart_mirror.umdl: Universal model for the hotword "Smart Mirror" (https://snowboy.kitt.ai/hotword/47). Set sensitivity to Sensitivity to 0.5, and ApplyFrontend to false.

Precompiled node module

Snowboy is available in the form of a native node module precompiled for: 64 bit Ubuntu, MacOS X, and the Raspberry Pi (Raspbian 8.0+). For quick installation run:

npm install --save snowboy

For sample usage see the examples/Node folder. You may have to install dependencies like fs, wav or node-record-lpcm16 depending on which script you use.

Precompiled Binaries with Python Demo

If you want to compile a version against your own environment/language, read on.

Dependencies

To run the demo you will likely need the following, depending on which demo you use and what platform you are working with:

  • SoX (audio conversion)
  • PortAudio or PyAudio (audio capturing)
  • SWIG 3.0.10 or above (compiling Snowboy for different languages/platforms)
  • ATLAS or OpenBLAS (matrix computation)

You can also find the exact commands you need to install the dependencies on Mac OS X, Ubuntu or Raspberry Pi below.

Mac OS X

brew install swig, sox, portaudio and its Python binding pyaudio:

brew install swig portaudio sox
pip install pyaudio

If you don't have Homebrew installed, please download it here. If you don't have pip, you can install it here.

Make sure that you can record audio with your microphone:

rec t.wav

Ubuntu/Raspberry Pi/Pine64/Nvidia Jetson TX1/Nvidia Jetson TX2

First apt-get install swig, sox, portaudio and its Python binding pyaudio:

sudo apt-get install swig3.0 python-pyaudio python3-pyaudio sox
pip install pyaudio

Then install the atlas matrix computing library:

sudo apt-get install libatlas-base-dev

Make sure that you can record audio with your microphone:

rec t.wav

If you need extra setup on your audio (especially on a Raspberry Pi), please see the full documentation.

Compile a Node addon

Compiling a node addon for Linux and the Raspberry Pi requires the installation of the following dependencies:

sudo apt-get install libmagic-dev libatlas-base-dev

Then to compile the addon run the following from the root of the snowboy repository:

npm install
./node_modules/node-pre-gyp/bin/node-pre-gyp clean configure build

Compile a Java Wrapper

# Make sure you have JDK installed.
cd swig/Java
make

SWIG will generate a directory called java which contains converted Java wrappers and a directory called jniLibs which contains the JNI library.

To run the Java example script:

cd examples/Java
make run

Compile a Python Wrapper

cd swig/Python
make

SWIG will generate a _snowboydetect.so file and a simple (but hard-to-read) python wrapper snowboydetect.py. We have provided a higher level python wrapper snowboydecoder.py on top of that.

Feel free to adapt the Makefile in swig/Python to your own system's setting if you cannot make it.

Compile a GO Wrapper

cd examples/Go
go get github.com/Kitt-AI/snowboy/swig/Go
go build -o snowboy main.go
./snowboy ../../resources/snowboy.umdl ../../resources/snowboy.wav

Expected Output:

Snowboy detecting keyword in ../../resources/snowboy.wav
Snowboy detected keyword  1

For more, please read examples/Go/readme.md.

Compile a Perl Wrapper

cd swig/Perl
make

The Perl examples include training personal hotword using the KITT.AI RESTful APIs, adding Google Speech API after the hotword detection, etc. To run the examples, do the following

cd examples/Perl

# Install cpanm, if you don't already have it.
curl -L https://cpanmin.us | perl - --sudo App::cpanminus

# Install the dependencies. Note, on Linux you will have to install the
# PortAudio package first, using e.g.:
# apt-get install portaudio19-dev
sudo cpanm --installdeps .

# Run the unit test.
./snowboy_unit_test.pl

# Run the personal model training example.
./snowboy_RESTful_train.pl <API_TOKEN> <Hotword> <Language>

# Run the Snowboy Google Speech API example. By default it uses the Snowboy
# universal hotword.
./snowboy_googlevoice.pl <Google_API_Key> [Hotword_Model]

Compile an iOS Wrapper

Using Snowboy library in Objective-C does not really require a wrapper. It is basically the same as using C++ library in Objective-C. We have compiled a "fat" static library for iOS devices, see the library here lib/ios/libsnowboy-detect.a.

To initialize Snowboy detector in Objective-C:

snowboy::SnowboyDetect* snowboyDetector = new snowboy::SnowboyDetect(
    std::string([[[NSBundle mainBundle]pathForResource:@"common" ofType:@"res"] UTF8String]),
    std::string([[[NSBundle mainBundle]pathForResource:@"snowboy" ofType:@"umdl"] UTF8String]));
snowboyDetector->SetSensitivity("0.45");        // Sensitivity for each hotword
snowboyDetector->SetAudioGain(2.0);             // Audio gain for detection

To run hotword detection in Objective-C:

int result = snowboyDetector->RunDetection(buffer[0], bufferSize);  // buffer[0] is a float array

You may want to play with the frequency of the calls to RunDetection(), which controls the CPU usage and the detection latency.

Thanks to @patrickjquinn and @grimlockrocks, we now have examples of using Snowboy in both Objective-C and Swift3. Check out the examples at examples/iOS/, and the screenshots below!

Obj-C Example Swift3 Example

Compile an Android Wrapper

Full README and tutorial is in Android README and here's a screenshot:

Android Alexa Demo

We have prepared an Android app which can be installed and run out of box: SnowboyAlexaDemo.apk (please uninstall any previous one first if you installed this app before).

Quick Start for Python Demo

Go to the examples/Python folder and open your python console:

In [1]: import snowboydecoder

In [2]: def detected_callback():
   ....:     print "hotword detected"
   ....:

In [3]: detector = snowboydecoder.HotwordDetector("resources/snowboy.umdl", sensitivity=0.5, audio_gain=1)

In [4]: detector.start(detected_callback)

Then speak "snowboy" to your microphone to see whetheer Snowboy detects you.

The snowboy.umdl file is a "universal" model that detect different people speaking "snowboy". If you want other hotwords, please go to snowboy.kitt.ai to record, train and downloand your own personal model (a .pmdl file).

When sensitiviy is higher, the hotword gets more easily triggered. But you might get more false alarms.

audio_gain controls whether to increase (>1) or decrease (<1) input volume.

Two demo files demo.py and demo2.py are provided to show more usages.

Note: if you see the following error:

TypeError: __init__() got an unexpected keyword argument 'model_str'

You are probably using an old version of SWIG. Please upgrade. We have tested with SWIG version 3.0.7 and 3.0.8.

Advanced Usages & Demos

See Full Documentation.

Change Log

v1.3.0, 2/19/2018

v1.2.0, 3/25/2017

  • Added better Alexa model for Alexa AVS sample app
  • New decoder that works well for short hotwords like Alexa

v1.1.1, 3/24/2017

  • Added Android demo
  • Added iOS demos
  • Added Samsung Artik support
  • Added Go support
  • Added Intel Edison support
  • Added Pine64 support
  • Added Perl Support
  • Added a more robust "Alexa" model (umdl)
  • Offering Hotword as a Service through /api/v1/train endpoint.
  • Decoder is not changed.

v1.1.0, 9/20/2016

  • Added library for Node.
  • Added support for Python3.
  • Added universal model alexa.umdl
  • Updated universal model snowboy.umdl so that it works in noisy environment.

v1.0.4, 7/13/2016

  • Updated universal snowboy.umdl model to make it more robust.
  • Various improvements to speed up the detection.
  • Bug fixes.

v1.0.3, 6/4/2016

  • Updated universal snowboy.umdl model to make it more robust in non-speech environment.
  • Fixed bug when using float as input data.
  • Added library support for Android ARMV7 architecture.
  • Added library for iOS.

v1.0.2, 5/24/2016

  • Updated universal snowboy.umdl model
  • added C++ examples, docs will come in next release.

v1.0.1, 5/16/2016

  • VAD now returns -2 on silence, -1 on error, 0 on voice and >0 on triggered models
  • added static library for Raspberry Pi in case people want to compile themselves instead of using the binary version

v1.0.0, 5/10/2016

  • initial release

changelog

Note: Because PortAudioCpp is now in the main PortAudio SVN repository, having these per-release changelogs probably doesn't make much sense anymore. Perhaps it's better to just note mayor changes by date from now on.

PortAudioCpp v19 revision 16 06/05/22:

mblaauw:
- Added up-to-date MSVC 6.0 projects created by David Moore. Besides MSVC 6.0 users, MSVC 7.0 users may use these projects and automatically convert them to MSVC 7.0 projects.
- Changed the code and projects (MSVC 7.1 only) to be up-to-date with PortAudio's new directory structure.
- Added equivalents of the PaAsio_GetInputChannelName() and PaAsio_GetOutputChannelName() functions to the AsioDeviceAdapter wrapper-class (missing functions pointed out by David Moore).
- Added code to PortAudio's main SVN repository.

PortAudioCpp v19 revision 15 (unknown release date):

mblaauw:
- Changed some exception handling code in HostApi's constructor.
- Added accessors to PortAudio PaStream from PortAudioCpp Stream (their absense being pointed out
by Tom Jordan).
- Fixed a bug/typo in MemFunToCallbackInterfaceAdapter::init() thanks to Fredrik Viklund.
- Fixed issue with concrete Stream classes possibly throwing an exception and fixed documentation w.r.t. this.
- Moved files to portaudio/binding/cpp/. Made new msvc 7.1 projects to reflect the change and removed msvc 6.0 
and 7.0 projects (because I can no longer maintain them myself). Gnu projects will probably need updating.

PortAudioCpp v19 revision 14 03/10/24:

mblaauw:
- Fixed some error handling bugs in Stream and System (pointed out by Tom Jordan).
- Updated documentation a little (main page).
- Fixed order of members so initializer list was in the right order in 
StreamParameters (pointed out by Ludwig Schwardt).
- Added new lines at EOF's (as indicated by Ludwig Schwardt).

PortAudioCpp v19 revision 13 03/10/19:

lschwardt:
- Added build files for GNU/Linux.
- Fixed bug in Exception where the inherited what() member function (and destructor) had looser 
exception specification (namely no exception specification, i.e. could throw anything) than 
the std::exception base class's what() member function (which had throw(), i.e. no-throw guarantee).
- Changed the iterators so that they have a set of public typedefs instead of deriving the C++ standard 
library std::iterator<> struct. G++ 2.95 doesn't support std::exception<> and composition-by-aggregation 
is prefered over composition-by-inheritance in this case.
- Changed some minor things to avoid G++ warning messages.

mblaauw:
- Renamed this file (/WHATSNEW.txt) to /CHANGELOG.
- Renamed /PA_ISSUES.txt to /PA_ISSUES.
- Added /INSTALL file with some build info for GNU/Linux and VC6.
- Added MSVC 6.0 projects for building PortAudioCpp as a staticly or dynamically linkable library.
- Moved build files to /build/(gnu/ or vc6/).
- Moved Doxygen configuration files to /doc/ and output to /doc/api_reference/.
- Added a /doc/README with some info how to generate Doxygen documentation.

PortAudioCpp v19 revision 12 03/09/02:

mblaauw:
- Updated code to reflect changes on V19-devel CVS branch.
- Fixed some typos in the documentation.

PortAudioCpp v19 revision 11 03/07/31:

mblaauw:
- Renamed SingleDirecionStreamParameters to DirectionSpecificStreamParameters.
- Implemented BlockingStream.
- Updated code to reflect recent changes to PortAudio V19-devel.
- Fixed a potential memory leak when an exception was thrown in the HostApi 
constructor.
- Renamed ``Latency'' to ``BufferSize'' in AsioDeviceAdapter.
- Updated class documentation.

PortAudioCpp v19 revision 10 03/07/18:

mblaauw:
- SingleDirectionStreamParameters now has a (static) null() method.
- StreamParameters uses references for the direction-specific stream parameters 
instead of pointers (use null() method (above) instead of NULL).
- StreamParameters and SingleDirectionStreamParameters must now be fully specified 
and now default values are used (because this was not very useful in general and 
only made things more complex).
- Updated documentation.

PortAudioCpp v19 revision 09 03/06/25:

mblaauw:
- Changed some things in SingleDirectionStreamParameters to ease it's usage.
- Placed all SingleDirectionStreamParameters stuff into a separate file.
+ Totally redid the callback stuff, now it's less ackward and supports C++ functions.

PortAudioCpp v19 revision 08 03/06/20:

mblaauw:
- Made deconstructors for Device and HostApi private.
+ Added a AsioDeviceWrapper host api specific device extension class.
- Refactored Exception into a Exception base class and PaException and PaCppException 
derived classes.
- Added ASIO specific device info to the devs.cxx example.
- Fixed a bug in System::hostApiCount() and System::defaultHostApi().
+ Moved Device::null to System::nullDevice.
- Fixed some bugs in Device and System.

PortAudioCpp v19 revision 07 03/06/08:

mblaauw:
- Updated some doxy comments.
+ Renamed CbXyz to CallbackXyz.
+ Renamed all ``configurations'' to ``parameters''.
+ Renamed HalfDuplexStreamConfiguration to SingleDirectionStreamConfiguration.
- Renamed SingleDirectionStreamParameters::streamParameters() to 
SingleDirectionStreamParameters::paSteamParameters.
- Added a non-constant version of SingleDirectionStreamParameters::paStreamParameters().
- A few improvements to SingleDirectionStreamParameters.
- Allowed AutoSystem to be created without initializing the System singleton 
(using a ctor flag).
- Added a BlockingStream class (not implemented for now).
- Fixed many bugs in the implementation of the iterators.
- Fixed a bug in Device::operator==().
+ Added a C++ version of the patest_sine.c test/example.
- Added a ctor for StreamParameters for a default half-duplex stream.
- Added SingleDirectionStreamParameters::setDevice() and setNumChannels().
- Renamed System::numHostApis() to System::hostApiCount().
+ Rewrote the iterators and related classes. They are now fully STL compliant. The System now 
has a static array of all HostApis and all Devices. Only the System can create HostApis and 
Devices and they are non-copyable now. All HostApis and Devices are now passed by-reference.
- Renamed (System::) getVersion() to version() and getVersionText() to versionText().
- Renamed (Device::) numXyzChannels() to maxXyzChannels().
- Changed some stuff in StreamParameters.
+ Added a C++ version of the patest_devs.c test/example.

PortAudioCpp v19 revision 06 03/06/04:

mblaauw:
+ Added this file to the project (roughly, a `+' denotes a major change, a `-' a minor change).
- Added System::deviceByIndex(), useful when a Device's index is stored for instance.
- Renamed System::hostApiFromTypeId() to System::hostApiByTypeId().
- Updated and added some Doxygen documentation.
- Made Stream::usedIntputLatency(), Stream::usedOutputLatency() and 
Stream::usedSampleRate() throw an paInternalError equivalent exception instead of paBadStreamPtr.
- Changed exception handling in Stream::open() functions. They now follow the PA error handling 
mechanism better and a couple of bugs regarding ownership of objects were fixed.
- Renamed Device::isDefaultXyzDevice() to Device::isSystemDefaultXyzDevice().
- Added Device::isHostApiDefaultXyzDevice().
- Added StreamConfiguration::unsetFlag().
- Removed CUSTOM from SampleDataFormat.
- System::hostApiByTypeId() now throws an paInternalError if the type id was out-of-range; this 
is a temporary work-around (see comments).
- Changed CbInterface to use paCallbackFun() instead of operator()().
- Renamed ``object'' to ``instance'' in CbMemFunAdapter.hxx.
- Added StreamConfiguration::setXyzHostApiSpecificSampleFormat().
- Added StreamConfiguration::isXyzSampleFormatHostApiSpecific().
- Changed error handling in System::terminate(), it can now throw an Exception.
- Added error handling in System::defaultHostApi().
- Added error handling in System::hostApisEnd().
- Changed some (but probably not all) C casts to C++ casts to avoid confusion with a 
certain Python person.
- Renamed RaiiSystem to AutoSystem (class and file) as this is a come common convention.
- Renamed System::numDevices() to System::deviceCount() to be more compatible with PortAudio 
(although PortAudio uses Pa_CountDevices() instead, see comment).
- Renamed HostApi::numDevices() to HostApi::deviceCount().
- Changed INC_ to INCLUDED_ in the header multiple include guards.
- Changed the order of functions in the StreamConfiguration class' header.
- Written some more info in PortAudioCpp.hxx (Doxygen).
- Added CallbackStream.hxx and CallbackStream.cxx files.
+ Refactored StreamConfiguration to remove the duplication which was there. There is now a 
HalfDuplexStreamConfiguration class. Also made some improvements to these classes while 
doing the refactoring.
+ Moved all code files to source/portaudiocpp/ and changed includes.
+ Moved all header files to include/portaudiocpp/ to easy a binary build if needed. The project 
must be set to have .../include/ as a path to look for includes.
+ Refactored the Stream class into a Stream base class and a CallbackStream derived class.
- Renamed Stream::usingXyz() to Stream::xyz().
- Updated some doxy comments.
- Changed ``using namespace portaudio'' in .cxx files to ``namespace portaudio { ... }''.

PortAudioCpp v19 revision 05 03/04/09:

mblaauw:
- Initial release on the PortAudio mailinglist.