@iternio/react-native-tts 4.1.2
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 +268 -0
- package/TextToSpeech.podspec +21 -0
- package/android/build.gradle +41 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/net/no_mad/tts/TextToSpeechModule.java +538 -0
- package/android/src/main/java/net/no_mad/tts/TextToSpeechPackage.java +31 -0
- package/index.d.ts +118 -0
- package/index.js +127 -0
- package/ios/TextToSpeech/TextToSpeech.h +20 -0
- package/ios/TextToSpeech/TextToSpeech.m +285 -0
- package/ios/TextToSpeech.xcodeproj/project.pbxproj +276 -0
- package/ios/TextToSpeech.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/TextToSpeech.xcodeproj/project.xcworkspace/xcuserdata/anton.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/TextToSpeech.xcodeproj/xcuserdata/anton.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +5 -0
- package/ios/TextToSpeech.xcodeproj/xcuserdata/anton.xcuserdatad/xcschemes/TextToSpeech.xcscheme +80 -0
- package/ios/TextToSpeech.xcodeproj/xcuserdata/anton.xcuserdatad/xcschemes/xcschememanagement.plist +22 -0
- package/package.json +27 -0
- package/windows/README.md +25 -0
- package/windows/RNTTS/PropertySheet.props +16 -0
- package/windows/RNTTS/RNTTS.cpp +224 -0
- package/windows/RNTTS/RNTTS.def +3 -0
- package/windows/RNTTS/RNTTS.h +75 -0
- package/windows/RNTTS/RNTTS.vcxproj +163 -0
- package/windows/RNTTS/RNTTS.vcxproj.filters +33 -0
- package/windows/RNTTS/ReactPackageProvider.cpp +15 -0
- package/windows/RNTTS/ReactPackageProvider.h +16 -0
- package/windows/RNTTS/ReactPackageProvider.idl +9 -0
- package/windows/RNTTS/packages.config +4 -0
- package/windows/RNTTS/pch.cpp +1 -0
- package/windows/RNTTS/pch.h +11 -0
- package/windows/RNTTS62.sln +254 -0
- package/windows/RNTTS63.sln +226 -0
package/index.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
|
|
2
|
+
|
|
3
|
+
const TextToSpeech = NativeModules.TextToSpeech;
|
|
4
|
+
|
|
5
|
+
class Tts extends NativeEventEmitter {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(TextToSpeech);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
getInitStatus() {
|
|
11
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
12
|
+
return Promise.resolve(true);
|
|
13
|
+
}
|
|
14
|
+
return TextToSpeech.getInitStatus();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
requestInstallEngine() {
|
|
18
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
19
|
+
return Promise.resolve(true);
|
|
20
|
+
}
|
|
21
|
+
return TextToSpeech.requestInstallEngine();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
requestInstallData() {
|
|
25
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
26
|
+
return Promise.resolve(true);
|
|
27
|
+
}
|
|
28
|
+
return TextToSpeech.requestInstallData();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
setDucking(enabled) {
|
|
32
|
+
if (Platform.OS === 'windows') {
|
|
33
|
+
return Promise.resolve(true);
|
|
34
|
+
}
|
|
35
|
+
return TextToSpeech.setDucking(enabled);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setDefaultEngine(engineName) {
|
|
39
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
40
|
+
return Promise.resolve(true);
|
|
41
|
+
}
|
|
42
|
+
return TextToSpeech.setDefaultEngine(engineName);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
setDefaultVoice(voiceId) {
|
|
46
|
+
return TextToSpeech.setDefaultVoice(voiceId);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setDefaultRate(rate, skipTransform) {
|
|
50
|
+
return TextToSpeech.setDefaultRate(rate, !!skipTransform);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setDefaultPitch(pitch) {
|
|
54
|
+
return TextToSpeech.setDefaultPitch(pitch);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
setDefaultLanguage(language) {
|
|
58
|
+
return TextToSpeech.setDefaultLanguage(language);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setIgnoreSilentSwitch(ignoreSilentSwitch) {
|
|
62
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
63
|
+
return TextToSpeech.setIgnoreSilentSwitch(ignoreSilentSwitch);
|
|
64
|
+
}
|
|
65
|
+
return Promise.resolve(true);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
voices() {
|
|
69
|
+
return TextToSpeech.voices();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
engines() {
|
|
73
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
74
|
+
return Promise.resolve([]);
|
|
75
|
+
}
|
|
76
|
+
return TextToSpeech.engines();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
speak(utterance, options = {}) {
|
|
80
|
+
// compatibility with old-style voiceId argument passing
|
|
81
|
+
if (typeof options === 'string') {
|
|
82
|
+
if (Platform.OS === 'ios') {
|
|
83
|
+
return TextToSpeech.speak(utterance, { iosVoiceId: options });
|
|
84
|
+
} else {
|
|
85
|
+
return TextToSpeech.speak(utterance, {});
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (Platform.OS === 'ios' || Platform.OS === 'windows') {
|
|
89
|
+
return TextToSpeech.speak(utterance, options);
|
|
90
|
+
} else {
|
|
91
|
+
return TextToSpeech.speak(utterance, options.androidParams || {});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
stop(onWordBoundary) {
|
|
97
|
+
if (Platform.OS === 'ios') {
|
|
98
|
+
return TextToSpeech.stop(onWordBoundary);
|
|
99
|
+
} else {
|
|
100
|
+
return TextToSpeech.stop();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
pause(onWordBoundary) {
|
|
105
|
+
if (Platform.OS === 'ios') {
|
|
106
|
+
return TextToSpeech.pause(onWordBoundary);
|
|
107
|
+
}
|
|
108
|
+
return Promise.resolve(false);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
resume() {
|
|
112
|
+
if (Platform.OS === 'ios') {
|
|
113
|
+
return TextToSpeech.resume();
|
|
114
|
+
}
|
|
115
|
+
return Promise.resolve(false);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
addEventListener(type, handler) {
|
|
119
|
+
return this.addListener(type, handler);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
removeEventListener(type, handler) {
|
|
123
|
+
this.removeListener(type, handler);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default new Tts();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//
|
|
2
|
+
// TextToSpeech.h
|
|
3
|
+
// TextToSpeech
|
|
4
|
+
//
|
|
5
|
+
// Created by Anton Krasovsky on 27/09/2016.
|
|
6
|
+
// Copyright © 2016 Anton Krasovsky. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <React/RCTBridgeModule.h>
|
|
10
|
+
#import <React/RCTEventEmitter.h>
|
|
11
|
+
|
|
12
|
+
@import AVFoundation;
|
|
13
|
+
|
|
14
|
+
@interface TextToSpeech : RCTEventEmitter <RCTBridgeModule, AVSpeechSynthesizerDelegate>
|
|
15
|
+
@property (nonatomic, strong) AVSpeechSynthesizer *synthesizer;
|
|
16
|
+
@property (nonatomic, strong) AVSpeechSynthesisVoice *defaultVoice;
|
|
17
|
+
@property (nonatomic) float defaultRate;
|
|
18
|
+
@property (nonatomic) float defaultPitch;
|
|
19
|
+
@property (nonatomic) bool ducking;
|
|
20
|
+
@end
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
//
|
|
2
|
+
// TextToSpeech.m
|
|
3
|
+
// TextToSpeech
|
|
4
|
+
//
|
|
5
|
+
// Created by Anton Krasovsky on 27/09/2016.
|
|
6
|
+
// Copyright © 2016 Anton Krasovsky. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <React/RCTBridge.h>
|
|
10
|
+
#import <React/RCTEventDispatcher.h>
|
|
11
|
+
#import <React/RCTLog.h>
|
|
12
|
+
|
|
13
|
+
#import "TextToSpeech.h"
|
|
14
|
+
|
|
15
|
+
@implementation TextToSpeech {
|
|
16
|
+
NSString * _ignoreSilentSwitch;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@synthesize bridge = _bridge;
|
|
20
|
+
|
|
21
|
+
RCT_EXPORT_MODULE()
|
|
22
|
+
|
|
23
|
+
-(NSArray<NSString *> *)supportedEvents
|
|
24
|
+
{
|
|
25
|
+
return @[@"tts-start", @"tts-finish", @"tts-pause", @"tts-resume", @"tts-progress", @"tts-cancel"];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
-(instancetype)init
|
|
29
|
+
{
|
|
30
|
+
self = [super init];
|
|
31
|
+
if (self) {
|
|
32
|
+
_synthesizer = [AVSpeechSynthesizer new];
|
|
33
|
+
_synthesizer.delegate = self;
|
|
34
|
+
_ducking = false;
|
|
35
|
+
_ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return self;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
+ (bool)requiresMainQueueSetup
|
|
42
|
+
{
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
RCT_EXPORT_METHOD(speak:(NSString *)text
|
|
47
|
+
params:(NSDictionary *)params
|
|
48
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
49
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
50
|
+
{
|
|
51
|
+
if(!text) {
|
|
52
|
+
reject(@"no_text", @"No text to speak", nil);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:text];
|
|
57
|
+
|
|
58
|
+
NSString* voice = [params valueForKey:@"iosVoiceId"];
|
|
59
|
+
if (voice) {
|
|
60
|
+
utterance.voice = [AVSpeechSynthesisVoice voiceWithIdentifier:voice];
|
|
61
|
+
} else if (_defaultVoice) {
|
|
62
|
+
utterance.voice = _defaultVoice;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
float rate = [[params valueForKey:@"rate"] floatValue];
|
|
66
|
+
if (rate) {
|
|
67
|
+
if(rate > AVSpeechUtteranceMinimumSpeechRate && rate < AVSpeechUtteranceMaximumSpeechRate) {
|
|
68
|
+
utterance.rate = rate;
|
|
69
|
+
} else {
|
|
70
|
+
reject(@"bad_rate", @"Wrong rate value", nil);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
} else if (_defaultRate) {
|
|
74
|
+
utterance.rate = _defaultRate;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (_defaultPitch) {
|
|
78
|
+
utterance.pitchMultiplier = _defaultPitch;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if([_ignoreSilentSwitch isEqualToString:@"ignore"]) {
|
|
82
|
+
[[AVAudioSession sharedInstance]
|
|
83
|
+
setCategory:AVAudioSessionCategoryPlayback
|
|
84
|
+
mode:AVAudioSessionModeVoicePrompt
|
|
85
|
+
// This will pause a spoken audio like podcast or audiobook and duck the volume for music
|
|
86
|
+
options:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
|
|
87
|
+
error:nil
|
|
88
|
+
];
|
|
89
|
+
} else if([_ignoreSilentSwitch isEqualToString:@"obey"]) {
|
|
90
|
+
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[self.synthesizer speakUtterance:utterance];
|
|
94
|
+
resolve([NSNumber numberWithUnsignedLong:utterance.hash]);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
RCT_EXPORT_METHOD(stop:(bool *)onWordBoundary resolve:(RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject)
|
|
98
|
+
{
|
|
99
|
+
AVSpeechBoundary boundary;
|
|
100
|
+
|
|
101
|
+
if(onWordBoundary != NULL && onWordBoundary) {
|
|
102
|
+
boundary = AVSpeechBoundaryWord;
|
|
103
|
+
} else {
|
|
104
|
+
boundary = AVSpeechBoundaryImmediate;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
bool stopped = [self.synthesizer stopSpeakingAtBoundary:boundary];
|
|
108
|
+
|
|
109
|
+
resolve([NSNumber numberWithBool:stopped]);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
RCT_EXPORT_METHOD(pause:(bool *)onWordBoundary resolve:(RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject)
|
|
113
|
+
{
|
|
114
|
+
AVSpeechBoundary boundary;
|
|
115
|
+
|
|
116
|
+
if(onWordBoundary != NULL && onWordBoundary) {
|
|
117
|
+
boundary = AVSpeechBoundaryWord;
|
|
118
|
+
} else {
|
|
119
|
+
boundary = AVSpeechBoundaryImmediate;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
bool paused = [self.synthesizer pauseSpeakingAtBoundary:boundary];
|
|
123
|
+
|
|
124
|
+
resolve([NSNumber numberWithBool:paused]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
RCT_EXPORT_METHOD(resume:(RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject)
|
|
128
|
+
{
|
|
129
|
+
bool continued = [self.synthesizer continueSpeaking];
|
|
130
|
+
|
|
131
|
+
resolve([NSNumber numberWithBool:continued]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
RCT_EXPORT_METHOD(setDucking:(bool *)ducking
|
|
136
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
137
|
+
reject:(__unused RCTPromiseRejectBlock)reject)
|
|
138
|
+
{
|
|
139
|
+
_ducking = ducking;
|
|
140
|
+
|
|
141
|
+
if(ducking) {
|
|
142
|
+
AVAudioSession *session = [AVAudioSession sharedInstance];
|
|
143
|
+
[session setCategory:AVAudioSessionCategoryPlayback
|
|
144
|
+
withOptions:AVAudioSessionCategoryOptionDuckOthers
|
|
145
|
+
error:nil];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
resolve(@"success");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
RCT_EXPORT_METHOD(setDefaultLanguage:(NSString *)language
|
|
153
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
154
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
155
|
+
{
|
|
156
|
+
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:language];
|
|
157
|
+
|
|
158
|
+
if(voice) {
|
|
159
|
+
_defaultVoice = voice;
|
|
160
|
+
resolve(@"success");
|
|
161
|
+
} else {
|
|
162
|
+
reject(@"not_found", @"Language not found", nil);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
RCT_EXPORT_METHOD(setDefaultVoice:(NSString *)identifier
|
|
167
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
168
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
169
|
+
{
|
|
170
|
+
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithIdentifier:identifier];
|
|
171
|
+
|
|
172
|
+
if(voice) {
|
|
173
|
+
_defaultVoice = voice;
|
|
174
|
+
resolve(@"success");
|
|
175
|
+
} else {
|
|
176
|
+
reject(@"not_found", @"Voice not found", nil);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
RCT_EXPORT_METHOD(setDefaultRate:(float)rate
|
|
181
|
+
skipTransform:(bool *)skipTransform // not used, compatibility with Android native module signature
|
|
182
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
183
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
184
|
+
{
|
|
185
|
+
if(rate > AVSpeechUtteranceMinimumSpeechRate && rate < AVSpeechUtteranceMaximumSpeechRate) {
|
|
186
|
+
_defaultRate = rate;
|
|
187
|
+
resolve(@"success");
|
|
188
|
+
} else {
|
|
189
|
+
reject(@"bad_rate", @"Wrong rate value", nil);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
RCT_EXPORT_METHOD(setDefaultPitch:(float)pitch
|
|
194
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
195
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
196
|
+
{
|
|
197
|
+
if(pitch > 0.5 && pitch < 2.0) {
|
|
198
|
+
_defaultPitch = pitch;
|
|
199
|
+
resolve(@"success");
|
|
200
|
+
} else {
|
|
201
|
+
reject(@"bad_rate", @"Wrong pitch value", nil);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
RCT_EXPORT_METHOD(setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch
|
|
206
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
207
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
208
|
+
{
|
|
209
|
+
if(ignoreSilentSwitch) {
|
|
210
|
+
_ignoreSilentSwitch = ignoreSilentSwitch;
|
|
211
|
+
resolve(@"success");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
RCT_EXPORT_METHOD(voices:(RCTPromiseResolveBlock)resolve
|
|
216
|
+
reject:(__unused RCTPromiseRejectBlock)reject)
|
|
217
|
+
{
|
|
218
|
+
NSMutableArray *voices = [NSMutableArray new];
|
|
219
|
+
|
|
220
|
+
for (AVSpeechSynthesisVoice *voice in [AVSpeechSynthesisVoice speechVoices]) {
|
|
221
|
+
[voices addObject:@{
|
|
222
|
+
@"id": voice.identifier,
|
|
223
|
+
@"name": voice.name,
|
|
224
|
+
@"language": voice.language,
|
|
225
|
+
@"quality": (voice.quality == AVSpeechSynthesisVoiceQualityEnhanced) ? @500 : @300
|
|
226
|
+
}];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
resolve(voices);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance
|
|
233
|
+
{
|
|
234
|
+
if(_ducking) {
|
|
235
|
+
[[AVAudioSession sharedInstance] setActive:true error:nil];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
[self sendEventWithName:@"tts-start" body:@{@"utteranceId":[NSNumber numberWithUnsignedLong:utterance.hash]}];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance
|
|
242
|
+
{
|
|
243
|
+
if(_ducking) {
|
|
244
|
+
[[AVAudioSession sharedInstance] setActive:false error:nil];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
[self sendEventWithName:@"tts-finish" body:@{@"utteranceId":[NSNumber numberWithUnsignedLong:utterance.hash]}];
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance
|
|
251
|
+
{
|
|
252
|
+
if(_ducking) {
|
|
253
|
+
[[AVAudioSession sharedInstance] setActive:false error:nil];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
[self sendEventWithName:@"tts-pause" body:@{@"utteranceId":[NSNumber numberWithUnsignedLong:utterance.hash]}];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance
|
|
260
|
+
{
|
|
261
|
+
if(_ducking) {
|
|
262
|
+
[[AVAudioSession sharedInstance] setActive:true error:nil];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
[self sendEventWithName:@"tts-resume" body:@{@"utteranceId":[NSNumber numberWithUnsignedLong:utterance.hash]}];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance
|
|
269
|
+
{
|
|
270
|
+
[self sendEventWithName:@"tts-progress"
|
|
271
|
+
body:@{@"location": [NSNumber numberWithUnsignedLong:characterRange.location],
|
|
272
|
+
@"length": [NSNumber numberWithUnsignedLong:characterRange.length],
|
|
273
|
+
@"utteranceId": [NSNumber numberWithUnsignedLong:utterance.hash]}];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance
|
|
277
|
+
{
|
|
278
|
+
if(_ducking) {
|
|
279
|
+
[[AVAudioSession sharedInstance] setActive:false error:nil];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
[self sendEventWithName:@"tts-cancel" body:@{@"utteranceId":[NSNumber numberWithUnsignedLong:utterance.hash]}];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@end
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// !$*UTF8*$!
|
|
2
|
+
{
|
|
3
|
+
archiveVersion = 1;
|
|
4
|
+
classes = {
|
|
5
|
+
};
|
|
6
|
+
objectVersion = 46;
|
|
7
|
+
objects = {
|
|
8
|
+
|
|
9
|
+
/* Begin PBXBuildFile section */
|
|
10
|
+
3A6FB20D1D99E12200593599 /* TextToSpeech.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A6FB20C1D99E12200593599 /* TextToSpeech.m */; };
|
|
11
|
+
3A6FB20E1D99E12200593599 /* TextToSpeech.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A6FB20B1D99E12200593599 /* TextToSpeech.h */; };
|
|
12
|
+
/* End PBXBuildFile section */
|
|
13
|
+
|
|
14
|
+
/* Begin PBXCopyFilesBuildPhase section */
|
|
15
|
+
3A6FB2061D99E12200593599 /* CopyFiles */ = {
|
|
16
|
+
isa = PBXCopyFilesBuildPhase;
|
|
17
|
+
buildActionMask = 2147483647;
|
|
18
|
+
dstPath = "include/$(PRODUCT_NAME)";
|
|
19
|
+
dstSubfolderSpec = 16;
|
|
20
|
+
files = (
|
|
21
|
+
3A6FB20E1D99E12200593599 /* TextToSpeech.h in CopyFiles */,
|
|
22
|
+
);
|
|
23
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
24
|
+
};
|
|
25
|
+
/* End PBXCopyFilesBuildPhase section */
|
|
26
|
+
|
|
27
|
+
/* Begin PBXFileReference section */
|
|
28
|
+
3A6FB2081D99E12200593599 /* libTextToSpeech.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTextToSpeech.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
29
|
+
3A6FB20B1D99E12200593599 /* TextToSpeech.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextToSpeech.h; sourceTree = "<group>"; };
|
|
30
|
+
3A6FB20C1D99E12200593599 /* TextToSpeech.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TextToSpeech.m; sourceTree = "<group>"; };
|
|
31
|
+
/* End PBXFileReference section */
|
|
32
|
+
|
|
33
|
+
/* Begin PBXFrameworksBuildPhase section */
|
|
34
|
+
3A6FB2051D99E12200593599 /* Frameworks */ = {
|
|
35
|
+
isa = PBXFrameworksBuildPhase;
|
|
36
|
+
buildActionMask = 2147483647;
|
|
37
|
+
files = (
|
|
38
|
+
);
|
|
39
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
40
|
+
};
|
|
41
|
+
/* End PBXFrameworksBuildPhase section */
|
|
42
|
+
|
|
43
|
+
/* Begin PBXGroup section */
|
|
44
|
+
3A6FB1FF1D99E12200593599 = {
|
|
45
|
+
isa = PBXGroup;
|
|
46
|
+
children = (
|
|
47
|
+
3A6FB20A1D99E12200593599 /* TextToSpeech */,
|
|
48
|
+
3A6FB2091D99E12200593599 /* Products */,
|
|
49
|
+
);
|
|
50
|
+
sourceTree = "<group>";
|
|
51
|
+
};
|
|
52
|
+
3A6FB2091D99E12200593599 /* Products */ = {
|
|
53
|
+
isa = PBXGroup;
|
|
54
|
+
children = (
|
|
55
|
+
3A6FB2081D99E12200593599 /* libTextToSpeech.a */,
|
|
56
|
+
);
|
|
57
|
+
name = Products;
|
|
58
|
+
sourceTree = "<group>";
|
|
59
|
+
};
|
|
60
|
+
3A6FB20A1D99E12200593599 /* TextToSpeech */ = {
|
|
61
|
+
isa = PBXGroup;
|
|
62
|
+
children = (
|
|
63
|
+
3A6FB20B1D99E12200593599 /* TextToSpeech.h */,
|
|
64
|
+
3A6FB20C1D99E12200593599 /* TextToSpeech.m */,
|
|
65
|
+
);
|
|
66
|
+
path = TextToSpeech;
|
|
67
|
+
sourceTree = "<group>";
|
|
68
|
+
};
|
|
69
|
+
/* End PBXGroup section */
|
|
70
|
+
|
|
71
|
+
/* Begin PBXNativeTarget section */
|
|
72
|
+
3A6FB2071D99E12200593599 /* TextToSpeech */ = {
|
|
73
|
+
isa = PBXNativeTarget;
|
|
74
|
+
buildConfigurationList = 3A6FB2111D99E12200593599 /* Build configuration list for PBXNativeTarget "TextToSpeech" */;
|
|
75
|
+
buildPhases = (
|
|
76
|
+
3A6FB2041D99E12200593599 /* Sources */,
|
|
77
|
+
3A6FB2051D99E12200593599 /* Frameworks */,
|
|
78
|
+
3A6FB2061D99E12200593599 /* CopyFiles */,
|
|
79
|
+
);
|
|
80
|
+
buildRules = (
|
|
81
|
+
);
|
|
82
|
+
dependencies = (
|
|
83
|
+
);
|
|
84
|
+
name = TextToSpeech;
|
|
85
|
+
productName = TextToSpeech;
|
|
86
|
+
productReference = 3A6FB2081D99E12200593599 /* libTextToSpeech.a */;
|
|
87
|
+
productType = "com.apple.product-type.library.static";
|
|
88
|
+
};
|
|
89
|
+
/* End PBXNativeTarget section */
|
|
90
|
+
|
|
91
|
+
/* Begin PBXProject section */
|
|
92
|
+
3A6FB2001D99E12200593599 /* Project object */ = {
|
|
93
|
+
isa = PBXProject;
|
|
94
|
+
attributes = {
|
|
95
|
+
LastUpgradeCheck = 0800;
|
|
96
|
+
ORGANIZATIONNAME = "Anton Krasovsky";
|
|
97
|
+
TargetAttributes = {
|
|
98
|
+
3A6FB2071D99E12200593599 = {
|
|
99
|
+
CreatedOnToolsVersion = 8.0;
|
|
100
|
+
DevelopmentTeam = 6W9ZGN9YUK;
|
|
101
|
+
ProvisioningStyle = Automatic;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
buildConfigurationList = 3A6FB2031D99E12200593599 /* Build configuration list for PBXProject "TextToSpeech" */;
|
|
106
|
+
compatibilityVersion = "Xcode 3.2";
|
|
107
|
+
developmentRegion = English;
|
|
108
|
+
hasScannedForEncodings = 0;
|
|
109
|
+
knownRegions = (
|
|
110
|
+
en,
|
|
111
|
+
);
|
|
112
|
+
mainGroup = 3A6FB1FF1D99E12200593599;
|
|
113
|
+
productRefGroup = 3A6FB2091D99E12200593599 /* Products */;
|
|
114
|
+
projectDirPath = "";
|
|
115
|
+
projectRoot = "";
|
|
116
|
+
targets = (
|
|
117
|
+
3A6FB2071D99E12200593599 /* TextToSpeech */,
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
/* End PBXProject section */
|
|
121
|
+
|
|
122
|
+
/* Begin PBXSourcesBuildPhase section */
|
|
123
|
+
3A6FB2041D99E12200593599 /* Sources */ = {
|
|
124
|
+
isa = PBXSourcesBuildPhase;
|
|
125
|
+
buildActionMask = 2147483647;
|
|
126
|
+
files = (
|
|
127
|
+
3A6FB20D1D99E12200593599 /* TextToSpeech.m in Sources */,
|
|
128
|
+
);
|
|
129
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
130
|
+
};
|
|
131
|
+
/* End PBXSourcesBuildPhase section */
|
|
132
|
+
|
|
133
|
+
/* Begin XCBuildConfiguration section */
|
|
134
|
+
3A6FB20F1D99E12200593599 /* Debug */ = {
|
|
135
|
+
isa = XCBuildConfiguration;
|
|
136
|
+
buildSettings = {
|
|
137
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
138
|
+
CLANG_ANALYZER_NONNULL = YES;
|
|
139
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
140
|
+
CLANG_CXX_LIBRARY = "libc++";
|
|
141
|
+
CLANG_ENABLE_MODULES = YES;
|
|
142
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
|
143
|
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
144
|
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
145
|
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
146
|
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
|
147
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
|
148
|
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
149
|
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
150
|
+
CLANG_WARN_INT_CONVERSION = YES;
|
|
151
|
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
152
|
+
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
|
153
|
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
154
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
155
|
+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
156
|
+
COPY_PHASE_STRIP = NO;
|
|
157
|
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
158
|
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
159
|
+
ENABLE_TESTABILITY = YES;
|
|
160
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
161
|
+
GCC_DYNAMIC_NO_PIC = NO;
|
|
162
|
+
GCC_NO_COMMON_BLOCKS = YES;
|
|
163
|
+
GCC_OPTIMIZATION_LEVEL = 0;
|
|
164
|
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
165
|
+
"DEBUG=1",
|
|
166
|
+
"$(inherited)",
|
|
167
|
+
);
|
|
168
|
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
169
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
170
|
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
171
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
172
|
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
173
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
174
|
+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
175
|
+
MTL_ENABLE_DEBUG_INFO = YES;
|
|
176
|
+
ONLY_ACTIVE_ARCH = YES;
|
|
177
|
+
SDKROOT = iphoneos;
|
|
178
|
+
};
|
|
179
|
+
name = Debug;
|
|
180
|
+
};
|
|
181
|
+
3A6FB2101D99E12200593599 /* Release */ = {
|
|
182
|
+
isa = XCBuildConfiguration;
|
|
183
|
+
buildSettings = {
|
|
184
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
185
|
+
CLANG_ANALYZER_NONNULL = YES;
|
|
186
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
187
|
+
CLANG_CXX_LIBRARY = "libc++";
|
|
188
|
+
CLANG_ENABLE_MODULES = YES;
|
|
189
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
|
190
|
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
191
|
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
192
|
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
193
|
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
|
194
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
|
195
|
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
196
|
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
197
|
+
CLANG_WARN_INT_CONVERSION = YES;
|
|
198
|
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
199
|
+
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
|
200
|
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
201
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
202
|
+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
203
|
+
COPY_PHASE_STRIP = NO;
|
|
204
|
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
205
|
+
ENABLE_NS_ASSERTIONS = NO;
|
|
206
|
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
207
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
208
|
+
GCC_NO_COMMON_BLOCKS = YES;
|
|
209
|
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
210
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
211
|
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
212
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
213
|
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
214
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
215
|
+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
216
|
+
MTL_ENABLE_DEBUG_INFO = NO;
|
|
217
|
+
SDKROOT = iphoneos;
|
|
218
|
+
VALIDATE_PRODUCT = YES;
|
|
219
|
+
};
|
|
220
|
+
name = Release;
|
|
221
|
+
};
|
|
222
|
+
3A6FB2121D99E12200593599 /* Debug */ = {
|
|
223
|
+
isa = XCBuildConfiguration;
|
|
224
|
+
buildSettings = {
|
|
225
|
+
DEVELOPMENT_TEAM = "";
|
|
226
|
+
HEADER_SEARCH_PATHS = (
|
|
227
|
+
"$(inherited)",
|
|
228
|
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
229
|
+
"$(SRCROOT)/../../react-native/React/**",
|
|
230
|
+
);
|
|
231
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
232
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
233
|
+
SKIP_INSTALL = YES;
|
|
234
|
+
};
|
|
235
|
+
name = Debug;
|
|
236
|
+
};
|
|
237
|
+
3A6FB2131D99E12200593599 /* Release */ = {
|
|
238
|
+
isa = XCBuildConfiguration;
|
|
239
|
+
buildSettings = {
|
|
240
|
+
DEVELOPMENT_TEAM = "";
|
|
241
|
+
HEADER_SEARCH_PATHS = (
|
|
242
|
+
"$(inherited)",
|
|
243
|
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
244
|
+
"$(SRCROOT)/../../react-native/React/**",
|
|
245
|
+
);
|
|
246
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
247
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
248
|
+
SKIP_INSTALL = YES;
|
|
249
|
+
};
|
|
250
|
+
name = Release;
|
|
251
|
+
};
|
|
252
|
+
/* End XCBuildConfiguration section */
|
|
253
|
+
|
|
254
|
+
/* Begin XCConfigurationList section */
|
|
255
|
+
3A6FB2031D99E12200593599 /* Build configuration list for PBXProject "TextToSpeech" */ = {
|
|
256
|
+
isa = XCConfigurationList;
|
|
257
|
+
buildConfigurations = (
|
|
258
|
+
3A6FB20F1D99E12200593599 /* Debug */,
|
|
259
|
+
3A6FB2101D99E12200593599 /* Release */,
|
|
260
|
+
);
|
|
261
|
+
defaultConfigurationIsVisible = 0;
|
|
262
|
+
defaultConfigurationName = Release;
|
|
263
|
+
};
|
|
264
|
+
3A6FB2111D99E12200593599 /* Build configuration list for PBXNativeTarget "TextToSpeech" */ = {
|
|
265
|
+
isa = XCConfigurationList;
|
|
266
|
+
buildConfigurations = (
|
|
267
|
+
3A6FB2121D99E12200593599 /* Debug */,
|
|
268
|
+
3A6FB2131D99E12200593599 /* Release */,
|
|
269
|
+
);
|
|
270
|
+
defaultConfigurationIsVisible = 0;
|
|
271
|
+
defaultConfigurationName = Release;
|
|
272
|
+
};
|
|
273
|
+
/* End XCConfigurationList section */
|
|
274
|
+
};
|
|
275
|
+
rootObject = 3A6FB2001D99E12200593599 /* Project object */;
|
|
276
|
+
}
|