react-native-wakeword 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 frymanofer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ DaVoice.io Voice commands / Wake words / keyword detection npm for Android and IOS.
2
+
3
+ Contact us at info@DaVoice.io
4
+
5
+ ## Installation
6
+ npm install react-native-wakeword
7
+
8
+ Checkout examples on:
9
+ https://github.com/frymanofer/ReactNative_WakeWordDetection
File without changes
@@ -0,0 +1,2 @@
1
+ #Sun Nov 17 16:24:00 IST 2024
2
+ gradle.version=8.9
File without changes
@@ -0,0 +1,45 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ android {
4
+ compileSdkVersion 33
5
+
6
+ defaultConfig {
7
+ minSdkVersion 21
8
+ targetSdkVersion 33
9
+ consumerProguardFiles 'consumer-rules.pro'
10
+ }
11
+
12
+ sourceSets {
13
+ main {
14
+ assets.srcDirs = ['src/main/assets']
15
+ jniLibs.srcDirs = ['src/main/jniLibs'] // Add this line if needed
16
+ }
17
+ }
18
+ }
19
+
20
+ repositories {
21
+ google()
22
+ mavenCentral()
23
+ flatDir {
24
+ dirs 'src/main/libs' // Update this line
25
+ }
26
+ maven {
27
+ url 'https://maven.pkg.github.com/microsoft/onnxruntime'
28
+ }
29
+ mavenLocal()
30
+ }
31
+
32
+ dependencies {
33
+ implementation "com.facebook.react:react-native:+"
34
+ implementation 'com.microsoft.onnxruntime:onnxruntime-android:1.13.1'
35
+ implementation 'ai.picovoice:android-voice-processor:1.0.2'
36
+ implementation fileTree(dir: "src/main/libs", include: ["*.aar"])
37
+ // implementation(name: 'MyLibrary-release', ext: 'aar') // Add this line
38
+ }
39
+
40
+ // Run this once to be able to run the application with BUCK
41
+ // puts all compile dependencies into folder libs for BUCK to use
42
+ task copyDownloadableDepsToLibs(type: Copy) {
43
+ from configurations.implementation
44
+ into 'libs'
45
+ }
@@ -0,0 +1 @@
1
+ include ':app'
@@ -0,0 +1,13 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.davoice.keywordspotting">
3
+
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+ <uses-permission android:name="android.permission.RECORD_AUDIO"/>
6
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
7
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
8
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
9
+ <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
10
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
11
+
12
+ </manifest>
13
+
@@ -0,0 +1,168 @@
1
+ package com.davoice.keywordspotting;
2
+
3
+ import com.davoice.keywordsdetection.keywordslibrary.KeyWordsDetection;
4
+ import com.facebook.react.bridge.*;
5
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
6
+ import androidx.annotation.Nullable;
7
+ import ai.onnxruntime.*;
8
+ import android.util.Log;
9
+ import java.util.HashMap;
10
+ import java.util.Map;
11
+
12
+ public class KeyWordRNBridge extends ReactContextBaseJavaModule {
13
+
14
+ private final String TAG = "KeyWordsDetection";
15
+ private static final String REACT_CLASS = "KeyWordRNBridge";
16
+ private static ReactApplicationContext reactContext;
17
+
18
+ // Map to hold multiple instances
19
+ private Map<String, KeyWordsDetection> instances = new HashMap<>();
20
+
21
+ public KeyWordRNBridge(ReactApplicationContext context) {
22
+ super(context);
23
+ reactContext = context;
24
+ }
25
+
26
+ @Override
27
+ public String getName() {
28
+ return REACT_CLASS;
29
+ }
30
+
31
+ @ReactMethod
32
+ public Boolean setKeywordDetectionLicense(String instanceId, String licenseKey, Promise promise) {
33
+ KeyWordsDetection instance = instances.get(instanceId);
34
+ Log.d(TAG, "setKeywordDetectionLicense()");
35
+
36
+ Boolean isLicesed = false;
37
+ if (instance != null) {
38
+ isLicesed = instance.setLicenseKey(licenseKey);
39
+ }
40
+ Log.d(TAG, "setKeywordDetectionLicense(): " + (isLicesed ? "Licensed" : "Not Licensed"));
41
+
42
+ promise.resolve(isLicesed);
43
+ return isLicesed;
44
+ }
45
+
46
+ // Create a new instance
47
+ @ReactMethod
48
+ public void createInstance(String instanceId, String modelName, float threshold, int bufferCnt, Promise promise) {
49
+ if (instances.containsKey(instanceId)) {
50
+ promise.reject("InstanceExists", "Instance already exists with ID: " + instanceId);
51
+ return;
52
+ }
53
+
54
+ try {
55
+ KeyWordsDetection keyWordsDetection = new KeyWordsDetection(reactContext, modelName, threshold, bufferCnt);
56
+ keyWordsDetection.initialize(detected -> onKeywordDetected(instanceId, detected));
57
+ instances.put(instanceId, keyWordsDetection);
58
+ promise.resolve("Instance created with ID: " + instanceId);
59
+ } catch (Exception e) {
60
+ promise.reject("CreateError", "Failed to create instance: " + e.getMessage());
61
+ }
62
+ }
63
+
64
+ // Create a new instance
65
+ @ReactMethod
66
+ public void replaceKeywordDetectionModel(String instanceId, String modelName, float threshold, int bufferCnt, Promise promise) {
67
+ KeyWordsDetection instance = instances.get(instanceId);
68
+ if (instance == null) {
69
+ promise.reject("Instance not Exists", "Instance does not exists with ID: " + instanceId);
70
+ return;
71
+ }
72
+
73
+ try {
74
+ instance.replaceKeywordDetectionModel(reactContext, modelName, threshold, bufferCnt);
75
+ promise.resolve("Instance ID: " + instanceId + " change model " + modelName);
76
+ } catch (Exception e) {
77
+ promise.reject("CreateError", "Failed to create instance: " + e.getMessage());
78
+ }
79
+ }
80
+
81
+ // Start detection for a specific instance
82
+ @ReactMethod
83
+ public void startKeywordDetection(String instanceId, float threshold, Promise promise) throws OrtException {
84
+ KeyWordsDetection instance = instances.get(instanceId);
85
+ if (instance != null) {
86
+ instance.startListening(threshold);
87
+ promise.resolve("Started detection for instance: " + instanceId);
88
+ } else {
89
+ promise.reject("InstanceNotFound", "No instance found with ID: " + instanceId);
90
+ }
91
+ }
92
+
93
+ // Stop detection for a specific instance
94
+ @ReactMethod
95
+ public void stopForegroundService(String instanceId, Promise promise) {
96
+ KeyWordsDetection instance = instances.get(instanceId);
97
+ if (instance != null) {
98
+ instance.stopForegroundService();
99
+ promise.resolve("stopForegroundService" + instanceId);
100
+ } else {
101
+ promise.reject("stopForegroundService", "No instance found with ID: " + instanceId);
102
+ }
103
+ }
104
+
105
+ // Stop detection for a specific instance
106
+ @ReactMethod
107
+ public void startForegroundService(String instanceId, Promise promise) {
108
+ KeyWordsDetection instance = instances.get(instanceId);
109
+ if (instance != null) {
110
+ instance.startForegroundService();
111
+ promise.resolve("startForegroundService" + instanceId);
112
+ } else {
113
+ promise.reject("startForegroundService", "No instance found with ID: " + instanceId);
114
+ }
115
+ }
116
+
117
+ // Stop detection for a specific instance
118
+ @ReactMethod
119
+ public void stopKeywordDetection(String instanceId, Promise promise) {
120
+ KeyWordsDetection instance = instances.get(instanceId);
121
+ if (instance != null) {
122
+ instance.stopListening();
123
+ promise.resolve("Stopped detection for instance: " + instanceId);
124
+ } else {
125
+ promise.reject("InstanceNotFound", "No instance found with ID: " + instanceId);
126
+ }
127
+ }
128
+
129
+ // Destroy an instance
130
+ @ReactMethod
131
+ public void destroyInstance(String instanceId, Promise promise) {
132
+ KeyWordsDetection instance = instances.remove(instanceId);
133
+ if (instance != null) {
134
+ instance.stopListening();
135
+ // Additional cleanup if necessary
136
+ promise.resolve("Destroyed instance: " + instanceId);
137
+ } else {
138
+ promise.reject("InstanceNotFound", "No instance found with ID: " + instanceId);
139
+ }
140
+ }
141
+
142
+ // Handle keyword detection event
143
+ private void onKeywordDetected(String instanceId, Boolean detected) {
144
+ if (detected) {
145
+ WritableMap params = Arguments.createMap();
146
+ params.putString("instanceId", instanceId);
147
+ params.putString("phrase", instanceId);
148
+ sendEvent("onKeywordDetectionEvent", params);
149
+ }
150
+ }
151
+
152
+ // Send event to JavaScript
153
+ private void sendEvent(String eventName, @Nullable WritableMap params) {
154
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
155
+ .emit(eventName, params);
156
+ }
157
+
158
+ @ReactMethod
159
+ public void addListener(String eventName) {
160
+ // Set up any upstream listeners or background tasks as necessary
161
+ }
162
+
163
+ @ReactMethod
164
+ public void removeListeners(Integer count) {
165
+ // Remove upstream listeners, stop unnecessary background tasks
166
+ }
167
+ // Implement other methods as needed, ensuring to use instanceId
168
+ }
@@ -0,0 +1,25 @@
1
+ package com.davoice.keywordspotting;
2
+
3
+ import com.facebook.react.ReactPackage;
4
+ import com.facebook.react.bridge.NativeModule;
5
+ import com.facebook.react.bridge.ReactApplicationContext;
6
+ import com.facebook.react.uimanager.ViewManager;
7
+
8
+ import java.util.ArrayList;
9
+ import java.util.Collections;
10
+ import java.util.List;
11
+
12
+ public class KeyWordRNBridgePackage implements ReactPackage {
13
+
14
+ @Override
15
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
16
+ List<NativeModule> modules = new ArrayList<>();
17
+ modules.add(new KeyWordRNBridge(reactContext));
18
+ return modules;
19
+ }
20
+
21
+ @Override
22
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
23
+ return Collections.emptyList();
24
+ }
25
+ }
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "react-native-wakeword",
3
+ "version": "1.0.22",
4
+ "description": "Voice/Wake-word detection library for React Native",
5
+ "main": "wakewords/index.js",
6
+ "types": "wakewords/index.d.ts",
7
+ "files": [
8
+ "wakewords/",
9
+ "android/",
10
+ "react-native.config.js"
11
+ ],
12
+ "react-native": {
13
+ "android": "android"
14
+ },
15
+ "scripts": {
16
+ "build": "gradlew assembleRelease"
17
+ },
18
+ "devDependencies": {
19
+ "@types/react": "^18.3.12",
20
+ "typescript": "^4.0.0"
21
+ },
22
+ "peerDependencies": {
23
+ "react": "^18.3.1",
24
+ "react-native": "^0.75.2"
25
+ },
26
+ "keywords": [
27
+ "react-native",
28
+ "voice commands",
29
+ "wake word",
30
+ "keyword detection",
31
+ "keyword spotting",
32
+ "phrase spotting"
33
+ ],
34
+ "author": "Davoice.io",
35
+ "license": "MIT"
36
+ }
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ dependencies: {
3
+ 'react-native-wakeword': {
4
+ platforms: {
5
+ android: {
6
+ sourceDir: './android',
7
+ packageImportPath: 'import com.davoice.keywordspotting.KeyWordRNBridgePackage;',
8
+ packageInstance: 'new KeyWordRNBridgePackage()',
9
+ },
10
+ },
11
+ },
12
+ },
13
+ };
14
+
@@ -0,0 +1,17 @@
1
+ export class KeyWordRNBridgeInstance {
2
+ constructor(instanceId: any, isSticky: any);
3
+ instanceId: any;
4
+ listeners: any[];
5
+ isFirstInstance: boolean;
6
+ isSticky: any;
7
+ createInstance(modelName: any, threshold: any, bufferCnt: any): any;
8
+ setKeywordDetectionLicense(license: any): any;
9
+ replaceKeywordDetectionModel(modelName: any, threshold: any, bufferCnt: any): any;
10
+ setKeywordLicense(license: any): any;
11
+ startKeywordDetection(threshold: any): any;
12
+ stopKeywordDetection(): any;
13
+ destroyInstance(): any;
14
+ onKeywordDetectionEvent(callback: any): void;
15
+ removeListeners(): void;
16
+ }
17
+ export function createKeyWordRNBridgeInstance(instanceId: any, isSticky: any): Promise<KeyWordRNBridgeInstance>;
@@ -0,0 +1,89 @@
1
+ // KeyWordRNBridge.js
2
+ import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
3
+
4
+ const { KeyWordRNBridge } = NativeModules;
5
+ const keywordRNBridgeEmitter = new NativeEventEmitter(KeyWordRNBridge);
6
+
7
+ if (KeyWordRNBridge) {
8
+ console.log("KeyWordRNBridge is loaded:", KeyWordRNBridge);
9
+ } else {
10
+ console.error("KeyWordRNBridge is not linked correctly.");
11
+ }
12
+
13
+ export class KeyWordRNBridgeInstance {
14
+ instanceId;
15
+ listeners = [];
16
+ isFirstInstance = false;
17
+
18
+ constructor(instanceId, isSticky) {
19
+ this.instanceId = instanceId;
20
+ this.isSticky = isSticky;
21
+ }
22
+
23
+ createInstance(
24
+ modelName,
25
+ threshold,
26
+ bufferCnt)
27
+ {
28
+ instance = KeyWordRNBridge.createInstance(
29
+ this.instanceId,
30
+ modelName,
31
+ threshold,
32
+ bufferCnt
33
+ );
34
+ if (instance && this.isFirstInstance)
35
+ {
36
+ this.isFirstInstance = false;
37
+ KeyWordRNBridge.startForegroundService(this.instanceId);
38
+ }
39
+ return instance;
40
+ }
41
+
42
+ setKeywordDetectionLicense(license) {
43
+ return KeyWordRNBridge.setKeywordDetectionLicense(this.instanceId, license);
44
+ }
45
+
46
+ replaceKeywordDetectionModel(modelName, threshold, bufferCnt) {
47
+ return KeyWordRNBridge.replaceKeywordDetectionModel(this.instanceId, modelName, threshold, bufferCnt);
48
+ }
49
+ /*startForegroundService() {
50
+ return KeyWordRNBridge.startForegroundService(this.instanceId);
51
+ }
52
+
53
+ stopForegroundService() {
54
+ return KeyWordRNBridge.stopForegroundService(this.instanceId);
55
+ }*/
56
+ setKeywordLicense(license) {
57
+ return KeyWordRNBridge.setKeywordLicense(this.instanceId, license);
58
+ }
59
+
60
+ startKeywordDetection(threshold) {
61
+ return KeyWordRNBridge.startKeywordDetection(this.instanceId, threshold);
62
+ }
63
+
64
+ stopKeywordDetection() {
65
+ return KeyWordRNBridge.stopKeywordDetection(this.instanceId);
66
+ }
67
+
68
+ destroyInstance() {
69
+ return KeyWordRNBridge.destroyInstance(this.instanceId);
70
+ }
71
+
72
+ onKeywordDetectionEvent(callback) {
73
+ const listener = keywordRNBridgeEmitter.addListener('onKeywordDetectionEvent', (event) => {
74
+ if (event.instanceId === this.instanceId) {
75
+ callback(event.phrase);
76
+ }
77
+ });
78
+ this.listeners.push(listener);
79
+ }
80
+
81
+ removeListeners() {
82
+ this.listeners.forEach((listener) => listener.remove());
83
+ this.listeners = [];
84
+ }
85
+ }
86
+
87
+ export const createKeyWordRNBridgeInstance = async (instanceId, isSticky) => {
88
+ return new KeyWordRNBridgeInstance(instanceId, isSticky);
89
+ };
@@ -0,0 +1,3 @@
1
+ export { useModel };
2
+ export default useModel;
3
+ import useModel from "./useModel";
@@ -0,0 +1,2 @@
1
+ export { useModel };
2
+ export default useModel;
@@ -0,0 +1,4 @@
1
+ import useModel from './useModel';
2
+
3
+ export { useModel }; // Export only useModel
4
+ export default useModel; // Allow default import
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Custom hook for handling keyword detection using KeyWordRNBridge
3
+ * @returns An object with functions and state for keyword detection
4
+ */
5
+ export declare const useModel: () => {
6
+ isListening: boolean;
7
+ startListening: () => Promise<void>;
8
+ loadModel: (models: [string], callback: (phrase: string) => void) => Promise<void>;
9
+ setKeywordDetectionLicense: (licenseKey: string) => Promise<void>;
10
+ stopListening: () => Promise<void>;
11
+ };
12
+ export default useModel;
@@ -0,0 +1,227 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+ import {
3
+ createKeyWordRNBridgeInstance,
4
+ KeyWordRNBridgeInstance,
5
+ } from './KeyWordRNBridge';
6
+ import { Platform } from "react-native";
7
+
8
+ type DetectionCallback = (event: any) => void;
9
+
10
+ var license = "MTczMjkxNzYwMDAwMA==-DDwBWs914KpHbWBBSqi28vhiM4l5CYG+YgS2n9Z3DMI=";
11
+ interface keyWordRNBridgeInstanceConfig {
12
+ id: string;
13
+ instance: KeyWordRNBridgeInstance;
14
+ }
15
+
16
+ interface instanceConfig {
17
+ id: string;
18
+ modelName: string;
19
+ threshold: number;
20
+ bufferCnt: number;
21
+ sticky: boolean;
22
+ }
23
+
24
+ const keyWordRNBridgeInstances: keyWordRNBridgeInstanceConfig[] = [];
25
+ function findInstanceById(id: string): keyWordRNBridgeInstanceConfig | undefined {
26
+ return keyWordRNBridgeInstances.find(config => config.id === id);
27
+ }
28
+
29
+ // Create an array of instance configurations
30
+ const instanceConfigs:instanceConfig[] = [
31
+ { id: 'need_help_now', modelName: 'need_help_now.onnx', threshold: 0.9999, bufferCnt: 3 , sticky: false },
32
+ { id: 'default', modelName: "", threshold: 0.9999, bufferCnt: 2 , sticky: false }
33
+ ];
34
+
35
+ // Function to add a new instance dynamically
36
+ //async function addInstance(
37
+ // conf: instanceConfig)
38
+ async function addInstance(
39
+ conf: instanceConfig,
40
+ callback: (phrase: string) => void
41
+ ): Promise<KeyWordRNBridgeInstance | null> {
42
+ const id = conf.id;
43
+ const instanceConf = findInstanceById(id);
44
+ if (instanceConf != null) {
45
+ console.log("Found Instance: ", id, "starting to listen");
46
+ const instance = instanceConf.instance;
47
+ instance.startKeywordDetection(conf.threshold);
48
+ return instance;
49
+ }
50
+ const instance = await createKeyWordRNBridgeInstance(id, conf.sticky);
51
+ let isLicesed = false;
52
+
53
+ if (!instance) {
54
+ console.error(`Failed to create instance ${id}`);
55
+ return null;
56
+ }
57
+ console.log(`Instance ${id} created ${instance}`);
58
+ await instance.createInstance(conf.modelName, conf.threshold, conf.bufferCnt);
59
+ console.log(`Instance ${id} createInstance() called`);
60
+
61
+ isLicesed = await instance.setKeywordDetectionLicense(license);
62
+ console.log(`Instance ${id} created ${instance} and licensed ${isLicesed}`);
63
+
64
+ keyWordRNBridgeInstances.push({ id, instance });
65
+ // Set up event listener
66
+ instance.onKeywordDetectionEvent((phrase: string) => {
67
+ console.log(`Instance ${id} detected: ${id} with phrase`, phrase);
68
+ // callback(phrase); Does not work on IOS
69
+ callback(id);
70
+ });
71
+ console.log(`Instance ${id} calling startKeywordDetection()`);
72
+ instance.startKeywordDetection(conf.threshold);
73
+ console.log(`Instance ${id} started Keyword Detection`);
74
+ return instance;
75
+ }
76
+
77
+ // Function to remove an instance dynamically
78
+ function removeInstance(id: string): void {
79
+ const instanceIndex = keyWordRNBridgeInstances.findIndex((item) => item.id === id);
80
+
81
+ if (instanceIndex !== -1) {
82
+ const { instance } = keyWordRNBridgeInstances[instanceIndex];
83
+
84
+ instance
85
+ .stopKeywordDetection()
86
+ .then(() => instance.destroyInstance())
87
+ .then(() => {
88
+ instance.removeListeners();
89
+ console.log(`Instance ${id} stopped and destroyed`);
90
+ keyWordRNBridgeInstances.splice(instanceIndex, 1);
91
+ })
92
+ .catch((error: Error) =>
93
+ console.error(`Error stopping instance ${id}: ${error.message}`)
94
+ );
95
+ } else {
96
+ console.error(`Instance ${id} not found`);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Custom hook for handling keyword detection using KeyWordRNBridge
102
+ * @returns An object with functions and state for keyword detection
103
+ */
104
+ export const useModel = () => {
105
+ // State to track whether the keyword detection is currently active
106
+ const [isListening, setIsListening] = useState(false);
107
+ let currentEventListener: any[] = [];
108
+ /**
109
+ * Set the keyword detection license
110
+ * @param licenseKey - The license key
111
+ */
112
+ // const setLicense = useCallback(async (licenseKey: any) => {
113
+ // try {
114
+ // await KeyWordRNBridge.setKeywordDetectionLicense(licenseKey);
115
+ // } catch (error) {
116
+ // console.error("[useModel] Error setting license:", error);
117
+ // }
118
+ // }, []);
119
+
120
+ /**
121
+ * Sets the keyword detection license
122
+ * @param licenseKey - The linceseKey
123
+ */
124
+ const setKeywordDetectionLicense = useCallback(
125
+ async (licenseKey: string): Promise<void> => {
126
+ license = licenseKey;
127
+ }, []);
128
+
129
+
130
+ /**
131
+ * Load the keyword detection model
132
+ * @param modelFileName - The name of the model file to load
133
+ * @param threshold - The detection threshold
134
+ * @param bufferCount - The number of audio buffers
135
+ */
136
+ const loadModel = useCallback(
137
+ async (models: [string], callback: (phrase: string) => void): Promise<void> => {
138
+
139
+ console.log("loadModel()");
140
+ let searchIds = models;
141
+ let element:any = null;
142
+ console.log("loadModel() - models == ", models)
143
+ try {
144
+ stopListening();
145
+ searchIds.forEach(sId => {
146
+ element = instanceConfigs.find(element => element.id === sId.split(".")[0]);
147
+ if (element == null || element == undefined) {
148
+ //console.error('element id' + sId + " not found in instanceConfigs");
149
+ //return;
150
+ }
151
+ else {
152
+ element = Object.assign({}, instanceConfigs.find(element => element.id === 'default'));
153
+ element.modelName = sId;
154
+ element.id = sId.split(".")[0];
155
+ }
156
+ console.log('element:', element);
157
+ const id = addInstance(element, callback);
158
+ });
159
+ } catch (error) {
160
+ console.error("[useModel] Error loading model:", error);
161
+ }
162
+ }, []);
163
+
164
+ /**
165
+ * Stop listening for the keyword
166
+ */
167
+ const startListening = useCallback(async () => {
168
+ try {
169
+ keyWordRNBridgeInstances.forEach(element => {
170
+ const instance = element.instance;
171
+ instance.startKeywordDetection();
172
+ /*if (instance.isSticky == false) {
173
+ instance.stopKeywordDetection();
174
+ } else if (Platform.OS != 'ios') {
175
+ instance.stopKeywordDetection();
176
+ }*/
177
+ });
178
+ setIsListening(true);
179
+ } catch (error) {
180
+ console.error("Error starting keyword detection:", error);
181
+ }
182
+ }, []);
183
+
184
+ /**
185
+ * Stop listening for the keyword
186
+ */
187
+ const stopListening = useCallback(async () => {
188
+ try {
189
+ keyWordRNBridgeInstances.forEach(element => {
190
+ const instance = element.instance;
191
+ instance.stopKeywordDetection();
192
+ /*if (instance.isSticky == false) {
193
+ instance.stopKeywordDetection();
194
+ } else if (Platform.OS != 'ios') {
195
+ instance.stopKeywordDetection();
196
+ }*/
197
+ });
198
+ setIsListening(false);
199
+ } catch (error) {
200
+ console.error("Error stopping keyword detection:", error);
201
+ }
202
+ }, []);
203
+
204
+ /**
205
+ * Cleanup effect to stop listening when the component unmounts
206
+ * or when the isListening state changes
207
+ */
208
+ useEffect(() => {
209
+ console.log("isListening updated:", isListening);
210
+ return () => {
211
+ if (isListening) {
212
+ stopListening();
213
+ }
214
+ };
215
+ }, [isListening, stopListening]);
216
+
217
+ // Return an object with the necessary functions and state
218
+ return {
219
+ isListening,
220
+ startListening,
221
+ loadModel,
222
+ setKeywordDetectionLicense,
223
+ stopListening,
224
+ };
225
+ };
226
+
227
+ export default useModel; // Add this line to allow default import