react-native-davoice-tts 1.0.405 → 1.0.407

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.
Files changed (43) hide show
  1. package/README.md +11 -0
  2. package/TTSRNBridge.podspec +1 -1
  3. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  4. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  5. package/android/.gradle/9.7.1/checksums/checksums.lock +0 -0
  6. package/android/.gradle/9.7.1/fileHashes/fileHashes.lock +0 -0
  7. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  8. package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
  9. package/android/build/reports/problems/problems-report.html +9 -2
  10. package/android/libs/com/davoice/tts/1.0.0/tts-1.0.0.aar +0 -0
  11. package/android/libs/com/davoice/tts/1.0.0/tts-1.0.0.aar.md5 +1 -1
  12. package/android/libs/com/davoice/tts/1.0.0/tts-1.0.0.aar.sha1 +1 -1
  13. package/android/src/main/java/com/davoice/stt/rn/STTModule.kt +90 -22
  14. package/android/src/main/java/com/davoice/tts/rn/DaVoiceTTSBridge.java +16 -0
  15. package/ios/SpeechBridge/SpeechBridge.m +108 -12
  16. package/ios/TTSRNBridge/DaVoiceTTSBridge.m +6 -0
  17. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/DavoiceTTS +0 -0
  18. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Headers/DavoiceTTS-Swift.h +24 -0
  19. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.abi.json +1708 -360
  20. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.private.swiftinterface +35 -0
  21. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  22. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios.swiftinterface +35 -0
  23. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/DavoiceTTS +0 -0
  24. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Headers/DavoiceTTS-Swift.h +48 -0
  25. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.abi.json +1708 -360
  26. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +35 -0
  27. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  28. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/arm64-apple-ios-simulator.swiftinterface +35 -0
  29. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.abi.json +1708 -360
  30. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +35 -0
  31. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  32. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/Modules/DavoiceTTS.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +35 -0
  33. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/_CodeSignature/CodeDirectory +0 -0
  34. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/_CodeSignature/CodeRequirements-1 +0 -0
  35. package/ios/TTSRNBridge/DavoiceTTS.xcframework/ios-arm64_x86_64-simulator/DavoiceTTS.framework/_CodeSignature/CodeResources +33 -33
  36. package/package.json +1 -1
  37. package/speech/index.d.ts +42 -1
  38. package/speech/index.ts +115 -4
  39. package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
  40. package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
  41. package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
  42. /package/android/.gradle/{9.2.0 → 9.7.1}/fileChanges/last-build.bin +0 -0
  43. /package/android/.gradle/{9.2.0 → 9.7.1}/gc.properties +0 -0
@@ -1 +1 @@
1
- c3a053f30eb1b1dcf7851eed512231af tts-1.0.0.aar
1
+ 8f7632a348c787a68e9282f3ce8e48dc tts-1.0.0.aar
@@ -1 +1 @@
1
- 373f63810dedf05e94f081b7f8550fd4661a7158 tts-1.0.0.aar
1
+ 86d0f842139d70bec863c85b3d86f56d0279124d tts-1.0.0.aar
@@ -35,19 +35,81 @@ class STTModule(private val rc: ReactApplicationContext)
35
35
  return stt!!
36
36
  }
37
37
 
38
+ // The native side accepts the JSON itself or a path to it.
38
39
  private fun readOnboardingJson(options: ReadableMap?): String? {
39
- var onboardingJson: String? = null
40
- try {
41
- if (options != null && options.hasKey("onboardingJsonPath") && !options.isNull("onboardingJsonPath")) {
42
- val p = options.getString("onboardingJsonPath")
43
- if (!p.isNullOrBlank()) {
44
- onboardingJson = java.io.File(p).readText(Charsets.UTF_8)
45
- }
40
+ if (options == null || !options.hasKey("onboardingJsonPath") || options.isNull("onboardingJsonPath")) return null
41
+ return options.getString("onboardingJsonPath")?.takeIf { it.isNotBlank() }
42
+ }
43
+
44
+ private fun readSpeakerId(options: ReadableMap?): String =
45
+ options?.takeIf { it.hasKey("speakerId") && !it.isNull("speakerId") }?.getString("speakerId")
46
+ ?.takeIf { it.isNotBlank() } ?: "default"
47
+
48
+ // JS [{id, json}] -> List<Map<String, String?>> (json = JSON string or path).
49
+ private fun toSpeakerItems(arr: ReadableArray?): List<Map<String, String?>> {
50
+ if (arr == null) return emptyList()
51
+ val out = ArrayList<Map<String, String?>>()
52
+ for (i in 0 until arr.size()) {
53
+ val m = arr.getMap(i) ?: continue
54
+ val item = HashMap<String, String?>()
55
+ val it = m.keySetIterator()
56
+ while (it.hasNextKey()) {
57
+ val k = it.nextKey()
58
+ if (m.getType(k) == ReadableType.String) item[k] = m.getString(k)
46
59
  }
47
- } catch (_: Throwable) {
48
- onboardingJson = null
60
+ out.add(item)
49
61
  }
50
- return onboardingJson
62
+ return out
63
+ }
64
+
65
+ // `speakers` replaces the set; else `onboardingJsonPath` (+ `speakerId`) adds one
66
+ // speaker; else the current set (if any) is kept.
67
+ private fun startWithOptions(locale: String?, options: ReadableMap?) {
68
+ val speakers = options?.takeIf { it.hasKey("speakers") && !it.isNull("speakers") }?.getArray("speakers")
69
+ if (speakers != null && speakers.size() > 0) {
70
+ ensure().startSpeech(locale, toSpeakerItems(speakers))
71
+ } else {
72
+ ensure().startSpeech(locale, readOnboardingJson(options), null, readSpeakerId(options))
73
+ }
74
+ }
75
+
76
+ private fun speakerIdsArray(): WritableArray =
77
+ Arguments.createArray().apply { (stt?.getSpeakerIds() ?: emptyList()).forEach { pushString(it) } }
78
+
79
+ @ReactMethod
80
+ fun addSpeaker(speakerId: String?, jsonOrPath: String?, promise: Promise) {
81
+ try {
82
+ ensure().addSpeaker(speakerId ?: "default", jsonOrPath ?: "")
83
+ promise.resolve(speakerIdsArray())
84
+ } catch (t: Throwable) {
85
+ promise.reject("sv_add_failed", t.message, t)
86
+ }
87
+ }
88
+
89
+ @ReactMethod
90
+ fun setSpeakers(speakers: ReadableArray?, promise: Promise) {
91
+ try {
92
+ ensure().setSpeakers(toSpeakerItems(speakers))
93
+ promise.resolve(speakerIdsArray())
94
+ } catch (t: Throwable) {
95
+ promise.reject("sv_set_failed", t.message, t)
96
+ }
97
+ }
98
+
99
+ @ReactMethod
100
+ fun removeSpeaker(speakerId: String?, promise: Promise) {
101
+ promise.resolve(stt?.removeSpeaker(speakerId ?: "") ?: false)
102
+ }
103
+
104
+ @ReactMethod
105
+ fun getSpeakerIds(promise: Promise) {
106
+ promise.resolve(speakerIdsArray())
107
+ }
108
+
109
+ @ReactMethod
110
+ fun startSpeechWithSVSpeakers(locale: String?, speakers: ReadableArray?, cb: Callback) {
111
+ ensure().startSpeech(locale, toSpeakerItems(speakers))
112
+ cb.invoke(false)
51
113
  }
52
114
 
53
115
  // ===== JS API =====
@@ -83,15 +145,13 @@ class STTModule(private val rc: ReactApplicationContext)
83
145
  // ANDROID expects (locale, options, callback) like @react-native-voice
84
146
  @ReactMethod
85
147
  fun startSpeech(locale: String?, options: ReadableMap, cb: Callback) {
86
- val onboardingJson = readOnboardingJson(options)
87
- ensure().startSpeech(locale, onboardingJson, null)
148
+ startWithOptions(locale, options)
88
149
  cb.invoke(false) // parity with voice: callback(false) on success
89
150
  }
90
151
 
91
152
  @ReactMethod
92
153
  fun initWithoutModel(locale: String?, options: ReadableMap?, cb: Callback) {
93
- val onboardingJson = readOnboardingJson(options)
94
- ensure().startSpeech(locale, onboardingJson, null)
154
+ startWithOptions(locale, options)
95
155
  cb.invoke(false)
96
156
  }
97
157
 
@@ -222,16 +282,24 @@ class STTModule(private val rc: ReactApplicationContext)
222
282
  send("onSpeechError", m)
223
283
  }
224
284
 
225
- override fun onSpeechResults(best: String, all: List<String>) {
226
- val arr = Arguments.createArray().apply { all.forEach { pushString(it) } }
227
- val m = Arguments.createMap().apply { putArray("value", arr) }
228
- send("onSpeechResults", m)
285
+ // speakerIds/speakerId are added only when speaker verification is on.
286
+ private fun resultMap(values: List<String>, speakerIds: List<String>, speakerId: String?): WritableMap {
287
+ val arr = Arguments.createArray().apply { values.forEach { pushString(it) } }
288
+ return Arguments.createMap().apply {
289
+ putArray("value", arr)
290
+ if (speakerIds.isNotEmpty()) {
291
+ putArray("speakerIds", Arguments.createArray().apply { speakerIds.forEach { pushString(it) } })
292
+ if (speakerId != null) putString("speakerId", speakerId)
293
+ }
294
+ }
295
+ }
296
+
297
+ override fun onSpeechResults(best: String, all: List<String>, speakerIds: List<String>, speakerId: String?) {
298
+ send("onSpeechResults", resultMap(all, speakerIds, speakerId))
229
299
  }
230
300
 
231
- override fun onSpeechPartialResults(list: List<String>) {
232
- val arr = Arguments.createArray().apply { list.forEach { pushString(it) } }
233
- val m = Arguments.createMap().apply { putArray("value", arr) }
234
- send("onSpeechPartialResults", m)
301
+ override fun onSpeechPartialResults(list: List<String>, speakerIds: List<String>, speakerId: String?) {
302
+ send("onSpeechPartialResults", resultMap(list, speakerIds, speakerId))
235
303
  }
236
304
 
237
305
  override fun onSpeechVolumeChanged(value: Float) {
@@ -2,11 +2,13 @@
2
2
  package com.davoice.tts.rn;
3
3
 
4
4
  import androidx.annotation.Nullable;
5
+ import com.facebook.react.bridge.Arguments;
5
6
  import com.facebook.react.bridge.Promise;
6
7
  import com.facebook.react.bridge.ReactApplicationContext;
7
8
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
8
9
  import com.facebook.react.bridge.ReactMethod;
9
10
  import com.facebook.react.bridge.ReadableMap;
11
+ import com.facebook.react.bridge.WritableArray;
10
12
  import com.facebook.react.bridge.WritableMap;
11
13
  import com.facebook.react.modules.core.DeviceEventManagerModule;
12
14
  // ADD
@@ -357,6 +359,20 @@ public class DaVoiceTTSBridge extends ReactContextBaseJavaModule {
357
359
  return null;
358
360
  }
359
361
 
362
+ // Voices available in the loaded .dm; [] when none (or no ttsv2 .dm).
363
+ @ReactMethod
364
+ public void getAllVoices(Promise promise) {
365
+ WritableArray voices = Arguments.createArray();
366
+ try {
367
+ if (tts != null) {
368
+ for (String name : tts.getAllVoices()) voices.pushString(name);
369
+ }
370
+ } catch (Exception ignored) {
371
+ voices = Arguments.createArray();
372
+ }
373
+ promise.resolve(voices);
374
+ }
375
+
360
376
  @ReactMethod
361
377
  public void changeVoice(String name, Promise promise) {
362
378
  try {
@@ -603,6 +603,106 @@ RCT_EXPORT_METHOD(clearAudioRoutingConfig:(RCTPromiseResolveBlock)resolve
603
603
  }
604
604
 
605
605
  /// initAll({ locale: "en-US", model: "/path/model.onnx", timeoutMs?: 8000 })
606
+ #pragma mark - Speaker verification (live multi-speaker)
607
+
608
+ // JS arrays of {id, json} -> NSArray<NSDictionary<NSString*,NSString*>*> with
609
+ // string values only (json may be the JSON itself or a path to it).
610
+ static NSArray<NSDictionary<NSString *, NSString *> *> *SBSpeakerItems(id raw) {
611
+ NSMutableArray<NSDictionary<NSString *, NSString *> *> *out = [NSMutableArray array];
612
+ if (![raw isKindOfClass:[NSArray class]]) return out;
613
+ for (id item in (NSArray *)raw) {
614
+ if (![item isKindOfClass:[NSDictionary class]]) continue;
615
+ NSMutableDictionary<NSString *, NSString *> *d = [NSMutableDictionary dictionary];
616
+ [(NSDictionary *)item enumerateKeysAndObjectsUsingBlock:^(id k, id v, BOOL *stop) {
617
+ if ([k isKindOfClass:[NSString class]] && [v isKindOfClass:[NSString class]]) d[k] = v;
618
+ }];
619
+ [out addObject:d];
620
+ }
621
+ return out;
622
+ }
623
+
624
+ static BOOL SBNonEmptyString(id v) {
625
+ return [v isKindOfClass:[NSString class]] && [(NSString *)v length] > 0;
626
+ }
627
+
628
+ // Starts STT from initAll-style options: `speakers` (array) replaces the set;
629
+ // otherwise `onboardingJsonPath` (+ optional `speakerId`, default "default") adds
630
+ // one speaker; otherwise the current set (if any) is kept.
631
+ - (void)startSTTWithLocale:(NSString *)locale opts:(NSDictionary *)opts
632
+ {
633
+ NSArray *speakers = SBSpeakerItems(opts[@"speakers"]);
634
+ id onboardingJsonPath = opts[@"onboardingJsonPath"];
635
+ id speakerId = opts[@"speakerId"];
636
+ if (speakers.count > 0) {
637
+ [self.stt startSpeechWithLocaleStr:locale speakers:speakers];
638
+ } else if (SBNonEmptyString(onboardingJsonPath)) {
639
+ [self.stt startSpeechWithLocaleStr:locale
640
+ onboardingJsonPath:onboardingJsonPath
641
+ speakerId:(SBNonEmptyString(speakerId) ? speakerId : @"default")];
642
+ } else {
643
+ [self.stt startSpeechWithLocaleStr:locale];
644
+ }
645
+ }
646
+
647
+ RCT_EXPORT_METHOD(addSpeaker:(NSString *)speakerId
648
+ jsonOrPath:(NSString *)jsonOrPath
649
+ resolver:(RCTPromiseResolveBlock)resolve
650
+ rejecter:(RCTPromiseRejectBlock)reject)
651
+ {
652
+ [self ensureSTT];
653
+ NSError *error = nil;
654
+ if (![self.stt addSpeakerWithId:(speakerId ?: @"default") jsonOrPath:(jsonOrPath ?: @"") error:&error]) {
655
+ reject(@"sv_add_failed", error.localizedDescription ?: @"addSpeaker failed", error);
656
+ return;
657
+ }
658
+ resolve([self.stt getSpeakerIds]);
659
+ }
660
+
661
+ RCT_EXPORT_METHOD(setSpeakers:(NSArray *)speakers
662
+ resolver:(RCTPromiseResolveBlock)resolve
663
+ rejecter:(RCTPromiseRejectBlock)reject)
664
+ {
665
+ [self ensureSTT];
666
+ NSError *error = nil;
667
+ if (![self.stt setSpeakers:SBSpeakerItems(speakers) error:&error]) {
668
+ reject(@"sv_set_failed", error.localizedDescription ?: @"setSpeakers failed", error);
669
+ return;
670
+ }
671
+ resolve([self.stt getSpeakerIds]);
672
+ }
673
+
674
+ RCT_EXPORT_METHOD(removeSpeaker:(NSString *)speakerId
675
+ resolver:(RCTPromiseResolveBlock)resolve
676
+ rejecter:(RCTPromiseRejectBlock)reject)
677
+ {
678
+ if (!self.stt) { resolve(@(NO)); return; }
679
+ resolve(@([self.stt removeSpeakerWithId:(speakerId ?: @"")]));
680
+ }
681
+
682
+ RCT_EXPORT_METHOD(getSpeakerIds:(RCTPromiseResolveBlock)resolve
683
+ rejecter:(RCTPromiseRejectBlock)reject)
684
+ {
685
+ resolve(self.stt ? [self.stt getSpeakerIds] : @[]);
686
+ }
687
+
688
+ RCT_EXPORT_METHOD(startSpeechWithSVSpeakers:(NSString *)locale
689
+ speakers:(NSArray *)speakers
690
+ timeoutMs:(nonnull NSNumber *)timeoutMs
691
+ resolver:(RCTPromiseResolveBlock)resolve
692
+ rejecter:(RCTPromiseRejectBlock)reject)
693
+ {
694
+ [self ensureSTT];
695
+ self.sttEngineHot = NO;
696
+ [self.stt startSpeechWithLocaleStr:locale speakers:SBSpeakerItems(speakers)];
697
+ [self waitForSTTEngineHotWithTimeoutMs:timeoutMs completion:^(BOOL ok) {
698
+ if (!ok) {
699
+ reject(@"stt_start_timeout", @"STT did not become ready before timeout", nil);
700
+ return;
701
+ }
702
+ resolve(@{@"ok": @(YES)});
703
+ }];
704
+ }
705
+
606
706
  RCT_EXPORT_METHOD(initAll:(NSDictionary *)opts
607
707
  resolver:(RCTPromiseResolveBlock)resolve
608
708
  rejecter:(RCTPromiseRejectBlock)reject)
@@ -615,7 +715,6 @@ RCT_EXPORT_METHOD(initAll:(NSDictionary *)opts
615
715
  self.sttEngineHot = NO;
616
716
 
617
717
  NSString *locale = opts[@"locale"] ?: @"en-US";
618
- NSString *onboardingJsonPath = opts[@"onboardingJsonPath"];
619
718
  NSString *modelPath = opts[@"model"];
620
719
  NSNumber *timeoutMs = opts[@"timeoutMs"];
621
720
  if (modelPath.length == 0) {
@@ -632,11 +731,7 @@ RCT_EXPORT_METHOD(initAll:(NSDictionary *)opts
632
731
  [self.stt setLicenseWithLicenseKey:self.lastLicenseKey];
633
732
  }
634
733
  }
635
- if (onboardingJsonPath && (id)onboardingJsonPath != [NSNull null] && onboardingJsonPath.length > 0) {
636
- [self.stt startSpeechWithLocaleStr:locale onboardingJsonPath:onboardingJsonPath];
637
- } else {
638
- [self.stt startSpeechWithLocaleStr:locale];
639
- }
734
+ [self startSTTWithLocale:locale opts:opts];
640
735
 
641
736
  // 2) TTS next
642
737
  NSURL *modelURL = nil;
@@ -740,17 +835,12 @@ RCT_EXPORT_METHOD(initWithoutModel:(NSDictionary *)opts
740
835
  self.sttEngineHot = NO;
741
836
 
742
837
  NSString *locale = opts[@"locale"] ?: @"en-US";
743
- NSString *onboardingJsonPath = opts[@"onboardingJsonPath"];
744
838
  NSNumber *timeoutMs = opts[@"timeoutMs"];
745
839
 
746
840
  [self tearDownSTT];
747
841
 
748
842
  [self ensureSTT];
749
- if (onboardingJsonPath && (id)onboardingJsonPath != [NSNull null] && onboardingJsonPath.length > 0) {
750
- [self.stt startSpeechWithLocaleStr:locale onboardingJsonPath:onboardingJsonPath];
751
- } else {
752
- [self.stt startSpeechWithLocaleStr:locale];
753
- }
843
+ [self startSTTWithLocale:locale opts:opts];
754
844
 
755
845
  [self waitForSTTEngineHotWithTimeoutMs:timeoutMs completion:^(BOOL ok) {
756
846
  if (!ok) {
@@ -1113,6 +1203,12 @@ RCT_EXPORT_METHOD(setAECEnabled:(BOOL)enabled
1113
1203
  resolve(@(YES));
1114
1204
  }
1115
1205
 
1206
+ RCT_EXPORT_METHOD(getAllVoices:(RCTPromiseResolveBlock)resolve
1207
+ rejecter:(RCTPromiseRejectBlock)reject)
1208
+ {
1209
+ resolve(self.tts ? ([self.tts getAllVoices] ?: @[]) : @[]);
1210
+ }
1211
+
1116
1212
  RCT_EXPORT_METHOD(changeVoice:(NSString *)name
1117
1213
  resolver:(RCTPromiseResolveBlock)resolve
1118
1214
  rejecter:(RCTPromiseRejectBlock)reject)
@@ -276,6 +276,12 @@ RCT_EXPORT_METHOD(initTTS:(NSDictionary *)configDict
276
276
  }];
277
277
  }
278
278
 
279
+ RCT_EXPORT_METHOD(getAllVoices:(RCTPromiseResolveBlock)resolve
280
+ rejecter:(RCTPromiseRejectBlock)reject)
281
+ {
282
+ resolve(self.ttsInstance ? ([self.ttsInstance getAllVoices] ?: @[]) : @[]);
283
+ }
284
+
279
285
  RCT_EXPORT_METHOD(changeVoice:(NSString *)name
280
286
  resolver:(RCTPromiseResolveBlock)resolve
281
287
  rejecter:(RCTPromiseRejectBlock)reject)
@@ -350,6 +350,10 @@ SWIFT_CLASS("_TtC10DavoiceTTS10DaVoiceTTS")
350
350
  + (void)setUseDavoiceProprietaryPhonemizer:(BOOL)enabled;
351
351
  + (BOOL)getUseDavoiceProprietaryPhonemizer SWIFT_WARN_UNUSED_RESULT;
352
352
  - (BOOL)isUsingDavoiceProprietaryPhonemizer SWIFT_WARN_UNUSED_RESULT;
353
+ /// Voices available in the loaded .dm (the names changeVoice() accepts, the
354
+ /// first being the default). Empty for v1 models, a .dm without voices, or
355
+ /// after destroy().
356
+ - (NSArray<NSString *> * _Nonnull)getAllVoices SWIFT_WARN_UNUSED_RESULT;
353
357
  - (void)changeVoice:(NSString * _Nonnull)name completion:(void (^ _Nonnull)(NSInteger))completion;
354
358
  @property (nonatomic, copy) void (^ _Nullable onLastUtteranceFinished)(void);
355
359
  + (BOOL)activateLicenseWithLicenseKey:(NSString * _Nonnull)licenseKey SWIFT_WARN_UNUSED_RESULT;
@@ -416,7 +420,27 @@ SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSArray<NSStri
416
420
  - (void)isSpeechAvailable:(void (^ _Nonnull)(BOOL))completion;
417
421
  - (BOOL)isRecognizing SWIFT_WARN_UNUSED_RESULT;
418
422
  - (void)startSpeechWithLocaleStr:(NSString * _Nullable)localeStr;
423
+ /// Starts STT with one speaker. <code>onboardingJsonPath</code> may be a path or the JSON
424
+ /// itself. The speaker is added to the current set (same id or same voiceprint
425
+ /// replaces the older entry) under the id “default”.
419
426
  - (void)startSpeechWithLocaleStr:(NSString * _Nullable)localeStr onboardingJsonPath:(NSString * _Nonnull)onboardingJsonPath;
427
+ - (void)startSpeechWithLocaleStr:(NSString * _Nullable)localeStr onboardingJsonPath:(NSString * _Nonnull)onboardingJsonPath speakerId:(NSString * _Nonnull)speakerId;
428
+ /// Starts STT with an array of speakers, replacing the current set.
429
+ /// Each item: [“id”: speakerId, “json”: JSON string or path to the JSON file].
430
+ - (void)startSpeechWithLocaleStr:(NSString * _Nullable)localeStr speakers:(NSArray<NSDictionary<NSString *, NSString *> *> * _Nonnull)speakers;
431
+ /// Adds one speaker (JSON string or path). Same id or same voiceprint replaces
432
+ /// the older entry. Applies immediately when STT is running, otherwise at the
433
+ /// next start. Throws if the JSON can’t be read or its audio-feature settings
434
+ /// differ from the running engine’s.
435
+ - (BOOL)addSpeakerWithId:(NSString * _Nonnull)id jsonOrPath:(NSString * _Nonnull)jsonOrPath error:(NSError * _Nullable * _Nullable)error;
436
+ /// Replaces the whole speaker set. Items: [“id”: …, “json”: JSON string or path].
437
+ /// An empty array turns speaker verification off.
438
+ - (BOOL)setSpeakers:(NSArray<NSDictionary<NSString *, NSString *> *> * _Nonnull)speakers error:(NSError * _Nullable * _Nullable)error;
439
+ /// Removes a speaker by id. Removing the last one turns the gate off (all audio
440
+ /// passes). Returns false if the id wasn’t enrolled.
441
+ - (BOOL)removeSpeakerWithId:(NSString * _Nonnull)id;
442
+ /// Ids of the enrolled speakers, in insertion order.
443
+ - (NSArray<NSString *> * _Nonnull)getSpeakerIds SWIFT_WARN_UNUSED_RESULT;
420
444
  - (void)stopSpeech:(void (^ _Nullable)(BOOL))completion;
421
445
  - (void)cancelSpeech:(void (^ _Nullable)(BOOL))completion;
422
446
  - (void)destroySpeech:(void (^ _Nullable)(BOOL))completion;