Porcupine - iOS API
This document outlines how to integrate Porcupine wake word engine within an iOS application.
Installation
The Porcupine iOS binding is available via Cocoapods. To import it into your iOS project, add the following line to your Podfile:
pod 'Porcupine-iOS'
Permissions
To enable recording with your iOS device's microphone you must add the following to your app's Info.plist
file:
<key>NSMicrophoneUsageDescription</key><string>[Permission explanation]</string>
Usage
The module provides you with two levels of API to choose from depending on your needs.
High-Level API
PorcupineManager provides a high-level API that takes care of audio recording and wake word detection. This class is the quickest way to get started.
To create an instance of PorcupineManager pass the desired keyword to the constructor:
import Porcupinedo {PorcupineManager porcupineManager = try PorcupineManager(keyword: Porcupine.BuiltInKeyword.picovoice,onDetection: wakeWordCallback)} catch { }
The wakeWordCallback
parameter is function that will be invoked when Porcupine has detected one of the keywords.
The callback should accept a single integer, which specifies which wake word has been detected.
let wakeWordCallback: ((Int32) -> Void) = { keywordIndex inif keywordIndex == 0 {// wake word 0 detected!}}}
Available built-in keywords are accessible via the Porcupine.BuiltInKeyword enum.
To create an instance of PorcupineManager that detects custom keywords, you can use the keywordPaths
parameter instead:
do {let paths = ["path/to/keyword/one.ppn", "path/to/keyword/two.ppn"]PorcupineManager porcupineManager = try PorcupineManager(keywordPaths: paths,onDetection: wakeWordCallback)} catch { }
In addition to custom keywords, you can override the default Porcupine English model file and/or keyword sensitivities.
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.
The model file contains the parameters for the wake word engine. To change the language that Porcupine understands, pass in a different model file.
These optional parameters can be set like so:
do {let paths = ["path/to/keyword/one.ppn", "path/to/keyword/two.ppn"]PorcupineManager porcupineManager = try PorcupineManager(keywordPaths: paths,modelPath: "path/to/model/file.pv",sensitivities: [0.7, 0.35],onDetection: wakeWordCallback)} catch { }
Once you have instantiated a PorcupineManager, you can start audio capture and wake word detection by calling:
do {porcupineManager.start()} catch { }
And then stop it by calling:
porcupineManager.stop()
Once the app is done with using an instance of PorcupineManager you can release the native resources manually rather than waiting for the garbage collector:
porcupineManager.delete()
Low-Level API
Porcupine provides low-level access to the wake word engine for those who want to incorporate wake word detection into a already existing audio processing pipeline.
To construct an instance of Porcupine, pass it a keyword.
import Porcupinedo {Porcupine porcupine = try Porcupine(keyword: Porcupine.BuiltInKeyword.picovoice)} catch { }
To search for a keyword in audio, you must pass frames of audio to Porcupine using the process
function. The keywordIndex
returned will either be -1 if no detection was made or an integer specifying which keyword was detected.
func getNextAudioFrame() -> [Int16] {// .. get audioFramereturn audioFrame;}while true {do {let keywordIndex = try porcupine.process(getNextAudioFrame())if keywordIndex >= 0 {// .. detection made!}} catch { }}
For process
to work correctly, the audio data must be in the audio format required by Picovoice.
The required audio format is found by using Porcupine.sampleRate
to get the required sample rate and Porcupine.frameLength
to get the required number of samples per input frame. Audio must be single-channel and 16-bit linearly-encoded.
Once you're done with Porcupine you can force it to release its native resources rather than waiting for the garbage collector:
porcupine.delete();
Custom Wake Word
You can create custom Porcupine wake word models using Picovoice Console.
Custom Wake Word Integration
To add a custom wake word to your iOS application you must include it in your app as a bundled resource (found by selecting in Build Phases > Copy Bundle Resources). Then in code, get its path like so:
// file is called keyword_ios.ppnlet keywordPath = Bundle.main.path(forResource: "keyword_ios", ofType: "ppn")
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.