@gmessier/nitro-speech 0.4.1 → 0.4.3
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/README.md +36 -7
- package/ios/Audio/AudioLevelTracker.swift +1 -1
- package/ios/Coordinator.swift +1 -0
- package/ios/HybridRecognizer.swift +31 -3
- package/ios/Shared/AutoStopper.swift +1 -1
- package/ios/Shared/Utils.swift +2 -1
- package/lib/Recognizer/RecognizerRef.js +2 -1
- package/lib/Recognizer/SpeechRecognizer.d.ts +2 -1
- package/lib/Recognizer/SpeechRecognizer.js +2 -1
- package/lib/Recognizer/methods.d.ts +4 -3
- package/lib/Recognizer/methods.js +4 -0
- package/lib/Recognizer/types.d.ts +3 -3
- package/lib/Recognizer/useRecognizer.js +2 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/specs/Recognizer.nitro.d.ts +19 -6
- package/lib/specs/SpeechRecognitionConfig.d.ts +5 -3
- package/nitrogen/generated/android/c++/JIosPreset.hpp +3 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrospeech/IosPreset.kt +2 -1
- package/nitrogen/generated/ios/swift/IosPreset.swift +4 -0
- package/nitrogen/generated/shared/c++/IosPreset.hpp +4 -0
- package/package.json +1 -1
- package/src/Recognizer/RecognizerRef.ts +2 -0
- package/src/Recognizer/SpeechRecognizer.ts +2 -1
- package/src/Recognizer/methods.ts +11 -3
- package/src/Recognizer/types.ts +6 -1
- package/src/Recognizer/useRecognizer.ts +2 -0
- package/src/index.ts +8 -1
- package/src/specs/Recognizer.nitro.ts +19 -6
- package/src/specs/SpeechRecognitionConfig.ts +5 -3
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
- 👆 Configurable Haptic Feedback on start and finish
|
|
35
35
|
- 🎚️ Speech-quality configurations:
|
|
36
36
|
- Result is grouped by speech segments into Batches.
|
|
37
|
-
- Param `iosPreset` -
|
|
37
|
+
- Param `iosPreset` - enables best transcriber for your situation
|
|
38
38
|
- Param `disableRepeatingFilter` - filters out consecutive duplicate words.
|
|
39
39
|
- Param `androidDisableBatchHandling` - disables empty partial results
|
|
40
40
|
- Many more, see `SpeechRecognitionConfig`
|
|
@@ -138,7 +138,7 @@ Both permissions are required for speech recognition to work on iOS.
|
|
|
138
138
|
| **Language model selection** | Choose between web search vs free-form models | Auto | ✅ |
|
|
139
139
|
| **Batch handling** | Filters out empty or repeated results | Auto | ✅ |
|
|
140
140
|
| **Formatting quality** | Prefer quality vs speed in formatting | Auto | ✅ |
|
|
141
|
-
| **Transcription preset** | `iosPreset` adapts for
|
|
141
|
+
| **Transcription preset** | `iosPreset` adapts for different scenarios | ✅ | Auto |
|
|
142
142
|
| **Automatic punctuation** | Adds punctuation to transcription (iOS 16+) | ✅ | Auto |
|
|
143
143
|
| **Atypical speech hint** | Hint iOS that speech may include accent, lisp, or other confounding traits | ✅ | Auto |
|
|
144
144
|
| **getSupportedLocalesIOS** | Supported locales for iOS (No available API for Android) | ✅ | X |
|
|
@@ -155,7 +155,8 @@ Because of that, treat it as a **single session owner** setup hook: use it once
|
|
|
155
155
|
import { useRecognizer } from '@gmessier/nitro-speech';
|
|
156
156
|
|
|
157
157
|
function MyComponent() {
|
|
158
|
-
const {
|
|
158
|
+
const {
|
|
159
|
+
prewarm,
|
|
159
160
|
startListening,
|
|
160
161
|
stopListening,
|
|
161
162
|
resetAutoFinishTime,
|
|
@@ -234,7 +235,7 @@ function MyComponent() {
|
|
|
234
235
|
}
|
|
235
236
|
```
|
|
236
237
|
|
|
237
|
-
On iOS 26+, the recognizer prefers the newer `SpeechTranscriber` path for general cases. Setting `iosPreset: 'shortForm'`, `iosAddPunctuation: false`, or `iosAtypicalSpeech: true` switches priority to `DictationTranscriber` that is better suited for short utterances or non-standard speech patterns.
|
|
238
|
+
On iOS 26+, the recognizer prefers the newer `SpeechTranscriber` path for general cases. Setting `iosPreset: 'shortForm' OR 'speed'`, `iosAddPunctuation: false`, or `iosAtypicalSpeech: true` switches priority to `DictationTranscriber` that is better suited for short utterances or non-standard speech patterns.
|
|
238
239
|
|
|
239
240
|
### With React Navigation (important)
|
|
240
241
|
|
|
@@ -261,6 +262,7 @@ If you need to call recognizer methods from other components without prop drilli
|
|
|
261
262
|
```typescript
|
|
262
263
|
import { RecognizerRef } from '@gmessier/nitro-speech';
|
|
263
264
|
|
|
265
|
+
RecognizerRef.prewarm({ locale: 'en-US' });
|
|
264
266
|
RecognizerRef.startListening({ locale: 'en-US' });
|
|
265
267
|
RecognizerRef.addAutoFinishTime(5000);
|
|
266
268
|
RecognizerRef.resetAutoFinishTime();
|
|
@@ -357,12 +359,20 @@ function MyComponent() {
|
|
|
357
359
|
|
|
358
360
|
`SpeechRecognizer` is the hybrid object. It gives direct access to callbacks and control methods, but it is unsafe to orchestrate the full session directly from it.
|
|
359
361
|
|
|
362
|
+
**Warning**: Since it reflects the original hybrid object, its API may change in the future.
|
|
363
|
+
|
|
360
364
|
```typescript
|
|
361
|
-
import {
|
|
365
|
+
import {
|
|
366
|
+
SpeechRecognizer,
|
|
367
|
+
speechRecognizerVolumeChangeHandler,
|
|
368
|
+
speechRecognizerActiveStateHandler,
|
|
369
|
+
} from '@gmessier/nitro-speech';
|
|
362
370
|
|
|
363
371
|
// Set up callbacks
|
|
364
372
|
SpeechRecognizer.onReadyForSpeech = () => {
|
|
365
373
|
console.log('Listening...');
|
|
374
|
+
// Add speechRecognizerActiveStateHandler to enable useRecognizerIsActive hook manually
|
|
375
|
+
speechRecognizerActiveStateHandler(true);
|
|
366
376
|
};
|
|
367
377
|
|
|
368
378
|
SpeechRecognizer.onResult = (textBatches) => {
|
|
@@ -371,6 +381,8 @@ SpeechRecognizer.onResult = (textBatches) => {
|
|
|
371
381
|
|
|
372
382
|
SpeechRecognizer.onRecordingStopped = () => {
|
|
373
383
|
console.log('Stopped');
|
|
384
|
+
// Add speechRecognizerActiveStateHandler to enable useRecognizerIsActive hook manually
|
|
385
|
+
speechRecognizerActiveStateHandler(false);
|
|
374
386
|
};
|
|
375
387
|
|
|
376
388
|
SpeechRecognizer.onAutoFinishProgress = (timeLeftMs) => {
|
|
@@ -387,10 +399,27 @@ SpeechRecognizer.onPermissionDenied = () => {
|
|
|
387
399
|
|
|
388
400
|
SpeechRecognizer.onVolumeChange = (volume) => {
|
|
389
401
|
console.log('new volume: ', volume);
|
|
402
|
+
// Add speechRecognizerVolumeChangeHandler to enable useVoiceInputVolume hook manually
|
|
403
|
+
speechRecognizerVolumeChangeHandler(volume);
|
|
390
404
|
};
|
|
391
|
-
// OR use speechRecognizerVolumeChangeHandler to enable useVoiceInputVolume hook manually
|
|
392
|
-
SpeechRecognizer.onVolumeChange = speechRecognizerVolumeChangeHandler
|
|
393
405
|
|
|
406
|
+
// Prepare resources, download assets, confirms locale availability
|
|
407
|
+
SpeechRecognizer.prewarm({
|
|
408
|
+
locale: 'en-US',
|
|
409
|
+
// ... your config to prepare
|
|
410
|
+
});
|
|
411
|
+
// OR `await` if you want to react to the success
|
|
412
|
+
await SpeechRecognizer.prewarm({
|
|
413
|
+
locale: 'en-US',
|
|
414
|
+
// ... your config to prepare
|
|
415
|
+
});
|
|
416
|
+
// OR from worklet (only sync)
|
|
417
|
+
scheduleOnRuntime(workletRuntime, () => {
|
|
418
|
+
SpeechRecognizer.prewarm({
|
|
419
|
+
locale: 'en-US',
|
|
420
|
+
// ... your config to prepare
|
|
421
|
+
});
|
|
422
|
+
});
|
|
394
423
|
|
|
395
424
|
// Start listening
|
|
396
425
|
SpeechRecognizer.startListening({
|
package/ios/Coordinator.swift
CHANGED
|
@@ -7,10 +7,13 @@ class HybridRecognizer: HybridRecognizerSpec {
|
|
|
7
7
|
var onReadyForSpeech: (() -> Void)?
|
|
8
8
|
var onRecordingStopped: (() -> Void)?
|
|
9
9
|
var onResult: (([String]) -> Void)?
|
|
10
|
+
var onResultFallback: (([String]) -> Void)?
|
|
10
11
|
var onAutoFinishProgress: ((Double) -> Void)?
|
|
12
|
+
var onAutoFinishProgressFallback: ((Double) -> Void)?
|
|
11
13
|
var onError: ((String) -> Void)?
|
|
12
14
|
var onPermissionDenied: (() -> Void)?
|
|
13
15
|
var onVolumeChange: ((VolumeChangeEvent) -> Void)?
|
|
16
|
+
var onVolumeChangeFallback: ((VolumeChangeEvent) -> Void)?
|
|
14
17
|
|
|
15
18
|
private let coordinator = Coordinator()
|
|
16
19
|
private var paramsHash: String?
|
|
@@ -154,12 +157,29 @@ extension HybridRecognizer: RecognizerDelegate {
|
|
|
154
157
|
|
|
155
158
|
func result(batches: [String]) {
|
|
156
159
|
self.lg.log("[onResult] \(batches)")
|
|
157
|
-
|
|
160
|
+
if onResult != nil {
|
|
161
|
+
onResultFallback = onResult
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (onResultFallback == nil) {
|
|
165
|
+
self.lg.log("onResultFallback -> nil")
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
onResultFallback?(batches)
|
|
158
169
|
}
|
|
159
170
|
|
|
160
171
|
func autoFinishProgress(timeLeftMs: Double) {
|
|
161
172
|
self.lg.log("[onAutoFinishProgress] \(timeLeftMs)ms")
|
|
162
|
-
|
|
173
|
+
|
|
174
|
+
if onAutoFinishProgress != nil {
|
|
175
|
+
onAutoFinishProgressFallback = onAutoFinishProgress
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (onAutoFinishProgressFallback == nil) {
|
|
179
|
+
self.lg.log("onAutoFinishProgressFallback -> nil")
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
onAutoFinishProgressFallback?(timeLeftMs)
|
|
163
183
|
}
|
|
164
184
|
|
|
165
185
|
func error(message: String) {
|
|
@@ -174,7 +194,15 @@ extension HybridRecognizer: RecognizerDelegate {
|
|
|
174
194
|
|
|
175
195
|
func volumeChange(event: VolumeChangeEvent) {
|
|
176
196
|
// self.lg.log("[onVolumeChange] \(event.rawVolume)")
|
|
177
|
-
|
|
197
|
+
if onVolumeChange != nil {
|
|
198
|
+
onVolumeChangeFallback = onVolumeChange
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (onVolumeChangeFallback == nil) {
|
|
202
|
+
self.lg.log("onVolumeChangeFallback -> nil")
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
onVolumeChangeFallback?(event)
|
|
178
206
|
}
|
|
179
207
|
|
|
180
208
|
func reselectEngine(forPrewarm: Bool) {
|
|
@@ -5,7 +5,7 @@ final class AutoStopper {
|
|
|
5
5
|
private static let defaultProgressIntervalMs = 1000.0
|
|
6
6
|
private static let minProgressIntervalMs = 50.0
|
|
7
7
|
|
|
8
|
-
private let lg = Lg(prefix: "AutoStopper", disable:
|
|
8
|
+
private let lg = Lg(prefix: "AutoStopper", disable: true)
|
|
9
9
|
|
|
10
10
|
private let queue = DispatchQueue(label: "com.margelo.nitrospeech.autostopper")
|
|
11
11
|
|
package/ios/Shared/Utils.swift
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { recognizerAddAutoFinishTime, recognizerGetSupportedLocalesIOS, recognizerGetIsActive, recognizerResetAutoFinishTime, recognizerStartListening, recognizerStopListening, recognizerUpdateConfig, recognizerGetVoiceInputVolume, } from './methods';
|
|
1
|
+
import { recognizerAddAutoFinishTime, recognizerGetSupportedLocalesIOS, recognizerGetIsActive, recognizerResetAutoFinishTime, recognizerStartListening, recognizerStopListening, recognizerUpdateConfig, recognizerGetVoiceInputVolume, recognizerPrewarm, } from './methods';
|
|
2
2
|
/**
|
|
3
3
|
* Safe cross-component reference to the Speech Recognizer methods.
|
|
4
4
|
*
|
|
5
5
|
* All methods support worklets and UI thread calls
|
|
6
6
|
*/
|
|
7
7
|
export const RecognizerRef = {
|
|
8
|
+
prewarm: recognizerPrewarm,
|
|
8
9
|
startListening: recognizerStartListening,
|
|
9
10
|
stopListening: recognizerStopListening,
|
|
10
11
|
resetAutoFinishTime: recognizerResetAutoFinishTime,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Direct access to the all Speech Recognizer methods and callbacks.
|
|
5
5
|
*
|
|
6
|
-
* @note
|
|
6
|
+
* @note Unsafe, might lead to race conditions
|
|
7
|
+
* @warning Since it reflects the original hybrid object, its API may change in the future.
|
|
7
8
|
*/
|
|
8
9
|
export declare const SpeechRecognizer: import("./types").RecognizerSpec;
|
|
@@ -4,6 +4,7 @@ import { NitroSpeech } from '../NitroSpeech';
|
|
|
4
4
|
*
|
|
5
5
|
* Direct access to the all Speech Recognizer methods and callbacks.
|
|
6
6
|
*
|
|
7
|
-
* @note
|
|
7
|
+
* @note Unsafe, might lead to race conditions
|
|
8
|
+
* @warning Since it reflects the original hybrid object, its API may change in the future.
|
|
8
9
|
*/
|
|
9
10
|
export const SpeechRecognizer = NitroSpeech.recognizer;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { SpeechRecognitionConfig } from './types';
|
|
2
|
-
export declare const
|
|
1
|
+
import type { MutableSpeechRecognitionConfig, SpeechRecognitionConfig } from './types';
|
|
2
|
+
export declare const recognizerPrewarm: (params?: SpeechRecognitionConfig) => Promise<void>;
|
|
3
|
+
export declare const recognizerStartListening: (params?: SpeechRecognitionConfig) => void;
|
|
3
4
|
export declare const recognizerStopListening: () => void;
|
|
4
5
|
export declare const recognizerResetAutoFinishTime: () => void;
|
|
5
6
|
export declare const recognizerAddAutoFinishTime: (additionalTimeMs?: number) => void;
|
|
6
|
-
export declare const recognizerUpdateConfig: (newConfig
|
|
7
|
+
export declare const recognizerUpdateConfig: (newConfig?: MutableSpeechRecognitionConfig, resetAutoFinishTime?: boolean) => void;
|
|
7
8
|
export declare const recognizerGetIsActive: () => boolean;
|
|
8
9
|
export declare const recognizerGetVoiceInputVolume: () => import("./types").VolumeChangeEvent;
|
|
9
10
|
export declare const recognizerGetSupportedLocalesIOS: () => string[];
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { SpeechRecognizer } from './SpeechRecognizer';
|
|
2
|
+
export const recognizerPrewarm = (params) => {
|
|
3
|
+
'worklet';
|
|
4
|
+
return SpeechRecognizer.prewarm(params);
|
|
5
|
+
};
|
|
2
6
|
export const recognizerStartListening = (params) => {
|
|
3
7
|
'worklet';
|
|
4
8
|
SpeechRecognizer.startListening(params);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Recognizer as RecognizerSpec } from '../specs/Recognizer.nitro';
|
|
2
|
-
import type { SpeechRecognitionConfig } from '../specs/SpeechRecognitionConfig';
|
|
2
|
+
import type { MutableSpeechRecognitionConfig, SpeechRecognitionConfig } from '../specs/SpeechRecognitionConfig';
|
|
3
3
|
import type { VolumeChangeEvent } from '../specs/VolumeChangeEvent';
|
|
4
4
|
type RecognizerCallbacks = Pick<RecognizerSpec, 'onReadyForSpeech' | 'onRecordingStopped' | 'onResult' | 'onAutoFinishProgress' | 'onError' | 'onPermissionDenied' | 'onVolumeChange'>;
|
|
5
|
-
type RecognizerMethods = Pick<RecognizerSpec, 'startListening' | 'stopListening' | 'resetAutoFinishTime' | 'addAutoFinishTime' | 'updateConfig' | 'getIsActive' | 'getVoiceInputVolume' | 'getSupportedLocalesIOS'>;
|
|
6
|
-
export type { RecognizerSpec, SpeechRecognitionConfig, VolumeChangeEvent, RecognizerCallbacks, RecognizerMethods, };
|
|
5
|
+
type RecognizerMethods = Pick<RecognizerSpec, 'prewarm' | 'startListening' | 'stopListening' | 'resetAutoFinishTime' | 'addAutoFinishTime' | 'updateConfig' | 'getIsActive' | 'getVoiceInputVolume' | 'getSupportedLocalesIOS'>;
|
|
6
|
+
export type { RecognizerSpec, SpeechRecognitionConfig, MutableSpeechRecognitionConfig, VolumeChangeEvent, RecognizerCallbacks, RecognizerMethods, };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
import { recognizerResetAutoFinishTime, recognizerAddAutoFinishTime, recognizerUpdateConfig, recognizerGetIsActive, recognizerGetSupportedLocalesIOS, recognizerStartListening, recognizerStopListening, recognizerGetVoiceInputVolume, } from './methods';
|
|
2
|
+
import { recognizerResetAutoFinishTime, recognizerAddAutoFinishTime, recognizerUpdateConfig, recognizerGetIsActive, recognizerGetSupportedLocalesIOS, recognizerStartListening, recognizerStopListening, recognizerGetVoiceInputVolume, recognizerPrewarm, } from './methods';
|
|
3
3
|
import { SpeechRecognizer } from './SpeechRecognizer';
|
|
4
4
|
import { speechRecognizerVolumeChangeHandler } from './useVoiceInputVolume';
|
|
5
5
|
import { speechRecognizerActiveStateHandler } from './useRecognizerIsActive';
|
|
@@ -59,6 +59,7 @@ export const useRecognizer = (callbacks, destroyDeps = []) => {
|
|
|
59
59
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
60
|
}, [...destroyDeps]);
|
|
61
61
|
return {
|
|
62
|
+
prewarm: recognizerPrewarm,
|
|
62
63
|
startListening: recognizerStartListening,
|
|
63
64
|
stopListening: recognizerStopListening,
|
|
64
65
|
resetAutoFinishTime: recognizerResetAutoFinishTime,
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './Recognizer/types';
|
|
2
1
|
export { useRecognizer } from './Recognizer/useRecognizer';
|
|
3
2
|
export { useVoiceInputVolume, speechRecognizerVolumeChangeHandler, } from './Recognizer/useVoiceInputVolume';
|
|
4
3
|
export { useRecognizerIsActive, speechRecognizerActiveStateHandler, } from './Recognizer/useRecognizerIsActive';
|
|
5
4
|
export { SpeechRecognizer } from './Recognizer/SpeechRecognizer';
|
|
6
5
|
export { RecognizerRef } from './Recognizer/RecognizerRef';
|
|
7
6
|
export { NitroSpeech } from './NitroSpeech';
|
|
7
|
+
export { type RecognizerSpec, type SpeechRecognitionConfig, type MutableSpeechRecognitionConfig, type VolumeChangeEvent, type RecognizerCallbacks, type RecognizerMethods, } from './Recognizer/types';
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './Recognizer/types';
|
|
2
1
|
export { useRecognizer } from './Recognizer/useRecognizer';
|
|
3
2
|
export { useVoiceInputVolume, speechRecognizerVolumeChangeHandler, } from './Recognizer/useVoiceInputVolume';
|
|
4
3
|
export { useRecognizerIsActive, speechRecognizerActiveStateHandler, } from './Recognizer/useRecognizerIsActive';
|
|
5
4
|
export { SpeechRecognizer } from './Recognizer/SpeechRecognizer';
|
|
6
5
|
export { RecognizerRef } from './Recognizer/RecognizerRef';
|
|
7
6
|
export { NitroSpeech } from './NitroSpeech';
|
|
7
|
+
export {} from './Recognizer/types';
|
|
@@ -8,9 +8,24 @@ export interface Recognizer extends HybridObject<{
|
|
|
8
8
|
/**
|
|
9
9
|
* Prepare the speech recognition engine and the model for the given parameters.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* @notes
|
|
12
|
+
* - Not required, {@linkcode startListening} will prewarm automatically.
|
|
13
|
+
*
|
|
14
|
+
* - Omit the {@linkcode Promise} result if you want to run synchronously.
|
|
12
15
|
* {@linkcode startListening} will start and resolve it automatically.
|
|
13
|
-
*
|
|
16
|
+
*
|
|
17
|
+
* - Only `await` if run beforehand and you want to react to the success
|
|
18
|
+
*
|
|
19
|
+
* @worklet **Do not** use `await` on Worklet or UI runtimes. It will not work properly.
|
|
20
|
+
*
|
|
21
|
+
* You can run it synchronously:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* scheduleOnRuntime(workletRuntime, () => {
|
|
24
|
+
* RecognizerRef.prewarm({
|
|
25
|
+
* // your config to prepare
|
|
26
|
+
* });
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
14
29
|
*/
|
|
15
30
|
prewarm(defaultParams?: SpeechRecognitionConfig): Promise<void>;
|
|
16
31
|
/**
|
|
@@ -24,9 +39,9 @@ export interface Recognizer extends HybridObject<{
|
|
|
24
39
|
*/
|
|
25
40
|
startListening(params?: SpeechRecognitionConfig): void;
|
|
26
41
|
/**
|
|
27
|
-
* Stops the speech recognition.
|
|
42
|
+
* Stops the speech recognition. If not started, does nothing.
|
|
28
43
|
*
|
|
29
|
-
* Not a sync operation for
|
|
44
|
+
* Not a sync operation for Android, delay about 250ms to polish the result.
|
|
30
45
|
*
|
|
31
46
|
* Use {@linkcode onRecordingStopped} to handle the stop event.
|
|
32
47
|
*/
|
|
@@ -78,8 +93,6 @@ export interface Recognizer extends HybridObject<{
|
|
|
78
93
|
* Fires every {@linkcode SpeechRecognitionConfig.autoFinishProgressIntervalMs} or 1000ms
|
|
79
94
|
*
|
|
80
95
|
* Time left in milliseconds until the timer stops.
|
|
81
|
-
*
|
|
82
|
-
* @note not implemented for Android yet.
|
|
83
96
|
*/
|
|
84
97
|
onAutoFinishProgress?: (timeLeftMs: number) => void;
|
|
85
98
|
/**
|
|
@@ -22,7 +22,7 @@ interface ParamsAndroid {
|
|
|
22
22
|
*/
|
|
23
23
|
androidDisableBatchHandling?: boolean;
|
|
24
24
|
}
|
|
25
|
-
type IosPreset = 'shortform' | 'general';
|
|
25
|
+
type IosPreset = 'shortform' | 'general' | 'speed';
|
|
26
26
|
interface ParamsIOS {
|
|
27
27
|
/**
|
|
28
28
|
* Add punctuation to speech recognition results
|
|
@@ -33,9 +33,11 @@ interface ParamsIOS {
|
|
|
33
33
|
*/
|
|
34
34
|
iosAddPunctuation?: boolean;
|
|
35
35
|
/**
|
|
36
|
-
* `"shortForm"` -
|
|
36
|
+
* `"shortForm"` - For a short phrase or sentence, also disables punctuation
|
|
37
37
|
*
|
|
38
|
-
* `"
|
|
38
|
+
* `"speed"` - Gives priority to speed over accuracy
|
|
39
|
+
*
|
|
40
|
+
* `"general"` - For longer speeches, more accurate but delayed response
|
|
39
41
|
*
|
|
40
42
|
* @since iOS 26.0+
|
|
41
43
|
*
|
|
@@ -48,6 +48,9 @@ namespace margelo::nitro::nitrospeech {
|
|
|
48
48
|
case IosPreset::GENERAL:
|
|
49
49
|
static const auto fieldGENERAL = clazz->getStaticField<JIosPreset>("GENERAL");
|
|
50
50
|
return clazz->getStaticFieldValue(fieldGENERAL);
|
|
51
|
+
case IosPreset::SPEED:
|
|
52
|
+
static const auto fieldSPEED = clazz->getStaticField<JIosPreset>("SPEED");
|
|
53
|
+
return clazz->getStaticFieldValue(fieldSPEED);
|
|
51
54
|
default:
|
|
52
55
|
std::string stringValue = std::to_string(static_cast<int>(value));
|
|
53
56
|
throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
|
|
@@ -21,6 +21,8 @@ public extension IosPreset {
|
|
|
21
21
|
self = .shortform
|
|
22
22
|
case "general":
|
|
23
23
|
self = .general
|
|
24
|
+
case "speed":
|
|
25
|
+
self = .speed
|
|
24
26
|
default:
|
|
25
27
|
return nil
|
|
26
28
|
}
|
|
@@ -35,6 +37,8 @@ public extension IosPreset {
|
|
|
35
37
|
return "shortform"
|
|
36
38
|
case .general:
|
|
37
39
|
return "general"
|
|
40
|
+
case .speed:
|
|
41
|
+
return "speed"
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
}
|
|
@@ -31,6 +31,7 @@ namespace margelo::nitro::nitrospeech {
|
|
|
31
31
|
enum class IosPreset {
|
|
32
32
|
SHORTFORM SWIFT_NAME(shortform) = 0,
|
|
33
33
|
GENERAL SWIFT_NAME(general) = 1,
|
|
34
|
+
SPEED SWIFT_NAME(speed) = 2,
|
|
34
35
|
} CLOSED_ENUM;
|
|
35
36
|
|
|
36
37
|
} // namespace margelo::nitro::nitrospeech
|
|
@@ -45,6 +46,7 @@ namespace margelo::nitro {
|
|
|
45
46
|
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
46
47
|
case hashString("shortform"): return margelo::nitro::nitrospeech::IosPreset::SHORTFORM;
|
|
47
48
|
case hashString("general"): return margelo::nitro::nitrospeech::IosPreset::GENERAL;
|
|
49
|
+
case hashString("speed"): return margelo::nitro::nitrospeech::IosPreset::SPEED;
|
|
48
50
|
default: [[unlikely]]
|
|
49
51
|
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum IosPreset - invalid value!");
|
|
50
52
|
}
|
|
@@ -53,6 +55,7 @@ namespace margelo::nitro {
|
|
|
53
55
|
switch (arg) {
|
|
54
56
|
case margelo::nitro::nitrospeech::IosPreset::SHORTFORM: return JSIConverter<std::string>::toJSI(runtime, "shortform");
|
|
55
57
|
case margelo::nitro::nitrospeech::IosPreset::GENERAL: return JSIConverter<std::string>::toJSI(runtime, "general");
|
|
58
|
+
case margelo::nitro::nitrospeech::IosPreset::SPEED: return JSIConverter<std::string>::toJSI(runtime, "speed");
|
|
56
59
|
default: [[unlikely]]
|
|
57
60
|
throw std::invalid_argument("Cannot convert IosPreset to JS - invalid value: "
|
|
58
61
|
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
@@ -66,6 +69,7 @@ namespace margelo::nitro {
|
|
|
66
69
|
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
67
70
|
case hashString("shortform"):
|
|
68
71
|
case hashString("general"):
|
|
72
|
+
case hashString("speed"):
|
|
69
73
|
return true;
|
|
70
74
|
default:
|
|
71
75
|
return false;
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
recognizerStopListening,
|
|
9
9
|
recognizerUpdateConfig,
|
|
10
10
|
recognizerGetVoiceInputVolume,
|
|
11
|
+
recognizerPrewarm,
|
|
11
12
|
} from './methods'
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
* All methods support worklets and UI thread calls
|
|
17
18
|
*/
|
|
18
19
|
export const RecognizerRef: RecognizerMethods = {
|
|
20
|
+
prewarm: recognizerPrewarm,
|
|
19
21
|
startListening: recognizerStartListening,
|
|
20
22
|
stopListening: recognizerStopListening,
|
|
21
23
|
resetAutoFinishTime: recognizerResetAutoFinishTime,
|
|
@@ -5,6 +5,7 @@ import { NitroSpeech } from '../NitroSpeech'
|
|
|
5
5
|
*
|
|
6
6
|
* Direct access to the all Speech Recognizer methods and callbacks.
|
|
7
7
|
*
|
|
8
|
-
* @note
|
|
8
|
+
* @note Unsafe, might lead to race conditions
|
|
9
|
+
* @warning Since it reflects the original hybrid object, its API may change in the future.
|
|
9
10
|
*/
|
|
10
11
|
export const SpeechRecognizer = NitroSpeech.recognizer
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { SpeechRecognizer } from './SpeechRecognizer'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
MutableSpeechRecognitionConfig,
|
|
4
|
+
SpeechRecognitionConfig,
|
|
5
|
+
} from './types'
|
|
3
6
|
|
|
4
|
-
export const
|
|
7
|
+
export const recognizerPrewarm = (params?: SpeechRecognitionConfig) => {
|
|
8
|
+
'worklet'
|
|
9
|
+
return SpeechRecognizer.prewarm(params)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const recognizerStartListening = (params?: SpeechRecognitionConfig) => {
|
|
5
13
|
'worklet'
|
|
6
14
|
SpeechRecognizer.startListening(params)
|
|
7
15
|
}
|
|
@@ -22,7 +30,7 @@ export const recognizerAddAutoFinishTime = (additionalTimeMs?: number) => {
|
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
export const recognizerUpdateConfig = (
|
|
25
|
-
newConfig
|
|
33
|
+
newConfig?: MutableSpeechRecognitionConfig,
|
|
26
34
|
resetAutoFinishTime?: boolean
|
|
27
35
|
) => {
|
|
28
36
|
'worklet'
|
package/src/Recognizer/types.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Recognizer as RecognizerSpec } from '../specs/Recognizer.nitro'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
MutableSpeechRecognitionConfig,
|
|
4
|
+
SpeechRecognitionConfig,
|
|
5
|
+
} from '../specs/SpeechRecognitionConfig'
|
|
3
6
|
import type { VolumeChangeEvent } from '../specs/VolumeChangeEvent'
|
|
4
7
|
|
|
5
8
|
type RecognizerCallbacks = Pick<
|
|
@@ -15,6 +18,7 @@ type RecognizerCallbacks = Pick<
|
|
|
15
18
|
|
|
16
19
|
type RecognizerMethods = Pick<
|
|
17
20
|
RecognizerSpec,
|
|
21
|
+
| 'prewarm'
|
|
18
22
|
| 'startListening'
|
|
19
23
|
| 'stopListening'
|
|
20
24
|
| 'resetAutoFinishTime'
|
|
@@ -28,6 +32,7 @@ type RecognizerMethods = Pick<
|
|
|
28
32
|
export type {
|
|
29
33
|
RecognizerSpec,
|
|
30
34
|
SpeechRecognitionConfig,
|
|
35
|
+
MutableSpeechRecognitionConfig,
|
|
31
36
|
VolumeChangeEvent,
|
|
32
37
|
RecognizerCallbacks,
|
|
33
38
|
RecognizerMethods,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
recognizerStartListening,
|
|
9
9
|
recognizerStopListening,
|
|
10
10
|
recognizerGetVoiceInputVolume,
|
|
11
|
+
recognizerPrewarm,
|
|
11
12
|
} from './methods'
|
|
12
13
|
import type { RecognizerCallbacks, RecognizerMethods } from './types'
|
|
13
14
|
import { SpeechRecognizer } from './SpeechRecognizer'
|
|
@@ -75,6 +76,7 @@ export const useRecognizer = (
|
|
|
75
76
|
}, [...destroyDeps])
|
|
76
77
|
|
|
77
78
|
return {
|
|
79
|
+
prewarm: recognizerPrewarm,
|
|
78
80
|
startListening: recognizerStartListening,
|
|
79
81
|
stopListening: recognizerStopListening,
|
|
80
82
|
resetAutoFinishTime: recognizerResetAutoFinishTime,
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './Recognizer/types'
|
|
2
1
|
export { useRecognizer } from './Recognizer/useRecognizer'
|
|
3
2
|
export {
|
|
4
3
|
useVoiceInputVolume,
|
|
@@ -11,3 +10,11 @@ export {
|
|
|
11
10
|
export { SpeechRecognizer } from './Recognizer/SpeechRecognizer'
|
|
12
11
|
export { RecognizerRef } from './Recognizer/RecognizerRef'
|
|
13
12
|
export { NitroSpeech } from './NitroSpeech'
|
|
13
|
+
export {
|
|
14
|
+
type RecognizerSpec,
|
|
15
|
+
type SpeechRecognitionConfig,
|
|
16
|
+
type MutableSpeechRecognitionConfig,
|
|
17
|
+
type VolumeChangeEvent,
|
|
18
|
+
type RecognizerCallbacks,
|
|
19
|
+
type RecognizerMethods,
|
|
20
|
+
} from './Recognizer/types'
|
|
@@ -12,9 +12,24 @@ export interface Recognizer extends HybridObject<{
|
|
|
12
12
|
/**
|
|
13
13
|
* Prepare the speech recognition engine and the model for the given parameters.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* @notes
|
|
16
|
+
* - Not required, {@linkcode startListening} will prewarm automatically.
|
|
17
|
+
*
|
|
18
|
+
* - Omit the {@linkcode Promise} result if you want to run synchronously.
|
|
16
19
|
* {@linkcode startListening} will start and resolve it automatically.
|
|
17
|
-
*
|
|
20
|
+
*
|
|
21
|
+
* - Only `await` if run beforehand and you want to react to the success
|
|
22
|
+
*
|
|
23
|
+
* @worklet **Do not** use `await` on Worklet or UI runtimes. It will not work properly.
|
|
24
|
+
*
|
|
25
|
+
* You can run it synchronously:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* scheduleOnRuntime(workletRuntime, () => {
|
|
28
|
+
* RecognizerRef.prewarm({
|
|
29
|
+
* // your config to prepare
|
|
30
|
+
* });
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
18
33
|
*/
|
|
19
34
|
prewarm(defaultParams?: SpeechRecognitionConfig): Promise<void>
|
|
20
35
|
|
|
@@ -30,9 +45,9 @@ export interface Recognizer extends HybridObject<{
|
|
|
30
45
|
startListening(params?: SpeechRecognitionConfig): void
|
|
31
46
|
|
|
32
47
|
/**
|
|
33
|
-
* Stops the speech recognition.
|
|
48
|
+
* Stops the speech recognition. If not started, does nothing.
|
|
34
49
|
*
|
|
35
|
-
* Not a sync operation for
|
|
50
|
+
* Not a sync operation for Android, delay about 250ms to polish the result.
|
|
36
51
|
*
|
|
37
52
|
* Use {@linkcode onRecordingStopped} to handle the stop event.
|
|
38
53
|
*/
|
|
@@ -94,8 +109,6 @@ export interface Recognizer extends HybridObject<{
|
|
|
94
109
|
* Fires every {@linkcode SpeechRecognitionConfig.autoFinishProgressIntervalMs} or 1000ms
|
|
95
110
|
*
|
|
96
111
|
* Time left in milliseconds until the timer stops.
|
|
97
|
-
*
|
|
98
|
-
* @note not implemented for Android yet.
|
|
99
112
|
*/
|
|
100
113
|
onAutoFinishProgress?: (timeLeftMs: number) => void
|
|
101
114
|
/**
|
|
@@ -23,7 +23,7 @@ interface ParamsAndroid {
|
|
|
23
23
|
androidDisableBatchHandling?: boolean
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
type IosPreset = 'shortform' | 'general'
|
|
26
|
+
type IosPreset = 'shortform' | 'general' | 'speed'
|
|
27
27
|
|
|
28
28
|
interface ParamsIOS {
|
|
29
29
|
/**
|
|
@@ -35,9 +35,11 @@ interface ParamsIOS {
|
|
|
35
35
|
*/
|
|
36
36
|
iosAddPunctuation?: boolean
|
|
37
37
|
/**
|
|
38
|
-
* `"shortForm"` -
|
|
38
|
+
* `"shortForm"` - For a short phrase or sentence, also disables punctuation
|
|
39
39
|
*
|
|
40
|
-
* `"
|
|
40
|
+
* `"speed"` - Gives priority to speed over accuracy
|
|
41
|
+
*
|
|
42
|
+
* `"general"` - For longer speeches, more accurate but delayed response
|
|
41
43
|
*
|
|
42
44
|
* @since iOS 26.0+
|
|
43
45
|
*
|