1
>
/*---------------------------------------------------------------------------------------------
speechService.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { localize } from '../../../../nls.js';
7
>
import { CancellationToken } from '../../../../base/common/cancellation.js';
8
>
import { Event } from '../../../../base/common/event.js';
9
>
import { IDisposable } from '../../../../base/common/lifecycle.js';
10
>
import { RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
11
>
import { ExtensionIdentifier } from '../../../../platform/extensions/common/extensions.js';
12
>
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
13
>
import { language } from '../../../../base/common/platform.js';
14
>
15
>
export const ISpeechService = createDecorator<ISpeechService>('speechService');
16
>
17
>
export const HasSpeechProvider = new RawContextKey<boolean>('hasSpeechProvider', false, { type: 'boolean', description: localize('hasSpeechProvider', "A speech provider is registered to the speech service.") });
18
>
export const SpeechToTextInProgress = new RawContextKey<boolean>('speechToTextInProgress', false, { type: 'boolean', description: localize('speechToTextInProgress', "A speech-to-text session is in progress.") });
19
>
export const TextToSpeechInProgress = new RawContextKey<boolean>('textToSpeechInProgress', false, { type: 'boolean', description: localize('textToSpeechInProgress', "A text-to-speech session is in progress.") });
20
>
21
>
export interface ISpeechProviderMetadata {
22
>
readonly extension: ExtensionIdentifier;
23
>
readonly displayName: string;
24
>
}
25
>
26
>
export enum SpeechToTextStatus {
27
>
Started = 1,
28
>
Recognizing = 2,
29
>
Recognized = 3,
30
>
Stopped = 4,
31
>
Error = 5
32
>
}
33
>
34
>
export interface ISpeechToTextEvent {
35
>
readonly status: SpeechToTextStatus;
36
>
readonly text?: string;
37
>
}
38
>
39
>
export interface ISpeechToTextSession {
40
>
readonly onDidChange: Event<ISpeechToTextEvent>;
41
>
}
42
>
43
>
export enum TextToSpeechStatus {
44
>
Started = 1,
45
>
Stopped = 2,
46
>
Error = 3
47
>
}
48
>
49
>
export interface ITextToSpeechEvent {
50
>
readonly status: TextToSpeechStatus;
51
>
readonly text?: string;
52
>
}
53
>
54
>
export interface ITextToSpeechSession {
55
>
readonly onDidChange: Event<ITextToSpeechEvent>;
56
>
57
>
synthesize(text: string): Promise<void>;
58
>
}
59
>
60
>
export enum KeywordRecognitionStatus {
61
>
Recognized = 1,
62
>
Stopped = 2,
63
>
Canceled = 3
64
>
}
65
>
66
>
export interface IKeywordRecognitionEvent {
67
>
readonly status: KeywordRecognitionStatus;
68
>
readonly text?: string;
69
>
}
70
>
71
>
export interface IKeywordRecognitionSession {
72
>
readonly onDidChange: Event<IKeywordRecognitionEvent>;
73
>
}
74
>
75
>
export interface ISpeechToTextSessionOptions {
76
>
readonly language?: string;
77
>
}
78
>
79
>
export interface ITextToSpeechSessionOptions {
80
>
readonly language?: string;
81
>
}
82
>
83
>
export interface ISpeechProvider {
84
>
readonly metadata: ISpeechProviderMetadata;
85
>
86
>
createSpeechToTextSession(token: CancellationToken, options?: ISpeechToTextSessionOptions): ISpeechToTextSession;
87
>
createTextToSpeechSession(token: CancellationToken, options?: ITextToSpeechSessionOptions): ITextToSpeechSession;
88
>
createKeywordRecognitionSession(token: CancellationToken): IKeywordRecognitionSession;
89
>
}
90
>
91
>
export interface ISpeechService {
92
>
93
>
readonly _serviceBrand: undefined;
94
>
95
>
readonly onDidChangeHasSpeechProvider: Event<void>;
96
>
97
>
readonly hasSpeechProvider: boolean;
98
>
99
>
registerSpeechProvider(identifier: string, provider: ISpeechProvider): IDisposable;
100
>
101
>
readonly onDidStartSpeechToTextSession: Event<void>;
102
>
readonly onDidEndSpeechToTextSession: Event<void>;
103
>
104
>
readonly hasActiveSpeechToTextSession: boolean;
105
>
106
>
/**
107
>
* Starts to transcribe speech from the default microphone. The returned
108
>
* session object provides an event to subscribe for transcribed text.
109
>
*/
110
>
createSpeechToTextSession(token: CancellationToken, context?: string): Promise<ISpeechToTextSession>;
111
>
112
>
readonly onDidStartTextToSpeechSession: Event<void>;
113
>
readonly onDidEndTextToSpeechSession: Event<void>;
114
>
115
>
readonly hasActiveTextToSpeechSession: boolean;
116
>
117
>
/**
118
>
* Creates a synthesizer to synthesize speech from text. The returned
119
>
* session object provides a method to synthesize text and listen for
120
>
* events.
121
>
*/
122
>
createTextToSpeechSession(token: CancellationToken, context?: string): Promise<ITextToSpeechSession>;
123
>
124
>
readonly onDidStartKeywordRecognition: Event<void>;
125
>
readonly onDidEndKeywordRecognition: Event<void>;
126
>
127
>
readonly hasActiveKeywordRecognition: boolean;
128
>
129
>
/**
130
>
* Starts to recognize a keyword from the default microphone. The returned
131
>
* status indicates if the keyword was recognized or if the session was
132
>
* stopped.
133
>
*/
134
>
recognizeKeyword(token: CancellationToken): Promise<KeywordRecognitionStatus>;
135
>
}
136
>
137
>
export const enum AccessibilityVoiceSettingId {
138
>
SpeechTimeout = 'accessibility.voice.speechTimeout',
139
>
AutoSynthesize = 'accessibility.voice.autoSynthesize',
140
>
SpeechLanguage = 'accessibility.voice.speechLanguage',
141
>
IgnoreCodeBlocks = 'accessibility.voice.ignoreCodeBlocks'
142
>
}
143
>
144
>
export const SPEECH_LANGUAGE_CONFIG = AccessibilityVoiceSettingId.SpeechLanguage;
145
>
146
>
export const SPEECH_LANGUAGES = {
147
>
['da-DK']: {
148
>
name: localize('speechLanguage.da-DK', "Danish (Denmark)")
149
>
},
150
>
['de-DE']: {
151
>
name: localize('speechLanguage.de-DE', "German (Germany)")
152
>
},
153
>
['en-AU']: {
154
>
name: localize('speechLanguage.en-AU', "English (Australia)")
155
>
},
156
>
['en-CA']: {
157
>
name: localize('speechLanguage.en-CA', "English (Canada)")
158
>
},
159
>
['en-GB']: {
160
>
name: localize('speechLanguage.en-GB', "English (United Kingdom)")
161
>
},
162
>
['en-IE']: {
163
>
name: localize('speechLanguage.en-IE', "English (Ireland)")
164
>
},
165
>
['en-IN']: {
166
>
name: localize('speechLanguage.en-IN', "English (India)")
167
>
},
168
>
['en-NZ']: {
169
>
name: localize('speechLanguage.en-NZ', "English (New Zealand)")
170
>
},
171
>
['en-US']: {
172
>
name: localize('speechLanguage.en-US', "English (United States)")
173
>
},
174
>
['es-ES']: {
175
>
name: localize('speechLanguage.es-ES', "Spanish (Spain)")
176
>
},
177
>
['es-MX']: {
178
>
name: localize('speechLanguage.es-MX', "Spanish (Mexico)")
179
>
},
180
>
['fr-CA']: {
181
>
name: localize('speechLanguage.fr-CA', "French (Canada)")
182
>
},
183
>
['fr-FR']: {
184
>
name: localize('speechLanguage.fr-FR', "French (France)")
185
>
},
186
>
['hi-IN']: {
187
>
name: localize('speechLanguage.hi-IN', "Hindi (India)")
188
>
},
189
>
['it-IT']: {
190
>
name: localize('speechLanguage.it-IT', "Italian (Italy)")
191
>
},
192
>
['ja-JP']: {
193
>
name: localize('speechLanguage.ja-JP', "Japanese (Japan)")
194
>
},
195
>
['ko-KR']: {
196
>
name: localize('speechLanguage.ko-KR', "Korean (South Korea)")
197
>
},
198
>
['nl-NL']: {
199
>
name: localize('speechLanguage.nl-NL', "Dutch (Netherlands)")
200
>
},
201
>
['pt-PT']: {
202
>
name: localize('speechLanguage.pt-PT', "Portuguese (Portugal)")
203
>
},
204
>
['pt-BR']: {
205
>
name: localize('speechLanguage.pt-BR', "Portuguese (Brazil)")
206
>
},
207
>
['ru-RU']: {
208
>
name: localize('speechLanguage.ru-RU', "Russian (Russia)")
209
>
},
210
>
['sv-SE']: {
211
>
name: localize('speechLanguage.sv-SE', "Swedish (Sweden)")
212
>
},
213
>
['tr-TR']: {
214
>
// allow-any-unicode-next-line
215
>
name: localize('speechLanguage.tr-TR', "Turkish (Türkiye)")
216
>
},
217
>
['zh-CN']: {
218
>
name: localize('speechLanguage.zh-CN', "Chinese (Simplified, China)")
219
>
},
220
>
['zh-HK']: {
221
>
name: localize('speechLanguage.zh-HK', "Chinese (Traditional, Hong Kong)")
222
>
},
223
>
['zh-TW']: {
224
>
name: localize('speechLanguage.zh-TW', "Chinese (Traditional, Taiwan)")
225
>
}
226
>
};
227
>
228
>
export function speechLanguageConfigToLanguage(config: unknown, lang = language): string {
229
if (typeof config === 'string') {
230
if (config === 'auto') {