androidPicovoice Platform — Android API

This document outlines how to integrate the Picovoice platform within an application using the Picovoice Android API.

Installation

Porcupine can be found on Maven Central. To include the package in your Android project, ensure you have included mavenCentral() in your top-level build.gradle file and then add the following to your app's build.gradle:

dependencies {
// ...
implementation 'ai.picovoice:picovoice-android:1.1.0'
}

Permissions

To enable recording with your Android device's microphone you must add the following line to your AndroidManifest.xml file:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

Usage

There are two possibilities for integrating Picovoice into an Android application.

High-Level API

PicovoiceManager provides a high-level API for integrating Picovoice into Android applications. It manages all activities related to creating an input audio stream, feeding it into Picovoice engine, and invoking user-defined callbacks upon wake word detection and inference completion. The class can be initialized using the PicovoiceManager Builder:

import ai.picovoice.picovoice.*;
PicovoiceManager manager = new PicovoiceManager.Builder()
.setKeywordPath("path/to/keyword/file.ppn")
.setWakeWordCallback(new PicovoiceWakeWordCallback() {
@Override
public void invoke() {
// logic to execute upon deletection of wake word
}
})
.setContextPath("path/to/context/file.rhn")
.setInferenceCallback(new PicovoiceInferenceCallback() {
@Override
public void invoke(final RhinoInference inference) {
// logic to execute upon completion of intent inference
}
})
.build(appContext);

The appContext parameter is the Android application context - this is used to extract Picovoice resources from the APK. The Builder also allows you to override the default model files and/or the sensitivities:

PicovoiceManager manager = new PicovoiceManager(
.setKeywordPath("path/to/keyword/file.ppn")
.setWakeWordCallback(wakeWordCallback)
.setContextPath("path/to/context/file.rhn")
.setInferenceCallback(inferenceCallback)
.setPorcupineModelPath("path/to/porcupine/model.pv")
.setPorcupineSensitivity(0.7f)
.setRhinoModelPath("path/to/rhino/model.pv")
.setRhinoSensitivity(0.35f)
.build(appContext);
);

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 associated engine. To change the language that the engine understands you'll have to provide a model file for that language.

Once you have instantiated a PicovoiceManager, you can start audio capture and voice recognition by calling:

manager.start();

Stop the manager with:

manager.stop();

Low-Level API

Picovoice.java provides a low-level binding for Android. It can be initialized using the Picovoice Builder:

import ai.picovoice.picovoice.*;
final String porcupineModelPath = ...
final String keywordPath = ...
final float porcupineSensitivity = 0.5f;
final String rhinoModelPath = ...
final String contextPath = ...
final float rhinoSensitivity = 0.5f;
try {
Picovoice picovoice = new Picovoice.Builder()
.setPorcupineModelPath(porcupineModelPath)
.setKeywordPath(keywordPath)
.setPorcupineSensitivity(porcupineSensitivity)
.setWakeWordCallback(new PicovoiceWakeWordCallback() {
@Override
public void invoke() {
// logic to execute upon deletection of wake word
}
})
.setRhinoModelPath(rhinoModelPath)
.setContextPath(contextPath)
.setRhinoSensitivity(rhinoSensitivity)
.setInferenceCallback(new PicovoiceInferenceCallback() {
@Override
public void invoke(final RhinoInference inference) {
// logic to execute upon completion of intent inference
}
})
.build(appContext);
} catch(PicovoiceException ex) { }

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 associated engine. To change the language that the engine understands you'll have to provide a model file for that language.

Once initialized, picovoice can be used to process incoming audio.

private short[] getNextAudioFrame();
while (true) {
try {
picovoice.process(getNextAudioFrame());
} catch (PicovoiceException e) {
// error handling logic
}
}

For process to work correctly, the audio data must be in the audio format required by Picovoice. The required audio format is found by calling .getSampleRate() to get the required sample rate and .getFrameLength() to get the required number of samples per input frame. Audio must be single-channel and 16-bit linearly-encoded.

Finally, be sure to explicitly release resources acquired as the binding class does not rely on the garbage collector for releasing native resources.

picovoice.delete();

Custom Wake Words & Contexts

You can create custom Porcupine wake word and Rhino context models using Picovoice Console

Custom Model Integration

To add a custom model to your Android application a couple of extra steps must be taken. First, add your model file to the /res/raw folder. All resources are compressed when the build system creates an APK, so you will have to extract your file first before using it:

try (
InputStream is = new BufferedInputStream(
getResources().openRawResource(R.raw.keyword), 256);
OutputStream os = new BufferedOutputStream(
openFileOutput(modelFileName, Context.MODE_PRIVATE), 256)
) {
int r;
while ((r = is.read()) != -1) {
os.write(r);
}
os.flush();
}

Non-English Models

In order to detect wake words and run inference in other languages you need to use the corresponding model file. The model files for all supported languages are available here and here.


Issue with this doc? Please let us know.