@picovoice/rhino-react-native
Version:
Picovoice Rhino React Native binding
237 lines (223 loc) • 10.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.RhinoInference = void 0;
var _reactNative = require("react-native");
var RhinoErrors = _interopRequireWildcard(require("./rhino_errors"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } //
// Copyright 2020-2023 Picovoice Inc.
//
// You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE"
// file accompanying this source.
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
class RhinoInference {
constructor(isFinalized, isUnderstood, intent, slots) {
_defineProperty(this, "_isFinalized", void 0);
_defineProperty(this, "_isUnderstood", void 0);
_defineProperty(this, "_intent", void 0);
_defineProperty(this, "_slots", void 0);
this._isFinalized = isFinalized;
this._isUnderstood = isUnderstood;
this._intent = intent;
this._slots = slots;
}
/**
* Whether Rhino has made an inference
*/
get isFinalized() {
return this._isFinalized;
}
/**
* If `isFinalized`, whether Rhino understood what it heard based on the context.
*/
get isUnderstood() {
return this._isUnderstood;
}
/**
* If `isUnderstood`, name of intent that was inferred.
*/
get intent() {
return this._intent;
}
/**
* If `isUnderstood`, dictionary of slot keys and values that were inferred.
*/
get slots() {
return this._slots;
}
}
exports.RhinoInference = RhinoInference;
const RCTRhino = _reactNative.NativeModules.PvRhino;
class Rhino {
/**
* Creates an instance of the Rhino Speech-to-Intent engine.
* @param accessKey AccessKey obtained from Picovoice Console (https://console.picovoice.ai/.
* @param contextPath Absolute path to context file.
* @param modelPath Path to the file containing model parameters. If not set it will be set to the default location.
* @param sensitivity Inference sensitivity. A higher sensitivity value results in fewer misses at the cost of (potentially) increasing the erroneous inference rate.
* Sensitivity should be a floating-point number within [0, 1].
* @param endpointDurationSec Endpoint duration in seconds. An endpoint is a chunk of silence at the end of an
* utterance that marks the end of spoken command. It should be a positive number within [0.5, 5]. A lower endpoint
* duration reduces delay and improves responsiveness. A higher endpoint duration assures Rhino doesn't return inference
* preemptively in case the user pauses before finishing the request.
* @param requireEndpoint If set to `true`, Rhino requires an endpoint (a chunk of silence) after the spoken command.
* If set to `false`, Rhino tries to detect silence, but if it cannot, it still will provide inference regardless. Set
* to `false` only if operating in an environment with overlapping speech (e.g. people talking in the background).
* @returns An instance of the engine.
*/
static async create(accessKey, contextPath, modelPath) {
let sensitivity = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0.5;
let endpointDurationSec = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.0;
let requireEndpoint = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
try {
let {
handle,
frameLength,
sampleRate,
version,
contextInfo
} = await RCTRhino.create(accessKey, modelPath, contextPath, sensitivity, endpointDurationSec, requireEndpoint);
return new Rhino(handle, frameLength, sampleRate, version, contextInfo);
} catch (err) {
if (err instanceof RhinoErrors.RhinoError) {
throw err;
} else {
const nativeError = err;
throw this.codeToError(nativeError.code, nativeError.message);
}
}
}
constructor(handle, frameLength, sampleRate, version, contextInfo) {
_defineProperty(this, "_handle", void 0);
_defineProperty(this, "_frameLength", void 0);
_defineProperty(this, "_sampleRate", void 0);
_defineProperty(this, "_version", void 0);
_defineProperty(this, "_contextInfo", void 0);
this._handle = handle;
this._frameLength = frameLength;
this._sampleRate = sampleRate;
this._version = version;
this._contextInfo = contextInfo;
}
/**
* Process a frame of pcm audio with the speech-to-intent engine.
* @param frame frame 16-bit integers of 16kHz linear PCM mono audio.
* The specific array length is obtained from Rhino via the frameLength field.
* @returns {RhinoInference} inference result at time of frame being processed with fields:
* - isFinalized: whether Rhino has made an inference
* - isUnderstood: if isFinalized, whether Rhino understood what it heard based on the context
* - intent: if isUnderstood, name of intent that were inferred
* - slots: if isUnderstood, dictionary of slot keys and values that were inferred
*/
async process(frame) {
if (frame === undefined || frame === null) {
throw new RhinoErrors.RhinoInvalidArgumentError(`Frame array provided to process() is undefined or null`);
} else if (frame.length !== this._frameLength) {
throw new RhinoErrors.RhinoInvalidArgumentError(`Size of frame array provided to 'process' (${frame.length}) does not match the engine 'frameLength' (${this._frameLength})`);
}
// sample the first frame to check for non-integer values
if (!Number.isInteger(frame[0])) {
throw new RhinoErrors.RhinoInvalidArgumentError(`Non-integer frame values provided to process(): ${frame[0]}. Rhino requires 16-bit integers`);
}
try {
const {
isFinalized,
isUnderstood,
intent,
slots
} = await RCTRhino.process(this._handle, frame);
return new RhinoInference(isFinalized, isUnderstood, intent, slots);
} catch (err) {
const nativeError = err;
throw Rhino.codeToError(nativeError.code, nativeError.message);
}
}
/**
* Resets the internal state of Rhino. It should be called before the engine
* can be used to infer intent from a new stream of audio.
*/
async reset() {
return RCTRhino.reset(this._handle);
}
/**
* Frees memory that was allocated for Rhino.
*/
async delete() {
return RCTRhino.delete(this._handle);
}
/**
* Gets the source of the Rhino context in YAML format. Shows the list of intents,
* which expressions map to those intents, as well as slots and their possible values.
* @returns The context YAML
*/
get contextInfo() {
return this._contextInfo;
}
/**
* Gets the required number of audio samples per frame.
* @returns Required frame length.
*/
get frameLength() {
return this._frameLength;
}
/**
* Get the audio sample rate required by Rhino.
* @returns Required sample rate.
*/
get sampleRate() {
return this._sampleRate;
}
/**
* Gets the version number of the Rhino library.
* @returns Version of Rhino
*/
get version() {
return this._version;
}
/**
* Gets the Error type given a code.
* @param code Code name of native Error.
* @param message Detailed message of the error.
*/
static codeToError(code, message) {
switch (code) {
case 'RhinoException':
return new RhinoErrors.RhinoError(message);
case 'RhinoMemoryException':
return new RhinoErrors.RhinoMemoryError(message);
case 'RhinoIOException':
return new RhinoErrors.RhinoIOError(message);
case 'RhinoInvalidArgumentException':
return new RhinoErrors.RhinoInvalidArgumentError(message);
case 'RhinoStopIterationException':
return new RhinoErrors.RhinoStopIterationError(message);
case 'RhinoKeyException':
return new RhinoErrors.RhinoKeyError(message);
case 'RhinoInvalidStateException':
return new RhinoErrors.RhinoInvalidStateError(message);
case 'RhinoRuntimeException':
return new RhinoErrors.RhinoRuntimeError(message);
case 'RhinoActivationException':
return new RhinoErrors.RhinoActivationError(message);
case 'RhinoActivationLimitException':
return new RhinoErrors.RhinoActivationLimitError(message);
case 'RhinoActivationThrottledException':
return new RhinoErrors.RhinoActivationThrottledError(message);
case 'RhinoActivationRefusedException':
return new RhinoErrors.RhinoActivationRefusedError(message);
default:
throw new RhinoErrors.RhinoError(`unexpected code: ${code}, message: ${message}`);
}
}
}
var _default = exports.default = Rhino;
//# sourceMappingURL=rhino.js.map