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)