19 stable releases (3 major)

3.0.2 Jan 30, 2024
3.0.1 Nov 16, 2023
3.0.0 Oct 25, 2023
2.2.1 Jun 7, 2023
0.0.2 Aug 9, 2021

#12 in Audio

Download history 38/week @ 2024-01-27 2/week @ 2024-02-03 208/week @ 2024-02-24 12/week @ 2024-03-02 24/week @ 2024-03-09 13/week @ 2024-03-16 28/week @ 2024-03-23 61/week @ 2024-03-30 35/week @ 2024-04-06 7/week @ 2024-04-13 20/week @ 2024-04-20 10/week @ 2024-04-27

75 downloads per month
Used in picovoice

Apache-2.0

3MB
743 lines

Contains (Windows DLL, 295KB) libpv_porcupine.dll, (ELF lib, 145KB) data/lib/beaglebone/libpv_porcupine.so, (ELF lib, 155KB) libpv_porcupine.so, (ELF lib, 180KB) data/lib/linux/x86_64/libpv_porcupine.so, (Mach-o library, 220KB) data/lib/mac/arm64/libpv_porcupine.dylib, (Mach-o library, 235KB) libpv_porcupine.dylib and 8 more.

Porcupine Wake Word Engine

Made in Vancouver, Canada by Picovoice

Porcupine is a highly-accurate and lightweight wake word engine. It enables building always-listening voice-enabled applications. It is

  • using deep neural networks trained in real-world environments.
  • compact and computationally-efficient. It is perfect for IoT.
  • cross-platform:
    • Arm Cortex-M, STM32, Arduino, and i.MX RT
    • Raspberry Pi, NVIDIA Jetson Nano, and BeagleBone
    • Android and iOS
    • Chrome, Safari, Firefox, and Edge
    • Linux (x86_64), macOS (x86_64, arm64), and Windows (x86_64)
  • scalable. It can detect multiple always-listening voice commands with no added runtime footprint.
  • self-service. Developers can train custom wake word models using Picovoice Console.

Compatibility

  • Rust 1.54+
  • Runs on Linux (x86_64), macOS (x86_64 and arm64), Windows (x86_64), Raspberry Pi, NVIDIA Jetson (Nano), and BeagleBone

Installation

First you will need Rust and Cargo installed on your system.

To add the porcupine library into your app, add pv_porcupine to your apps Cargo.toml manifest:

[dependencies]
pv_porcupine = "*"

If you prefer to clone the repo and use it locally, first run copy.sh. (NOTE: on Windows, Git Bash or another bash shell is required, or you will have to manually copy the libs into the project). Then you can reference the local binding location:

[dependencies]
pv_porcupine = { path = "/path/to/rust/binding" }

AccessKey

Porcupine requires a valid Picovoice AccessKey at initialization. AccessKey acts as your credentials when using Porcupine SDKs. You can get your AccessKey for free. Make sure to keep your AccessKey secret. Signup or Login to Picovoice Console to get your AccessKey.

Usage

To create an instance of the engine you first create a PorcupineBuilder instance with the configuration parameters for the wake word engine and then make a call to .init():

use porcupine::{BuiltinKeywords, PorcupineBuilder};

let access_key = "${ACCESS_KEY}"; // AccessKey obtained from Picovoice Console (https://console.picovoice.ai/)

let porcupine: Porcupine = PorcupineBuilder::new_with_keywords(access_key, &[BuiltinKeywords::Porcupine]).init().expect("Unable to create Porcupine");

In the above example, we've initialized the engine to detect the built-in wake word "Porcupine". Built-in keywords are contained in the package with the BuiltinKeywords enum type.

Porcupine can detect multiple keywords concurrently:

let porcupine: Porcupine = PorcupineBuilder::new_with_keywords(access_key, &[BuiltinKeywords::Porcupine, BuiltinKeywords::Blueberry, BuiltinKeywords::Bumblebee])
    .init().expect("Unable to create Porcupine");

To detect custom keywords, use PorcupineBuilder's new_with_keyword_paths method to pass in *.ppn file paths instead:

let porcupine: Porcupine = PorcupineBuilder::new_with_keyword_paths(access_key, &["/absolute/path/to/keyword/one.ppn", "/absolute/path/to/keyword/two.ppn"])
    .init().expect("Unable to create Porcupine");

The language can be changed by passing in an appropriate *.pv file path into the model_path method:

let porcupine: Porcupine = PorcupineBuilder::new_with_keyword_paths(access_key, &["/absolute/path/to/keyword/one.ppn"])
    .model_path("/path/to/another/language_params.pv")
    .init().expect("Unable to create Porcupine");

The sensitivity of the engine can be tuned per keyword using the sensitivities method:

let porcupine: Porcupine = PorcupineBuilder::new_with_keywords(access_key, &[BuiltinKeywords::Porcupine, BuiltinKeywords::Bumblebee])
    .sensitivities(&[0.2f32, 0.42f32])
    .init().expect("Unable to create Porcupine");

Sensitivity is the parameter that enables trading miss rate for the false alarm rate. It is a floating point number within [0, 1]. A higher sensitivity reduces the miss rate at the cost of increased false alarm rate.

When initialized, the valid sample rate is given by sample_rate(). Expected frame length (number of audio samples in an input array) is given by frame_length(). The engine accepts 16-bit linearly-encoded PCM and operates on single-channel audio.

To feed audio into Porcupine, use the process function in your capture loop.

fn next_audio_frame() -> Vec<i16> {
    // get audio frame
}

loop {
    if let Ok(keyword_index) = porcupine.process(&next_audio_frame()) {
        if keyword_index >= 0 {
            // wake word detected!
        }   
    }
}

Non-English Wake Words

In order to detect non-English wake words you need to use the corresponding model file. The model files for all supported languages are available here.

Demos

Check out the Porcupine Rust demos here

Dependencies