diff --git a/README.md b/README.md index 4f269ae2e..ee8a0d84f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Made in Vancouver, Canada by [Picovoice](https://picovoice.ai) -Rhino is Picovoice's Speech-to-Intent engine. It directly infers intent from speech commands within a given context of +Rhino is Picovoice's Speech-to-Intent engine. It directly infers intent from spoken commands within a given context of interest in real-time. For example, given a speech command "*Can I have a small double-shot espresso with a lot of sugar and some milk*" it infers that the user wants to *order a drink* with the following specific requirements. @@ -20,16 +20,15 @@ Rhino is * intuitive. It allows users to utter their intention in a natural and conversational fashion. * using deep neural networks trained in **real-world situations**. -* compact and computationally-efficient making it suitable for **IoT** applications. It can run with as low as 100 KB of RAM. -* cross-platform. It is implemented in fixed-point ANSI C. Currently **ARM Cortex-M**, **ARM Cortex-A**, -**Raspberry Pi**, **Android**, **iOS**, **watchOS**, **Linux**, **Mac**, **Windows**, and **WebAssembly** are supported. +* compact and computationally-efficient making it suitable for **IoT** applications. It can run with as low as 90 KB of +RAM on an MCU. +* cross-platform. It is implemented in fixed-point ANSI C. Currently **Raspberry Pi**, **Beagle Bone** **Android**, +**iOS**, **Linux**, **Mac**, **Windows**, and **web browsers** (**WebAssembly**) are supported. Additionally support for +various **ARM Cortex-A**, **ARM Cortex-M** (M4/M7) and **DSP cores** is available for commercial customers. * customizable. It can be customized for any given domain. [![Rhino in Action](https://img.youtube.com/vi/WadKhfLyqTQ/0.jpg)](https://www.youtube.com/watch?v=WadKhfLyqTQ) -NOTE: Currently Raspberry Pi, Android, and Linux builds are available to the open-source community. But we do have plans -to make other platforms available as well in upcoming releases. - ## Table of Contents * [Try It Out](#try-it-out) * [Motivation](#motivation) @@ -43,9 +42,11 @@ to make other platforms available as well in upcoming releases. * [Running Demo Applications](#running-demo-applications) * [Running Python Demo Application](#running-python-demo-application) * [Running C Demo Application](#running-c-demo-application) + * [Runnning Android Demo Application](#running-android-demo-application) * [Integration](#integration) * [C](#c) * [Python](#python) + * [Android](#android) * [Releases](#releases) * [License](#license) @@ -64,17 +65,17 @@ requires significant CPU and memory for an on-device implementation. Rhino solves this problem by providing a tightly-coupled speech recognition and NLU engine that are jointly optimized for a specific domain (use case). Rhino is quite lean and can even run on small embedded processors -(think ARM Cortex-M or fixed-point DSPs) with very limited RAM (as low as 100 KB) making it ideal for +(think ARM Cortex-M or fixed-point DSPs) with very limited RAM (as low as 90 KB) making it ideal for resource-constrained IoT applications. ## Metrics -The table shows the average CPU usage on three different platforms (1) Raspberry Pi zero, (2) Raspberry Pi 3, and an -Ubuntu box (i5-6500 CPU @ 3.20GHz). You can recreate this using the [C demo application](/demo/c). +The table shows the average CPU usage on two different platforms (1) Raspberry Pi zero and (2) Raspberry Pi 3. You can +recreate this using the [C demo application](/demo/c). -Raspberry Pi zero | Raspberry Pi 3 | Ubuntu Desktop (i5-6500 CPU @ 3.20GHz) -:---: | :---: | :---: -48.7% | 8.9% | 1.2% +Raspberry Pi zero | Raspberry Pi 3 +:---: | :---: +46.4% | 7.2% ## Terminology @@ -93,8 +94,8 @@ of spoken commands: ### Expression -A context is made of a collection of spoken commands mapped to the user's intent. An expression is an entity that defines a mapping between -a (or a set of) spoken commands and its (their) corresponding intent. For example +A context is made of a collection of spoken commands mapped to the user's intent. An expression is an entity that defines +a mapping between a (or a set of) spoken commands and its (their) corresponding intent. For example * {turnCommand} the lights. -> {turnIntent} * Make the {location} light {intensityChange}. -> {changeIntensityIntent} @@ -143,7 +144,7 @@ python demo/python/rhino_demo.py \ --rhino_context_file_path ./resources/contexts/linux/coffee_maker_linux.rhn \ --porcupine_library_path ./resources/porcupine/lib/linux/x86_64/libpv_porcupine.so \ --porcupine_model_file_path ./resources/porcupine/lib/common/porcupine_params.pv \ ---porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn +--porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey\ pico_linux.ppn ``` The following runs the engine on a *Raspberry Pi 3* to infer intent within the context of smart lighting system @@ -155,7 +156,7 @@ python demo/python/rhino_demo.py \ --rhino_context_file_path ./resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn \ --porcupine_library_path ./resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.so \ --porcupine_model_file_path ./resources/porcupine/lib/common/porcupine_params.pv \ ---porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/raspberrypi/hey_alfred_raspberrypi.ppn +--porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/raspberrypi/hey\ pico_raspberrypi.ppn ``` ### Running C Demo Application @@ -163,6 +164,11 @@ python demo/python/rhino_demo.py \ This [demo application](demo/c) is mainly used to show how Rhino can be integrated into an efficient C/C++ application. Furthermore it can be used to measure runtime metrics of the engine on various supported platforms. +### Running Android Demo Application + +Using Android Studio open [demo/android](/demo/android) as an Android project and then run the application. Note that +you need an android phone with developer options enabled connected to your machine in order to run the application. + ## Integration Below are code snippets showcasing how Rhino can be integrated into different applications. @@ -282,8 +288,52 @@ collector. rhino.delete() ``` +### Android + +Rhino provides a binding for Android using JNI. It can be initialized using. + +```java + final String modelFilePath = ... // It is available at lib/common/rhino_params.pv + final String contextFilePath = ... + + Rhino rhino = new Rhino(modelFilePath, contextFilePath); +``` + +once initialized `rhino` can be used for intent inference. + + +```java + private short[] getNextAudioFrame(); + + while (rhino.process(getNextAudioFrame())); + + if (rhino.isUnderstood()) { + RhinoIntent intent = rhino.getIntent(); + // logic to perform an action given the intent object. + } else { + // logic for handling out of context or unrecognized command + } +``` + +when finalized the processing be sure to reset the object before processing a new stream of audio via + +```java + rhino.reset() +``` + +finally, prior to exiting the application be sure to release resources acquired via + +```java + rhino.delete() +``` + ## Releases +### v1.2.0 April 26, 2019 + +* Accuracy improvements. +* Runtime optimizations. + ### v1.1.0 December 23rd, 2018 * Accuracy improvements. diff --git a/binding/android/rhino/src/main/java/ai/picovoice/rhino/Rhino.java b/binding/android/rhino/src/main/java/ai/picovoice/rhino/Rhino.java index 739d34490..d16ad234f 100644 --- a/binding/android/rhino/src/main/java/ai/picovoice/rhino/Rhino.java +++ b/binding/android/rhino/src/main/java/ai/picovoice/rhino/Rhino.java @@ -17,19 +17,18 @@ package ai.picovoice.rhino; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; /** - * Binding for Picovoice's speech-to-intent engine (aka Rhino). - * The object directly infers intent from speech commands within a given context of interest in - * real-time. It processes incoming audio in consecutive frames (chunks) and at the end of each - * frame indicates if the intent extraction is finalized. When finalized, the intent can be - * retrieved as structured data in form of an intent string and pairs of slots and values - * representing arguments (details) of intent. The number of samples per frame can be attained by - * calling {@link #frameLength()}. The incoming audio needs to have a sample rate equal to - * {@link #sampleRate()} and be 16-bit linearly-encoded. Furthermore, Rhino operates on single - * channel audio. + * Binding for Picovoice's speech-to-intent engine (aka Rhino). The object directly infers intent + * from speech commands within a given context of interest in real-time. It processes incoming audio + * in consecutive frames (chunks) and at the end of each frame indicates if the intent extraction is + * finalized. When finalized, the intent can be retrieved as structured data in form of an intent + * string and pairs of slots and values representing arguments (details) of intent. The number of + * samples per frame can be attained by calling {@link #frameLength()}. The incoming audio needs to + * have a sample rate equal to {@link #sampleRate()} and be 16-bit linearly-encoded. Furthermore, + * Rhino operates on single channel audio. */ public class Rhino { static { @@ -40,10 +39,11 @@ public class Rhino { /** * Constructor. - * @param modelFilePath Absolute path to file containing model parameters. - * @param contextFilePath Absolute path to file containing context parameters. A context - * represents the set of expressions (commands), intents, and intent - * arguments (slots) within a domain of interest. + * + * @param modelFilePath Absolute path to file containing model parameters. + * @param contextFilePath Absolute path to file containing context parameters. A context + * represents the set of expressions (commands), intents, and intent + * arguments (slots) within a domain of interest. * @throws RhinoException On failure. */ public Rhino(String modelFilePath, String contextFilePath) throws RhinoException { @@ -55,7 +55,8 @@ public Rhino(String modelFilePath, String contextFilePath) throws RhinoException } /** - * Destructor. This is needs to be called explicitly as we do not rely on garbage collector. + * Destructor. This needs to be called explicitly as we do not rely on garbage collector. + * * @throws RhinoException On failure. */ public void delete() throws RhinoException { @@ -69,7 +70,8 @@ public void delete() throws RhinoException { /** * Processes a frame of audio and emits a flag indicating if the engine has finalized intent * extraction. When finalized, {@link #isUnderstood()} should be called to check if the command - * was valid (is within context of interest). + * was valid (is within context of interest) and is understood. + * * @param pcm A frame of audio samples. The number of samples per frame can be attained by * calling {@link #frameLength()}. The incoming audio needs to have a sample rate * equal to {@link #sampleRate()} and be 16-bit linearly-encoded. Furthermore, @@ -79,7 +81,7 @@ public void delete() throws RhinoException { */ public boolean process(short[] pcm) throws RhinoException { try { - return process(object, pcm) == 1; + return process(object, pcm); } catch (Exception e) { throw new RhinoException(e); } @@ -88,13 +90,14 @@ public boolean process(short[] pcm) throws RhinoException { /** * Indicates if the spoken command is valid, is within the domain of interest (context), and the * engine understood it. + * * @return Flag indicating if the spoken command is valid, is within the domain of interest * (context), and the engine understood it. * @throws RhinoException On failure. */ public boolean isUnderstood() throws RhinoException { try { - return isUnderstood(object) == 1; + return isUnderstood(object); } catch (Exception e) { throw new RhinoException(e); } @@ -105,6 +108,7 @@ public boolean isUnderstood() throws RhinoException { * string and pairs of slots and their values. It should be called only after intent extraction * is finalized and it is verified that the spoken command is valid and understood via calling * {@link #isUnderstood()}. + * * @return Inferred intent object. * @throws RhinoException On failure. */ @@ -112,14 +116,14 @@ public RhinoIntent getIntent() throws RhinoException { final String intentPacked = getIntent(object); String[] parts = intentPacked.split(","); if (parts.length == 0) { - throw new RhinoException(String.format("Failed to retrieve intent from %s", intentPacked)); + throw new RhinoException(String.format("failed to retrieve intent from %s", intentPacked)); } - Map slots = new HashMap<>(); + Map slots = new LinkedHashMap<>(); for (int i = 1; i < parts.length; i++) { String[] slotAndValue = parts[i].split(":"); if (slotAndValue.length != 2) { - throw new RhinoException(String.format("Failed to retrieve intent from %s", intentPacked)); + throw new RhinoException(String.format("failed to retrieve intent from %s", intentPacked)); } slots.put(slotAndValue[0], slotAndValue[1]); } @@ -130,6 +134,7 @@ public RhinoIntent getIntent() throws RhinoException { /** * Resets the internal state of the engine. It should be called before the engine can be used to * infer intent from a new stream of audio. + * * @throws RhinoException On failure. */ public void reset() throws RhinoException { @@ -143,6 +148,7 @@ public void reset() throws RhinoException { /** * Getter for expressions. Each expression maps a set of spoken phrases to an intent and * possibly a number of slots (intent arguments). + * * @return Expressions. * @throws RhinoException On failure. */ @@ -154,35 +160,38 @@ public String getContextExpressions() throws RhinoException { } } - private native long init(String model_file_path, String context_file_path); - - private native long delete(long object); - - private native int process(long object, short[] pcm); - - private native int isUnderstood(long object); - - private native String getIntent(long object); - - private native boolean reset(long object); - - private native String contextExpressions(long object); - /** * Getter for length (number of audio samples) per frame. + * * @return Frame length. */ public native int frameLength(); /** * Audio sample rate accepted by Picovoice. + * * @return Sample rate. */ public native int sampleRate(); /** * Getter for version string. + * * @return Version string. */ public native String version(); + + private native long init(String model_file_path, String context_file_path); + + private native void delete(long object); + + private native boolean process(long object, short[] pcm); + + private native boolean isUnderstood(long object); + + private native String getIntent(long object); + + private native boolean reset(long object); + + private native String contextExpressions(long object); } diff --git a/binding/python/rhino.py b/binding/python/rhino.py index e881e7371..f5ba9b37d 100644 --- a/binding/python/rhino.py +++ b/binding/python/rhino.py @@ -20,7 +20,7 @@ class Rhino(object): - """Python binding for Picovoice's Speech to Intent (a.k.a Rhino) engine.""" + """Python binding for Picovoice's Speech-to-Intent (a.k.a Rhino) engine.""" class PicovoiceStatuses(Enum): """Status codes corresponding to 'pv_status_t' defined in 'include/picovoice.h'""" diff --git a/binding/python/test_rhino.py b/binding/python/test_rhino.py index f160e0f4c..c3d65ca55 100644 --- a/binding/python/test_rhino.py +++ b/binding/python/test_rhino.py @@ -88,25 +88,34 @@ def _library_path(cls): system = platform.system() machine = platform.machine() - if system == 'Linux': + if system == 'Darwin': + return cls._abs_path('lib/mac/x86_64/libpv_rhino.dylib') + elif system == 'Linux': if machine == 'x86_64': return cls._abs_path('lib/linux/x86_64/libpv_rhino.so') elif machine.startswith('arm'): return cls._abs_path('lib/raspberry-pi/arm11/libpv_rhino.so') - - raise NotImplementedError('Rhino is not supported on %s/%s yet!' % (system, machine)) + elif system == 'Windows': + return cls._abs_path('lib/windows/amd64/libpv_rhino.dll') + else: + raise NotImplementedError('Rhino is not supported on %s/%s yet!' % (system, machine)) @classmethod def _context_file_path(cls): system = platform.system() machine = platform.machine() - if system == 'Linux' and machine == 'x86_64': - return cls._abs_path('resources/contexts/linux/coffee_maker_linux.rhn') - elif system == 'Linux' and machine.startswith('arm'): - return cls._abs_path('resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn') - - raise NotImplementedError('Rhino is not supported on %s/%s yet!' % (system, machine)) + if system == 'Darwin': + return cls._abs_path('resources/contexts/mac/coffee_maker_mac.rhn') + elif system == 'Linux': + if machine == 'x86_64': + return cls._abs_path('resources/contexts/linux/coffee_maker_linux.rhn') + elif machine.startswith('arm'): + return cls._abs_path('resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn') + elif system == 'Windows': + return cls._abs_path('resources/contexts/windows/coffee_maker_windows.rhn') + else: + raise NotImplementedError('Rhino is not supported on %s/%s yet!' % (system, machine)) if __name__ == '__main__': diff --git a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioConsumer.java b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioConsumer.java index 1dcb03a2d..bafba9106 100644 --- a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioConsumer.java +++ b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioConsumer.java @@ -22,6 +22,7 @@ interface AudioConsumer { /** * Consumes (processes) a frame of audio. + * * @param pcm Audio PCM. * @throws Exception On failure. */ @@ -29,12 +30,14 @@ interface AudioConsumer { /** * Getter for valid number of samples per frame. + * * @return Valid number of samples per frame. */ int getFrameLength(); /** * Getter for valid sample rate. + * * @return Valid sample rate. */ int getSampleRate(); diff --git a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioRecorder.java b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioRecorder.java index f8fbfcb3e..ccc14cfb7 100644 --- a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioRecorder.java +++ b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/AudioRecorder.java @@ -52,6 +52,7 @@ public Void call() throws Exception { /** * Constructor. + * * @param audioConsumer The consumer for recorded audio. */ AudioRecorder(AudioConsumer audioConsumer) { @@ -72,6 +73,7 @@ void start() { /** * Stops the recording of audio. + * * @throws InterruptedException On failure. */ void stop() throws InterruptedException { @@ -81,7 +83,7 @@ void stop() throws InterruptedException { stop.set(true); while (!stopped.get()) { - Thread.sleep(10); + Thread.sleep(32); } started.set(false); @@ -111,7 +113,7 @@ record = new AudioRecord( if (numRead == frame.length) { audioConsumer.consume(frame); } else { - Log.w(TAG, "Not enough samples for the audio consumer."); + Log.w(TAG, "not enough samples for the audio consumer."); } } record.stop(); diff --git a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoAudioConsumer.java b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoAudioConsumer.java index e164f982f..ec65aa858 100644 --- a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoAudioConsumer.java +++ b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoAudioConsumer.java @@ -31,9 +31,10 @@ public class RhinoAudioConsumer implements AudioConsumer { /** * Constructor. - * @param modelFilePath Absolute path to model file. + * + * @param modelFilePath Absolute path to model file. * @param contextFilePath Absolute path to context file. - * @param callback Callback to be executed upon inference of the intent. + * @param callback Callback to be executed upon inference of the intent. * @throws RhinoException On failure. */ RhinoAudioConsumer(String modelFilePath, String contextFilePath, RhinoCallback callback) throws RhinoException { @@ -43,6 +44,7 @@ public class RhinoAudioConsumer implements AudioConsumer { /** * Releases resources acquired by Rhino. + * * @throws RhinoException On failure. */ void delete() throws RhinoException { @@ -77,6 +79,7 @@ public int getSampleRate() { /** * Resets the internal state of the engine. It should be called before the engine can be used * to infer intent from a new stream of audio. + * * @throws RhinoException On failure. */ void reset() throws RhinoException { diff --git a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoCallback.java b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoCallback.java index 547513154..36bb084aa 100644 --- a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoCallback.java +++ b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoCallback.java @@ -19,14 +19,15 @@ import ai.picovoice.rhino.RhinoIntent; /** - * Callback to be used by Rhino (Picovoice's speech to intent engine) upon inferring user's intent. + * Callback to be called by Rhino (Picovoice's speech to intent engine) upon inferring user's intent. */ public interface RhinoCallback { /** * Callback function. + * * @param isUnderstood Flag indicating if the spoken command is understood and is within domain * of interest. - * @param intent User's intent. + * @param intent User's intent. */ void run(final boolean isUnderstood, final RhinoIntent intent); } diff --git a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoDemoActivity.java b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoDemoActivity.java index a5c9d009d..1cb2caf3f 100644 --- a/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoDemoActivity.java +++ b/demo/android/RhinoDemo/app/src/main/java/ai/picovoice/rhinodemo/RhinoDemoActivity.java @@ -52,7 +52,6 @@ public class RhinoDemoActivity extends AppCompatActivity { private ToggleButton recordButton; private TextView intentTextView; - private AudioRecorder audioRecorder; private RhinoAudioConsumer rhinoAudioConsumer; @@ -80,11 +79,6 @@ private void copyResource(int resourceId, String filename) throws IOException { } } - private void copyResources() throws IOException { - copyResource(PARAM_ID, PARAM_FILENAME); - copyResource(CONTEXT_ID, CONTEXT_FILENAME); - } - private String getAbsolutePath(String filename) { return new File(this.getFilesDir(), filename).getAbsolutePath(); } @@ -105,18 +99,18 @@ public void run() { intentTextView.append(String.format("intent: %s\n", intent.getIntent())); final Map slots = intent.getSlots(); - for (String key: slots.keySet()) { + for (String key : slots.keySet()) { intentTextView.append(String.format("%s: %s\n", key, slots.get(key))); } } else { - intentTextView.setText("Spoken command is not understood.\n"); + intentTextView.setText("spoken command is not understood.\n"); } try { audioRecorder.stop(); rhinoAudioConsumer.reset(); } catch (Exception e) { - Log.e(TAG, "Failed to stop recording audio and reset Rhino"); + Log.e(TAG, "failed to stop recording audio and reset Rhino"); Log.e(TAG, e.getMessage()); } } @@ -131,12 +125,13 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_rhino_demo); try { - copyResources(); + copyResource(PARAM_ID, PARAM_FILENAME); + copyResource(CONTEXT_ID, CONTEXT_FILENAME); } catch (IOException e) { - Log.e(TAG, "Failed to copy resource files."); + Log.e(TAG, "failed to copy resource files."); Log.e(TAG, e.getMessage()); - Toast.makeText(this, "Failed to copy resource files.", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "failed to copy resource files.", Toast.LENGTH_SHORT).show(); } recordButton = findViewById(R.id.startButton); @@ -148,10 +143,20 @@ protected void onCreate(Bundle savedInstanceState) { try { initRhino(); } catch (Exception e) { - Log.e(TAG, "Failed to initialize Rhino."); + Log.e(TAG, "failed to initialize Rhino."); Log.e(TAG, e.getMessage()); - Toast.makeText(this, "Failed to initialize Rhino.", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "failed to initialize Rhino.", Toast.LENGTH_SHORT).show(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + try { + rhinoAudioConsumer.delete(); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @@ -169,7 +174,7 @@ public void onClick(View view) { audioRecorder.start(); } else { recordButton.toggle(); - Toast.makeText(this, "Does not have record permission.", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "does not have record permission.", Toast.LENGTH_SHORT).show(); } } else { audioRecorder.stop(); @@ -178,7 +183,7 @@ public void onClick(View view) { } catch (Exception e) { Log.e(TAG, e.getMessage()); - Toast.makeText(this, "Something went wrong.", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "something went wrong.", Toast.LENGTH_SHORT).show(); } } } diff --git a/demo/c/README.md b/demo/c/README.md index e77751049..08f41d06b 100644 --- a/demo/c/README.md +++ b/demo/c/README.md @@ -9,7 +9,7 @@ The following command compiles the demo. It has been tested on Ubuntu 16.04/18.0 Raspberry Pi. Note that you need to execute this from the root of the repository. ```bash -gcc -O3 -o demo/c/rhino_demo -I include demo/c/rhino_demo.c -lm -ldl --std-=c99 + gcc -O3 -o demo/c/rhino_demo -I include demo/c/rhino_demo.c -lm -ldl --std-=c99 ``` ## Run diff --git a/demo/python/README.md b/demo/python/README.md index d4f7fca8d..b3b35a04e 100644 --- a/demo/python/README.md +++ b/demo/python/README.md @@ -1,7 +1,7 @@ # Prerequisites -First, consult the prerequisites section of [Python binding](/binding/python). Additionally, demo application -uses [PyAudio](https://people.csail.mit.edu/hubert/pyaudio/) for recording input audio (i.e. microphone). +First, consult the prerequisites section of [Python binding](/binding/python). Additionally, demo application uses +[PyAudio](https://people.csail.mit.edu/hubert/pyaudio/) for recording input audio (i.e. microphone). Consult the installation guide at [PyAudio](https://people.csail.mit.edu/hubert/pyaudio/). # Demo Application @@ -21,11 +21,11 @@ python demo/python/rhino_demo.py \ --rhino_context_file_path ./resources/contexts/raspberrypi/smart_lighting_raspberrypi.rhn \ --porcupine_library_path ./resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.so \ --porcupine_model_file_path ./resources/porcupine/lib/common/porcupine_params.pv \ ---porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/raspberrypi/hey_alfred_raspberrypi.ppn +--porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/raspberrypi/hey\ pico_raspberrypi.ppn ``` It starts recording audio from the **default** input audio device, initializes instances of Porcupine and Rhino -engines, and monitors the incoming audio for the wake phrase **Hey Alfred**. Upon detection of the wake word the followup +engines, and monitors the incoming audio for the wake phrase **Hey Pico**. Upon detection of the wake word the followup command is processed by Rhino to infer user's intent and the inferred result is writen into the console. For running on a different platform you to use the corresponding platform-specific library paths, Porcupine keyword file, @@ -35,77 +35,45 @@ and Rhino context file. For example to run the same demo on a Linux box python demo/python/rhino_demo.py \ --rhino_library_path ./lib/linux/x86_64/libpv_rhino.so \ --rhino_model_file_path ./lib/common/rhino_params.pv \ ---rhino_context_file_path ./resources/contexts/linux/smart_lighting_linux.rhn \ +--rhino_context_file_path ./resources/contexts/linux/music_player_linux.rhn \ --porcupine_library_path ./resources/porcupine/lib/linux/x86_64/libpv_porcupine.so \ --porcupine_model_file_path ./resources/porcupine/lib/common/porcupine_params.pv \ ---porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn +--porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey\ pico_linux.ppn ``` Below is an example console output ``` -LIGHTING SYSTEM CONTEXT: - -EXPRESSIONS: - -{turnCommand} the light(s). -> {turnLight} -{turnCommand} the {location} light(s). -> {turnLight} -{turnCommand} the light(s) in the {location}. -> {turnLight} -make the light(s) {intensityChange}. -> {changeIntensity} -make the {location} light(s) {intensityChange}. -> {changeIntensity} -make the light(s) in the {location} {intensityChange}. -> {changeIntensity} -set the light(s) to {color}. -> changeColor -set the {location} light(s) to {color}. -> changeColor -set the light(s) in the {location} to {color}. -> changeColor - -SLOT VALUES: - -turnCommand: [turn off, turn on] -location: [attic, balcony, basement, bathroom, bedroom, corridor, den, entrance, kitchen, living room] -color: [blue, green, lavender, olive, pink, purple, red, silver, violet, white, yellow] -intensityChange: [brighter, darker] - -EXAMPLES: - -turn off the lights. -> (intent: turnLight, slots: {turnCommand: turn off}) -turn on the kitchen light. -> (intent: turnLight, slots: {location: kitchen}) -set the living room light to blue. -> (intent: changeColor, slots: {location: living room, color: blue}) -make the light in the attic brighter. -> (intent: changeIntensity, slots: {location: attic, intensityChange: brighter}) -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline -ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'defaults.bluealsa.device' -ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory -ALSA lib conf.c:4996:(snd_config_expand) Args evaluate error: No such file or directory -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM bluealsa -ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'defaults.bluealsa.device' -ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory -ALSA lib conf.c:4996:(snd_config_expand) Args evaluate error: No such file or directory -ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM bluealsa -ALSA lib pcm_hw.c:1713:(_snd_pcm_hw_open) Invalid value for card -ALSA lib pcm_hw.c:1713:(_snd_pcm_hw_open) Invalid value for card +****************************** context ****************************** + + +turnLight : {turnCommand} the lights +turnLight : {turnCommand} the {location} lights +turnLight : {turnCommand} the lights in the {location} +changeIntensity : make the lights {intensityChange} +changeIntensity : make the {location} lights {intensityChange} +changeIntensity : make the lights in the {location} {intensityChange} +changeColor : set the lights to {color} +changeColor : set the {location} lights to {color} +changeColor : set the lights in the {location} to {color} + + + +turnCommand : [turn off, turn on] +location : [attic, balcony, basement, bathroom, bedroom, corridor, den, entrance, kitchen, living room] +intensityChange : [brighter, darker] +color : [blue, green, lavender, olive, pink, purple, red, silver, violet, white, yellow] +********************************************************************* + +ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear +ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe +ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side +ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started -JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock -JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock +JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for 4294967295, skipping unlock +JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for 4294967295, skipping unlock ```` First, the demo outputs the information regarding the context of Rhino including supported expressions, slots, and their @@ -164,7 +132,7 @@ python demo/python/rhino_demo.py \ --rhino_context_file_path ./resources/contexts/linux/smart_lighting_linux.rhn \ --porcupine_library_path ./resources/porcupine/lib/linux/x86_64/libpv_porcupine.so \ --porcupine_model_file_path ./resources/porcupine/lib/common/porcupine_params.pv \ ---porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn +--porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey\ pico_linux.ppn --input_audio_device_index 10 ``` @@ -177,7 +145,7 @@ python demo/python/rhino_demo.py \ --rhino_context_file_path ./resources/contexts/linux/smart_lighting_linux.rhn \ --porcupine_library_path ./resources/porcupine/lib/linux/x86_64/libpv_porcupine.so \ --porcupine_model_file_path ./resources/porcupine/lib/common/porcupine_params.pv \ ---porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn +--porcupine_keyword_file_path ./resources/porcupine/resources/keyword_files/linux/hey\ pico_linux.ppn --input_audio_device_index 10 \ --output-path ~/test.wav ``` diff --git a/demo/python/rhino_demo.py b/demo/python/rhino_demo.py index 2d9cb384e..0671e6189 100644 --- a/demo/python/rhino_demo.py +++ b/demo/python/rhino_demo.py @@ -39,7 +39,7 @@ def _abs_path(rel_path): class RhinoDemo(Thread): """ - Demo class for Speech to Intent (aka Rhino) library. It creates an input audio stream from a microphone, monitors + Demo class for Speech-to-Intent (aka Rhino) library. It creates an input audio stream from a microphone, monitors it, and upon detecting the specified wake phrase extracts the intent from the speech command that follows. Wake word detection is done using Porcupine's wake word detection engine (https://github.com/Picovoice/Porcupine). """ @@ -113,7 +113,12 @@ def run(self): library_path=self._rhino_library_path, model_file_path=self._rhino_model_file_path, context_file_path=self._rhino_context_file_path) + + print() + print('****************************** context ******************************') print(rhino.context_expressions) + print('*********************************************************************') + print() pa = pyaudio.PyAudio() @@ -144,6 +149,7 @@ def run(self): else: if rhino.is_understood(): intent, slot_values = rhino.get_intent() + print() print('intent: %s' % intent) print('---') for slot, value in slot_values.items(): diff --git a/include/picovoice.h b/include/picovoice.h index afdb8828a..825216edb 100644 --- a/include/picovoice.h +++ b/include/picovoice.h @@ -18,8 +18,10 @@ #define PICOVOICE_H #ifdef __cplusplus + extern "C" { + #endif #define PV_API __attribute__((visibility ("default"))) @@ -42,8 +44,18 @@ typedef enum { PV_STATUS_INVALID_STATE, } pv_status_t; +/** + * Provides string representations of status codes. + * + * @param status Status code. + * @return String representation. + */ +const char *pv_status_to_string(pv_status_t status); + #ifdef __cplusplus + } + #endif #endif // PICOVOICE_H diff --git a/include/pv_rhino.h b/include/pv_rhino.h index 00aaeeeae..68df9749b 100644 --- a/include/pv_rhino.h +++ b/include/pv_rhino.h @@ -23,8 +23,10 @@ #include "picovoice.h" #ifdef __cplusplus + extern "C" { + #endif /** @@ -34,22 +36,10 @@ extern "C" * extraction is finalized. When finalized, the intent can be retrieved as structured data in form of an intent string * and pairs of slots and values representing arguments (details) of intent. The number of samples per frame can be * attained by calling 'pv_rhino_frame_length()'. The incoming audio needs to have a sample rate equal to - * 'pv_sample_rate()' and be 16-bit linearly-encoded. Furthermore, Rhino operates on single channel audio. + * 'pv_sample_rate()' and be 16-bit linearly-encoded. Furthermore, Rhino operates on single-channel audio. */ typedef struct pv_rhino_object pv_rhino_object_t; -#ifdef PV_RHINO_BAREMACHINE -/** - * Constructor. - * - * @param context Context parameters. A context represents the set of expressions (commands), intents, and intent - * arguments (slots) within a domain of interest. - * @param context_length Length of context in bytes. - * @param[out] object Constructed speech-to-intent object. - * @return Status code. Returns 'PV_STATUS_INVALID_ARGUMENT' or 'PV_STATUS_OUT_OF_MEMORY' on failure. - */ -PV_API pv_status_t pv_rhino_init(const void *context, int context_length, pv_rhino_object_t **object); -#else /** * Constructor. * @@ -60,8 +50,10 @@ PV_API pv_status_t pv_rhino_init(const void *context, int context_length, pv_rhi * @return Status code. Returns 'PV_STATUS_INVALID_ARGUMENT', 'PV_STATUS_IO_ERROR', or 'PV_STATUS_OUT_OF_MEMORY' on * failure. */ -PV_API pv_status_t pv_rhino_init(const char *model_file_path, const char *context_file_path, pv_rhino_object_t **object); -#endif +PV_API pv_status_t pv_rhino_init( + const char *model_file_path, + const char *context_file_path, + pv_rhino_object_t **object); /** * Destructor. @@ -101,16 +93,16 @@ PV_API pv_status_t pv_rhino_is_understood(const pv_rhino_object_t *object, bool * @param object Speech-to-intent object. * @param[out] intent Inferred intent. * @param[out] num_slots Number of slots. - * @param[out] slots Array of inferred slots. Its memory needs to be freed by the caller. + * @param[out] slots Array of inferred slots. Its memory needs to be freed by calling 'pv_rhino_free_slots_and_values()'. * @param[out] values Array of inferred slot values in the same order of inferred slots. Its memory needs to be freed - * by the caller. + * by calling 'pv_rhino_free_slots_and_values()'. * @return State code. Returns 'PV_STATUS_INVALID_ARGUMENT', 'PV_STATUS_INVALID_STATE', or 'PV_STATUS_OUT_OF_MEMORY' on * failure. */ PV_API pv_status_t pv_rhino_get_intent( const pv_rhino_object_t *object, const char **intent, - int *num_slots, + int32_t *num_slots, const char ***slots, const char ***values); @@ -147,8 +139,22 @@ PV_API const char *pv_rhino_version(void); */ PV_API int pv_rhino_frame_length(void); +/** + * Frees memory resources allocated to returned slots and their corresponding values after calling + * 'pv_rhino_get_intent()'. Note that you can't and shouldn't free these resources via standard C library 'free()'. + * + * @param object Speech-to-intent object. + * @param slots Slots + * @param values Slot values. + * + * @return Returns 'PV_STATUS_INVALID_ARGUMENT' on failure. + */ +PV_API pv_status_t pv_rhino_free_slots_and_values(const pv_rhino_object_t *object, const char **slots, const char **values); + #ifdef __cplusplus + } + #endif #endif // PV_RHINO_H diff --git a/lib/android/arm64-v8a/libpv_rhino.so b/lib/android/arm64-v8a/libpv_rhino.so index f5aa57f6f..675c44515 100644 Binary files a/lib/android/arm64-v8a/libpv_rhino.so and b/lib/android/arm64-v8a/libpv_rhino.so differ diff --git a/lib/android/armeabi-v7a/libpv_rhino.so b/lib/android/armeabi-v7a/libpv_rhino.so index 61cb888ef..c21d87426 100644 Binary files a/lib/android/armeabi-v7a/libpv_rhino.so and b/lib/android/armeabi-v7a/libpv_rhino.so differ diff --git a/lib/android/x86/libpv_rhino.so b/lib/android/x86/libpv_rhino.so index da1a55187..b9f649dc2 100644 Binary files a/lib/android/x86/libpv_rhino.so and b/lib/android/x86/libpv_rhino.so differ diff --git a/lib/android/x86_64/libpv_rhino.so b/lib/android/x86_64/libpv_rhino.so index c4de89ae9..b18fac151 100644 Binary files a/lib/android/x86_64/libpv_rhino.so and b/lib/android/x86_64/libpv_rhino.so differ diff --git a/lib/beaglebone/libpv_rhino.so b/lib/beaglebone/libpv_rhino.so new file mode 100755 index 000000000..c024d0efe Binary files /dev/null and b/lib/beaglebone/libpv_rhino.so differ diff --git a/lib/common/rhino_params.pv b/lib/common/rhino_params.pv index 821bcd95c..6dd27d0ff 100644 Binary files a/lib/common/rhino_params.pv and b/lib/common/rhino_params.pv differ diff --git a/lib/linux/x86_64/libpv_rhino.so b/lib/linux/x86_64/libpv_rhino.so index 48e4eca5a..16cd445f2 100755 Binary files a/lib/linux/x86_64/libpv_rhino.so and b/lib/linux/x86_64/libpv_rhino.so differ diff --git a/lib/mac/x86_64/libpv_rhino.dylib b/lib/mac/x86_64/libpv_rhino.dylib new file mode 100755 index 000000000..80f1eb45d Binary files /dev/null and b/lib/mac/x86_64/libpv_rhino.dylib differ diff --git a/lib/raspberry-pi/arm11/libpv_rhino.so b/lib/raspberry-pi/arm11/libpv_rhino.so index f4c0a5702..4522f9f7d 100755 Binary files a/lib/raspberry-pi/arm11/libpv_rhino.so and b/lib/raspberry-pi/arm11/libpv_rhino.so differ diff --git a/lib/raspberry-pi/cortex-a53/libpv_rhino.so b/lib/raspberry-pi/cortex-a53/libpv_rhino.so index f4c8e9f18..edc967ec9 100755 Binary files a/lib/raspberry-pi/cortex-a53/libpv_rhino.so and b/lib/raspberry-pi/cortex-a53/libpv_rhino.so differ diff --git a/lib/raspberry-pi/cortex-a7/libpv_rhino.so b/lib/raspberry-pi/cortex-a7/libpv_rhino.so index 77f4db3f2..917063879 100755 Binary files a/lib/raspberry-pi/cortex-a7/libpv_rhino.so and b/lib/raspberry-pi/cortex-a7/libpv_rhino.so differ diff --git a/lib/windows/libpv_rhino.dll b/lib/windows/libpv_rhino.dll new file mode 100644 index 000000000..eb5dc1603 Binary files /dev/null and b/lib/windows/libpv_rhino.dll differ diff --git a/resources/contexts/android/coffee_maker_android.rhn b/resources/contexts/android/coffee_maker_android.rhn index 5cd323031..7ae53780e 100644 Binary files a/resources/contexts/android/coffee_maker_android.rhn and b/resources/contexts/android/coffee_maker_android.rhn differ diff --git a/resources/contexts/android/music_player_android.rhn b/resources/contexts/android/music_player_android.rhn index bfb7b56e5..04dff1ff0 100644 Binary files a/resources/contexts/android/music_player_android.rhn and b/resources/contexts/android/music_player_android.rhn differ diff --git a/resources/contexts/android/smart_lighting_android.rhn b/resources/contexts/android/smart_lighting_android.rhn index 98d0d3cbe..d5b21dd24 100644 Binary files a/resources/contexts/android/smart_lighting_android.rhn and b/resources/contexts/android/smart_lighting_android.rhn differ diff --git a/resources/contexts/beaglebone/coffee_maker_beaglebone.rhn b/resources/contexts/beaglebone/coffee_maker_beaglebone.rhn new file mode 100644 index 000000000..3f03d8299 Binary files /dev/null and b/resources/contexts/beaglebone/coffee_maker_beaglebone.rhn differ diff --git a/resources/contexts/beaglebone/music_player_beaglebone.rhn b/resources/contexts/beaglebone/music_player_beaglebone.rhn new file mode 100644 index 000000000..55cf60e9f Binary files /dev/null and b/resources/contexts/beaglebone/music_player_beaglebone.rhn differ diff --git a/resources/contexts/beaglebone/smart_lighting_beaglebone.rhn b/resources/contexts/beaglebone/smart_lighting_beaglebone.rhn new file mode 100644 index 000000000..b32ab7569 Binary files /dev/null and b/resources/contexts/beaglebone/smart_lighting_beaglebone.rhn differ diff --git a/resources/contexts/linux/coffee_maker_linux.rhn b/resources/contexts/linux/coffee_maker_linux.rhn index 5ec24dffb..cb67cd0fc 100644 Binary files a/resources/contexts/linux/coffee_maker_linux.rhn and b/resources/contexts/linux/coffee_maker_linux.rhn differ diff --git a/resources/contexts/linux/music_player_linux.rhn b/resources/contexts/linux/music_player_linux.rhn index 4fa6aef87..098c879a7 100644 Binary files a/resources/contexts/linux/music_player_linux.rhn and b/resources/contexts/linux/music_player_linux.rhn differ diff --git a/resources/contexts/linux/smart_lighting_linux.rhn b/resources/contexts/linux/smart_lighting_linux.rhn index 310d36360..3ae29e9de 100644 Binary files a/resources/contexts/linux/smart_lighting_linux.rhn and b/resources/contexts/linux/smart_lighting_linux.rhn differ diff --git a/resources/contexts/mac/coffee_maker_mac.rhn b/resources/contexts/mac/coffee_maker_mac.rhn new file mode 100644 index 000000000..0f53e08b8 Binary files /dev/null and b/resources/contexts/mac/coffee_maker_mac.rhn differ diff --git a/resources/contexts/mac/music_player_mac.rhn b/resources/contexts/mac/music_player_mac.rhn new file mode 100644 index 000000000..48798241f Binary files /dev/null and b/resources/contexts/mac/music_player_mac.rhn differ diff --git a/resources/contexts/mac/smart_lighting_mac.rhn b/resources/contexts/mac/smart_lighting_mac.rhn new file mode 100644 index 000000000..bfc0e4424 Binary files /dev/null and b/resources/contexts/mac/smart_lighting_mac.rhn differ diff --git a/resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn b/resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn index fa05e0436..d2b246581 100644 Binary files a/resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn and b/resources/contexts/raspberrypi/coffee_maker_raspberrypi.rhn differ diff --git a/resources/contexts/raspberrypi/music_player_raspberrypi.rhn b/resources/contexts/raspberrypi/music_player_raspberrypi.rhn index 3972f86f7..f25f28cba 100644 Binary files a/resources/contexts/raspberrypi/music_player_raspberrypi.rhn and b/resources/contexts/raspberrypi/music_player_raspberrypi.rhn differ diff --git a/resources/contexts/raspberrypi/smart_lighting_raspberrypi.rhn b/resources/contexts/raspberrypi/smart_lighting_raspberrypi.rhn index 15c609a9a..10c0f433c 100644 Binary files a/resources/contexts/raspberrypi/smart_lighting_raspberrypi.rhn and b/resources/contexts/raspberrypi/smart_lighting_raspberrypi.rhn differ diff --git a/resources/contexts/windows/coffee_maker_windows.rhn b/resources/contexts/windows/coffee_maker_windows.rhn new file mode 100644 index 000000000..854e15ecf Binary files /dev/null and b/resources/contexts/windows/coffee_maker_windows.rhn differ diff --git a/resources/contexts/windows/music_player_windows.rhn b/resources/contexts/windows/music_player_windows.rhn new file mode 100644 index 000000000..514c23627 Binary files /dev/null and b/resources/contexts/windows/music_player_windows.rhn differ diff --git a/resources/contexts/windows/smart_lighting_windows.rhn b/resources/contexts/windows/smart_lighting_windows.rhn new file mode 100644 index 000000000..487ca3663 Binary files /dev/null and b/resources/contexts/windows/smart_lighting_windows.rhn differ diff --git a/resources/porcupine/lib/beaglebone/libpv_porcupine.so b/resources/porcupine/lib/beaglebone/libpv_porcupine.so new file mode 100755 index 000000000..1de826940 Binary files /dev/null and b/resources/porcupine/lib/beaglebone/libpv_porcupine.so differ diff --git a/resources/porcupine/lib/common/porcupine_params.pv b/resources/porcupine/lib/common/porcupine_params.pv index 7206be899..4d88bb5a2 100644 Binary files a/resources/porcupine/lib/common/porcupine_params.pv and b/resources/porcupine/lib/common/porcupine_params.pv differ diff --git a/resources/porcupine/lib/linux/x86_64/libpv_porcupine.so b/resources/porcupine/lib/linux/x86_64/libpv_porcupine.so index 159602de0..521fc8813 100755 Binary files a/resources/porcupine/lib/linux/x86_64/libpv_porcupine.so and b/resources/porcupine/lib/linux/x86_64/libpv_porcupine.so differ diff --git a/resources/porcupine/lib/mac/x86_64/libpv_porcupine.dylib b/resources/porcupine/lib/mac/x86_64/libpv_porcupine.dylib new file mode 100755 index 000000000..e400d56b5 Binary files /dev/null and b/resources/porcupine/lib/mac/x86_64/libpv_porcupine.dylib differ diff --git a/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.a b/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.a index 10d9abf3a..3e9a37a49 100644 Binary files a/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.a and b/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.a differ diff --git a/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.so b/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.so index d1ea1fef8..d287bb9d3 100755 Binary files a/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.so and b/resources/porcupine/lib/raspberry-pi/arm11/libpv_porcupine.so differ diff --git a/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.a b/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.a index fc6e05b7b..7efa97850 100644 Binary files a/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.a and b/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.a differ diff --git a/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.so b/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.so index 242aa5c30..2774433b2 100755 Binary files a/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.so and b/resources/porcupine/lib/raspberry-pi/cortex-a53/libpv_porcupine.so differ diff --git a/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.a b/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.a index 9980a6f31..23db29afc 100644 Binary files a/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.a and b/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.a differ diff --git a/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.so b/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.so index 4c9ac428a..ad18d400f 100755 Binary files a/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.so and b/resources/porcupine/lib/raspberry-pi/cortex-a7/libpv_porcupine.so differ diff --git a/resources/porcupine/lib/windows/amd64/libpv_porcupine.dll b/resources/porcupine/lib/windows/amd64/libpv_porcupine.dll new file mode 100644 index 000000000..e9af3bd43 Binary files /dev/null and b/resources/porcupine/lib/windows/amd64/libpv_porcupine.dll differ diff --git a/resources/porcupine/resources/keyword_files/android/hey pico_android.ppn b/resources/porcupine/resources/keyword_files/android/hey pico_android.ppn new file mode 100644 index 000000000..22f2c1d36 Binary files /dev/null and b/resources/porcupine/resources/keyword_files/android/hey pico_android.ppn differ diff --git a/resources/porcupine/resources/keyword_files/android/hey_alfred_android.ppn b/resources/porcupine/resources/keyword_files/android/hey_alfred_android.ppn deleted file mode 100644 index bddfe6ece..000000000 --- a/resources/porcupine/resources/keyword_files/android/hey_alfred_android.ppn +++ /dev/null @@ -1 +0,0 @@ - Imk c*mN" * 8vT@L>2>K֙R[dTqʸkT5{TG}'wO{ j Q%f7e \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/android/hey_rachel_android.ppn b/resources/porcupine/resources/keyword_files/android/hey_rachel_android.ppn deleted file mode 100644 index 62e6f02d7..000000000 Binary files a/resources/porcupine/resources/keyword_files/android/hey_rachel_android.ppn and /dev/null differ diff --git a/resources/porcupine/resources/keyword_files/beaglebone/hey pico_beaglebone.ppn b/resources/porcupine/resources/keyword_files/beaglebone/hey pico_beaglebone.ppn new file mode 100644 index 000000000..44c2526cf --- /dev/null +++ b/resources/porcupine/resources/keyword_files/beaglebone/hey pico_beaglebone.ppn @@ -0,0 +1 @@ +RH^;30Zd"m;?<3&VI;L\ڏx/Uz ];@e/% v̄xGW?HJ \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/linux/hey pico_linux.ppn b/resources/porcupine/resources/keyword_files/linux/hey pico_linux.ppn new file mode 100644 index 000000000..8371c8db4 --- /dev/null +++ b/resources/porcupine/resources/keyword_files/linux/hey pico_linux.ppn @@ -0,0 +1,2 @@ ++lTHiK ZrHU41:h +l$E{1鯽;Xg(15l⼣0X2K!= \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn b/resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn deleted file mode 100644 index bb8e745bb..000000000 --- a/resources/porcupine/resources/keyword_files/linux/hey_alfred_linux.ppn +++ /dev/null @@ -1,2 +0,0 @@ -;dD7svkUba@RFhKZ 򜫦sz&/^,V,5C^.ak -g-u)Z'u \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/linux/hey_rachel_linux.ppn b/resources/porcupine/resources/keyword_files/linux/hey_rachel_linux.ppn deleted file mode 100644 index 1ef3d21f9..000000000 Binary files a/resources/porcupine/resources/keyword_files/linux/hey_rachel_linux.ppn and /dev/null differ diff --git a/resources/porcupine/resources/keyword_files/mac/hey pico_mac.ppn b/resources/porcupine/resources/keyword_files/mac/hey pico_mac.ppn new file mode 100644 index 000000000..2bf605979 --- /dev/null +++ b/resources/porcupine/resources/keyword_files/mac/hey pico_mac.ppn @@ -0,0 +1,3 @@ +F +6c*UCZZEi׼ `x=nm$̧|eÉ +@OC~W_ϦpVt]Ma \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/raspberrypi/hey pico_raspberrypi.ppn b/resources/porcupine/resources/keyword_files/raspberrypi/hey pico_raspberrypi.ppn new file mode 100644 index 000000000..c7af43778 --- /dev/null +++ b/resources/porcupine/resources/keyword_files/raspberrypi/hey pico_raspberrypi.ppn @@ -0,0 +1 @@ +„ߧ80i{lk6(r|Foh!=o&!-`*ZO[_R@xsfԄĕbXovV \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/raspberrypi/hey_alfred_raspberrypi.ppn b/resources/porcupine/resources/keyword_files/raspberrypi/hey_alfred_raspberrypi.ppn deleted file mode 100644 index cdaef0220..000000000 --- a/resources/porcupine/resources/keyword_files/raspberrypi/hey_alfred_raspberrypi.ppn +++ /dev/null @@ -1,3 +0,0 @@ -yNO0>RCv2~gQb7 -2tM46 -֧f@ulY%ttgOn  Pj+#t \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/raspberrypi/hey_rachel_raspberrypi.ppn b/resources/porcupine/resources/keyword_files/raspberrypi/hey_rachel_raspberrypi.ppn deleted file mode 100644 index 9b96be43f..000000000 --- a/resources/porcupine/resources/keyword_files/raspberrypi/hey_rachel_raspberrypi.ppn +++ /dev/null @@ -1 +0,0 @@ - 56}CءE{@1iHoyN^5|}&-y^^OO \ No newline at end of file diff --git a/resources/porcupine/resources/keyword_files/windows/hey pico_windows.ppn b/resources/porcupine/resources/keyword_files/windows/hey pico_windows.ppn new file mode 100644 index 000000000..645d52ae0 Binary files /dev/null and b/resources/porcupine/resources/keyword_files/windows/hey pico_windows.ppn differ