If you find adding voice inputs to a Java application difficult, you're not alone. JDK's Speech API relies on outdated products and third-party cloud providers.
But we have a good news, on day 37, we'll add custom voice commands, like Jarvis, turn off the lights
, with Picovoice Java SDK.
The Picovoice SDK combines Porcupine Wake Word and Rhino Speech-to-Intent engines. Wake words like Jarvis
, powered by Porcupine and follow-up commands like turn off the lights
powered by Rhino.
Let's get started
- Get the latest version of the SDK from Maven Central Repository:
ai.picovoice:picovoice-java:${version}
- Design and train models on the Picovoice Platform
While developers can train and adapt custom voice AI models on the Picovoice Console. However, you can use pre-trained ones, too! For this tutorial, we'll use the pre-trained
[Jarvis](https://github.com/Picovoice/porcupine/tree/master/resources/keyword_files)
wake word and the[Smart Lighting](https://github.com/Picovoice/rhino/tree/master/resources/contexts)
context, which understands commands that change the color/state of lights. - Get an AccessKey Picovoice
If you still haven't, create an account on the Picovoice Console for free and grab your
AccessKey
. - Initialize the Picovoice Platform
import ai.picovoice.picovoice.*;
final String accessKey = "..."; // your Picovoice AccessKey
final String keywordPath = "res/path/to/jarvis.ppn";
final String contextPath = "res/path/to/smart_lighting.rhn";
PicovoiceWakeWordCallback wakeWordCallback = () -> {
System.out.println("Wake word detected!");
// let user know wake word was detected
};
PicovoiceInferenceCallback inferenceCallback = inference -> {
if (inference.getIsUnderstood()) {
final String intent = inference.getIntent();
final Map<String, String> slots = inference.getSlots();
// use intent and slots to trigger action
}
};
Picovoice picovoice = new Picovoice.Builder()
.setAccessKey(accessKey)
.setKeywordPath(keywordPath)
.setWakeWordCallback(wakeWordCallback)
.setContextPath(contextPath)
.setInferenceCallback(inferenceCallback)
.build();
Do not forget to replace AccessKey
, KeywordPath
, and ContextPath
placeholders. Copy your AccessKey from Picovoice Console. The path for the downloaded Porcupine keyword and Rhino Context files, depends on where you save them when you download.
- Read and Process Microphone Audio
import javax.sound.sampled.*;
// get default audio capture device
AudioFormat format = new AudioFormat(16000f, 16, 1, true, false);
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine micDataLine;
try {
micDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
micDataLine.open(format);
} catch (LineUnavailableException e) {
System.err.println("Failed to get a valid audio capture device.");
return;
}
// start audio capture
micDataLine.start();
- Create a loop that reads microphone data and passes it to Picovoice:
// buffers for processing audio
short[] picovoiceBuffer = new short[picovoice.getFrameLength()];
ByteBuffer captureBuffer = ByteBuffer.allocate(picovoice.getFrameLength() * 2);
captureBuffer.order(ByteOrder.LITTLE_ENDIAN);
int numBytesRead;
boolean recordingCancelled = false;
while (!recordingCancelled) {
// read a buffer of audio
numBytesRead = micDataLine.read(captureBuffer.array(), 0, captureBuffer.capacity());
// don't pass to Picovoice if we don't have a full buffer
if (numBytesRead != picovoice.getFrameLength() * 2) {
continue;
}
// copy into 16-bit buffer
captureBuffer.asShortBuffer().get(picovoiceBuffer);
// process with picovoice
picovoice.process(picovoiceBuffer);
}
This tutorial was originally published on Medium
Resources:
Source Code
Picovoice
Picovoice Java SDK (https://picovoice.ai/docs/quick-start/picovoice-java/)
Top comments (0)