speechstate 2.0.0-beta.1 → 2.0.0-beta.11

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.
@@ -12,21 +12,21 @@ const speechstate = (0, xstate_1.createMachine)({
12
12
  id: "speechstate",
13
13
  type: "parallel",
14
14
  states: {
15
- asrTtsSpawner: {
16
- initial: "idle",
15
+ AsrTtsSpawner: {
16
+ initial: "Idle",
17
17
  states: {
18
- idle: { on: { PREPARE: "createAudioContext" } },
19
- createAudioContext: {
18
+ Idle: { on: { PREPARE: "CreateAudioContext" } },
19
+ CreateAudioContext: {
20
20
  invoke: {
21
21
  id: "createAudioContext",
22
22
  src: "audioContext",
23
23
  onDone: {
24
- target: "spawn",
24
+ target: "Spawn",
25
25
  actions: (0, xstate_1.assign)({ audioContext: ({ event }) => event.output }),
26
26
  },
27
27
  },
28
28
  },
29
- spawn: {
29
+ Spawn: {
30
30
  entry: [
31
31
  (0, xstate_1.assign)({
32
32
  ttsRef: ({ context, spawn }) => {
@@ -48,6 +48,8 @@ const speechstate = (0, xstate_1.createMachine)({
48
48
  locale: context.settings.locale,
49
49
  audioContext: context.audioContext,
50
50
  azureCredentials: context.settings.azureCredentials,
51
+ azureLanguageCredentials: context.settings.azureLanguageCredentials,
52
+ speechRecognitionEndpointId: context.settings.speechRecognitionEndpointId,
51
53
  },
52
54
  });
53
55
  },
@@ -55,68 +57,68 @@ const speechstate = (0, xstate_1.createMachine)({
55
57
  ],
56
58
  after: {
57
59
  300000: {
58
- target: "spawn",
60
+ target: "Spawn",
59
61
  },
60
62
  },
61
63
  },
62
64
  },
63
65
  },
64
- asrTtsManager: {
65
- initial: "initialize",
66
+ AsrTtsManager: {
67
+ initial: "Initialize",
66
68
  on: {
67
69
  TTS_READY: {
68
70
  actions: () => console.debug("[TTS→SpSt] TTS_READY"),
69
- target: ".preReady",
71
+ target: ".PreReady",
70
72
  },
71
73
  ASR_READY: {
72
74
  actions: () => console.debug("[ASR→SpSt] ASR_READY"),
73
- target: ".preReady",
75
+ target: ".PreReady",
74
76
  },
75
77
  // ASR_ERROR not implemented
76
78
  TTS_ERROR: {
77
79
  actions: () => console.error("[TTS→SpSt] TTS_ERROR"),
78
- target: ".fail",
80
+ target: ".Fail",
79
81
  },
80
82
  ASR_NOINPUT: {
81
83
  actions: [
82
84
  () => console.debug("[ASR→SpSt] NOINPUT"),
83
85
  (0, xstate_1.sendParent)({ type: "ASR_NOINPUT" }),
84
86
  ],
85
- target: ".ready",
87
+ target: ".Ready",
86
88
  },
87
89
  },
88
90
  states: {
89
- initialize: {},
90
- preReady: {
91
+ Initialize: {},
92
+ PreReady: {
91
93
  on: {
92
94
  TTS_READY: {
93
95
  actions: () => console.debug("[TTS→SpSt] TTS_READY"),
94
- target: "ready",
96
+ target: "Ready",
95
97
  },
96
98
  ASR_READY: {
97
99
  actions: () => console.debug("[ASR→SpSt] ASR_READY"),
98
- target: "ready",
100
+ target: "Ready",
99
101
  },
100
102
  },
101
103
  },
102
- ready: {
103
- initial: "idle",
104
+ Ready: {
105
+ initial: "Idle",
104
106
  entry: [
105
107
  () => console.debug("[SpSt] All ready"),
106
108
  (0, xstate_1.sendParent)({ type: "ASRTTS_READY" }),
107
109
  ],
108
110
  states: {
109
- idle: {
111
+ Idle: {
110
112
  on: {
111
- LISTEN: { target: "waitForRecogniser" },
113
+ LISTEN: { target: "WaitForRecogniser" },
112
114
  SPEAK: [
113
115
  {
114
- target: "speaking",
116
+ target: "Speaking",
115
117
  },
116
118
  ],
117
119
  },
118
120
  },
119
- speaking: {
121
+ Speaking: {
120
122
  entry: [
121
123
  ({ event }) => console.debug("[SpSt→TTS] SPEAK", event.value),
122
124
  ({ context, event }) => context.ttsRef.send({
@@ -148,7 +150,7 @@ const speechstate = (0, xstate_1.createMachine)({
148
150
  ],
149
151
  },
150
152
  SPEAK_COMPLETE: {
151
- target: "idle",
153
+ target: "Idle",
152
154
  actions: [
153
155
  () => console.debug("[TTS→SpSt] SPEAK_COMPLETE"),
154
156
  (0, xstate_1.sendParent)({ type: "SPEAK_COMPLETE" }),
@@ -156,7 +158,7 @@ const speechstate = (0, xstate_1.createMachine)({
156
158
  },
157
159
  },
158
160
  },
159
- waitForRecogniser: {
161
+ WaitForRecogniser: {
160
162
  entry: [
161
163
  ({ event }) => console.debug("[SpSt→ASR] START", event.value),
162
164
  ({ context, event }) => context.asrRef.send({
@@ -166,7 +168,7 @@ const speechstate = (0, xstate_1.createMachine)({
166
168
  ],
167
169
  on: {
168
170
  ASR_STARTED: {
169
- target: "recognising",
171
+ target: "Recognising",
170
172
  actions: [
171
173
  () => console.debug("[ASR→SpSt] ASR_STARTED"),
172
174
  (0, xstate_1.sendParent)({ type: "ASR_STARTED" }),
@@ -174,7 +176,7 @@ const speechstate = (0, xstate_1.createMachine)({
174
176
  },
175
177
  },
176
178
  },
177
- recognising: {
179
+ Recognising: {
178
180
  on: {
179
181
  CONTROL: {
180
182
  actions: [
@@ -184,21 +186,31 @@ const speechstate = (0, xstate_1.createMachine)({
184
186
  }),
185
187
  ],
186
188
  },
189
+ STOP: {
190
+ target: "Idle",
191
+ actions: [
192
+ () => console.debug("[SpSt→ASR] STOP"),
193
+ ({ context }) => context.asrRef.send({
194
+ type: "STOP",
195
+ }),
196
+ ],
197
+ },
187
198
  RECOGNISED: {
188
199
  actions: [
189
- ({ event }) => console.debug("[ASR→SpSt] RECOGNISED", event.value),
200
+ ({ event }) => console.debug("[ASR→SpSt] RECOGNISED", event.value, event.nluValue),
190
201
  (0, xstate_1.sendParent)(({ event }) => ({
191
202
  type: "RECOGNISED",
192
203
  value: event.value,
204
+ nluValue: event.nluValue,
193
205
  })),
194
206
  ],
195
- target: "idle",
207
+ target: "Idle",
196
208
  },
197
209
  },
198
210
  },
199
211
  },
200
212
  },
201
- fail: {},
213
+ Fail: {},
202
214
  },
203
215
  },
204
216
  },
package/dist/tts.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { AzureCredentials, Agenda } from "./types";
1
+ import { AzureSpeechCredentials, Agenda } from "./types";
2
2
  interface MySpeechSynthesisUtterance extends SpeechSynthesisUtterance {
3
3
  new (s: string): any;
4
4
  }
5
5
  interface TTSInit {
6
6
  audioContext: AudioContext;
7
- azureCredentials: string | AzureCredentials;
7
+ azureCredentials: string | AzureSpeechCredentials;
8
8
  ttsDefaultVoice: string;
9
9
  }
10
10
  interface TTSContext extends TTSInit {
@@ -14,6 +14,8 @@ interface TTSContext extends TTSInit {
14
14
  wsaVoice?: SpeechSynthesisVoice;
15
15
  wsaUtt?: MySpeechSynthesisUtterance;
16
16
  agenda?: Agenda;
17
+ buffer?: string;
18
+ utteranceFromStream?: string;
17
19
  }
18
20
  type TTSEvent = {
19
21
  type: "PREPARE";
@@ -34,9 +36,79 @@ type TTSEvent = {
34
36
  value: Agenda;
35
37
  } | {
36
38
  type: "TTS_STARTED";
39
+ } | {
40
+ type: "STREAMING_CHUNK";
41
+ value: string;
42
+ } | {
43
+ type: "STREAMING_DONE";
37
44
  } | {
38
45
  type: "SPEAK_COMPLETE";
39
46
  };
40
- export declare const ttsMachine: import("xstate").StateMachine<TTSContext, TTSEvent, Record<string, import("xstate").AnyActorRef>, import("xstate").ProvidedActor, import("xstate").ParameterizedObject, import("xstate").ParameterizedObject, string, import("xstate").StateValue, string, TTSInit, {}, import("xstate").ResolveTypegenMeta<import("xstate").TypegenDisabled, TTSEvent, import("xstate").ProvidedActor, import("xstate").ParameterizedObject, import("xstate").ParameterizedObject, string, string>>;
47
+ export declare const ttsMachine: import("xstate").StateMachine<TTSContext, TTSEvent, {
48
+ [x: string]: import("xstate").ActorRef<import("xstate").CallbackSnapshot<{}>, import("xstate").EventObject> | import("xstate").ActorRef<import("xstate").PromiseSnapshot<string, any>, {
49
+ [k: string]: unknown;
50
+ type: string;
51
+ }> | import("xstate").ActorRef<import("xstate").CallbackSnapshot<Agenda>, import("xstate").EventObject>;
52
+ }, {
53
+ src: "getToken";
54
+ logic: import("xstate").PromiseActorLogic<string, any>;
55
+ id: string;
56
+ } | {
57
+ src: "createEventsFromStream";
58
+ logic: import("xstate").CallbackActorLogic<import("xstate").EventObject, Agenda>;
59
+ id: string;
60
+ } | {
61
+ src: "ponyfill";
62
+ logic: import("xstate").CallbackActorLogic<import("xstate").EventObject, {}>;
63
+ id: string;
64
+ } | {
65
+ src: "start";
66
+ logic: import("xstate").CallbackActorLogic<import("xstate").EventObject, {}>;
67
+ id: string;
68
+ }, {
69
+ type: "ttsStop";
70
+ params: unknown;
71
+ } | {
72
+ type: "addFiller";
73
+ params: {};
74
+ }, {
75
+ type: "bufferContainsUtterancePartReadyToBeSpoken";
76
+ params: unknown;
77
+ }, "FILLER_DELAY", "GetToken" | "Fail" | "Ponyfill" | {
78
+ Ready?: "Idle" | {
79
+ BufferedSpeaker?: Required<{
80
+ Buffer?: "BufferIdle" | "Buffering" | "BufferingDone";
81
+ Speaker?: "SpeakingIdle" | "PrepareSpeech" | {
82
+ Speak?: "Go" | "Paused";
83
+ };
84
+ }>;
85
+ Speaking?: "Go" | "Paused";
86
+ };
87
+ }, string, TTSInit, {}, import("xstate").ResolveTypegenMeta<import("xstate").TypegenDisabled, TTSEvent, {
88
+ src: "getToken";
89
+ logic: import("xstate").PromiseActorLogic<string, any>;
90
+ id: string;
91
+ } | {
92
+ src: "createEventsFromStream";
93
+ logic: import("xstate").CallbackActorLogic<import("xstate").EventObject, Agenda>;
94
+ id: string;
95
+ } | {
96
+ src: "ponyfill";
97
+ logic: import("xstate").CallbackActorLogic<import("xstate").EventObject, {}>;
98
+ id: string;
99
+ } | {
100
+ src: "start";
101
+ logic: import("xstate").CallbackActorLogic<import("xstate").EventObject, {}>;
102
+ id: string;
103
+ }, {
104
+ type: "ttsStop";
105
+ params: unknown;
106
+ } | {
107
+ type: "addFiller";
108
+ params: {};
109
+ }, {
110
+ type: "bufferContainsUtterancePartReadyToBeSpoken";
111
+ params: unknown;
112
+ }, "FILLER_DELAY", string>>;
41
113
  export {};
42
114
  //# sourceMappingURL=tts.d.ts.map
package/dist/tts.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEnD,UAAU,0BAA2B,SAAQ,wBAAwB;IACnE,KAAK,CAAC,EAAE,MAAM,OAAE;CACjB;AAED,UAAU,OAAO;IACf,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5C,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,UAAW,SAAQ,OAAO;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,MAAM,CAAC,EAAE,0BAA0B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,QAAQ,GACT;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE;QACL,MAAM,EAAE,eAAe,CAAC;QACxB,MAAM,EAAE,0BAA0B,CAAC;KACpC,CAAC;CACH,GACD;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE/B,eAAO,MAAM,UAAU,sdA+KtB,CAAC"}
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEzD,UAAU,0BAA2B,SAAQ,wBAAwB;IACnE,KAAK,CAAC,EAAE,MAAM,OAAE;CACjB;AAED,UAAU,OAAO;IACf,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,MAAM,GAAG,sBAAsB,CAAC;IAClD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,UAAW,SAAQ,OAAO;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,MAAM,CAAC,EAAE,0BAA0B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,KAAK,QAAQ,GACT;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE;QACL,MAAM,EAAE,eAAe,CAAC;QACxB,MAAM,EAAE,0BAA0B,CAAC;KACpC,CAAC;CACH,GACD;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAI/B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA4WrB,CAAC"}
package/dist/tts.js CHANGED
@@ -5,13 +5,96 @@ const xstate_1 = require("xstate");
5
5
  const getToken_1 = require("./getToken");
6
6
  const TextToSpeech_1 = require("web-speech-cognitive-services/lib/SpeechServices/TextToSpeech");
7
7
  const REGION = "northeurope";
8
- exports.ttsMachine = (0, xstate_1.createMachine)({
9
- id: "tts",
8
+ const UTTERANCE_CHUNK_REGEX = /(^.*([!?]+|([.,]+\s)))/;
9
+ exports.ttsMachine = (0, xstate_1.setup)({
10
10
  types: {},
11
+ actions: {
12
+ ttsStop: ({ context }) => {
13
+ context.wsaTTS.cancel();
14
+ },
15
+ addFiller: (0, xstate_1.assign)(({ context }) => {
16
+ const spaceIndex = context.buffer.lastIndexOf(" ");
17
+ return {
18
+ buffer: context.buffer.substring(0, spaceIndex) +
19
+ " um," +
20
+ context.buffer.substring(spaceIndex),
21
+ };
22
+ }),
23
+ },
24
+ actors: {
25
+ getToken: getToken_1.getToken,
26
+ createEventsFromStream: (0, xstate_1.fromCallback)(({ sendBack, input }) => {
27
+ const stream = new EventSource(input.stream);
28
+ stream.onmessage = function (event) {
29
+ console.log(JSON.parse(event.data));
30
+ sendBack(JSON.parse(event.data));
31
+ };
32
+ }),
33
+ ponyfill: (0, xstate_1.fromCallback)(({ sendBack, input }) => {
34
+ const ponyfill = (0, TextToSpeech_1.default)({
35
+ audioContext: input.audioContext,
36
+ credentials: {
37
+ region: REGION, // TODO
38
+ authorizationToken: input.azureAuthorizationToken,
39
+ },
40
+ });
41
+ const { speechSynthesis, SpeechSynthesisUtterance } = ponyfill;
42
+ const tts = speechSynthesis;
43
+ const ttsUtterance = SpeechSynthesisUtterance;
44
+ tts.addEventListener("voiceschanged", () => {
45
+ const voices = tts.getVoices();
46
+ if (voices.length > 0) {
47
+ console.debug("[TTS] READY");
48
+ sendBack({
49
+ type: "READY",
50
+ value: { wsaTTS: tts, wsaUtt: ttsUtterance },
51
+ });
52
+ }
53
+ else {
54
+ console.error("[TTS] No voices available");
55
+ sendBack({ type: "ERROR" });
56
+ }
57
+ });
58
+ }),
59
+ start: (0, xstate_1.fromCallback)(({ sendBack, input }) => {
60
+ if (["", " "].includes(input.utterance)) {
61
+ console.debug("[TTS] SPEAK: ", input.utterance);
62
+ input.wsaTTS.speak("");
63
+ }
64
+ else {
65
+ console.debug("[TTS] SPEAK: ", input.utterance);
66
+ const content = wrapSSML(input.utterance, input.voice, input.ttsLexicon, 1); // todo speech rate;
67
+ const utterance = new input.wsaUtt(content);
68
+ utterance.addEventListener("start", () => {
69
+ sendBack({ type: "TTS_STARTED" });
70
+ console.debug("[TTS] TTS_STARTED");
71
+ });
72
+ utterance.addEventListener("end", () => {
73
+ sendBack({ type: "SPEAK_COMPLETE" });
74
+ console.debug("[TTS] SPEAK_COMPLETE");
75
+ });
76
+ input.wsaTTS.speak(utterance);
77
+ }
78
+ }),
79
+ },
80
+ guards: {
81
+ bufferContainsUtterancePartReadyToBeSpoken: ({ context }) => {
82
+ const m = context.buffer.match(UTTERANCE_CHUNK_REGEX);
83
+ return !!m;
84
+ },
85
+ },
86
+ delays: {
87
+ FILLER_DELAY: ({ context }) => {
88
+ return context.agenda.fillerDelay;
89
+ },
90
+ },
91
+ }).createMachine({
92
+ id: "tts",
11
93
  context: ({ input }) => ({
12
94
  ttsDefaultVoice: input.ttsDefaultVoice || "en-US-DavisNeural",
13
95
  audioContext: input.audioContext,
14
96
  azureCredentials: input.azureCredentials,
97
+ buffer: "",
15
98
  }),
16
99
  initial: "GetToken",
17
100
  on: {
@@ -33,9 +116,164 @@ exports.ttsMachine = (0, xstate_1.createMachine)({
33
116
  states: {
34
117
  Idle: {
35
118
  on: {
36
- SPEAK: {
37
- target: "Speaking",
38
- actions: (0, xstate_1.assign)({ agenda: ({ event }) => event.value }),
119
+ SPEAK: [
120
+ {
121
+ target: "BufferedSpeaker",
122
+ guard: ({ event }) => !!event.value.stream,
123
+ actions: (0, xstate_1.assign)({
124
+ agenda: ({ event }) => event.value.fillerDelay
125
+ ? event.value
126
+ : Object.assign(Object.assign({}, event.value), { fillerDelay: 500 }),
127
+ }),
128
+ },
129
+ {
130
+ target: "Speaking",
131
+ actions: (0, xstate_1.assign)({ agenda: ({ event }) => event.value }),
132
+ },
133
+ ],
134
+ },
135
+ },
136
+ BufferedSpeaker: {
137
+ type: "parallel",
138
+ invoke: {
139
+ id: "createEventsFromStream",
140
+ src: "createEventsFromStream",
141
+ input: ({ context }) => context.agenda,
142
+ },
143
+ on: {
144
+ STOP: {
145
+ target: "Idle",
146
+ },
147
+ SPEAK_COMPLETE: [
148
+ {
149
+ guard: (0, xstate_1.stateIn)("#BufferingDone"),
150
+ target: "Idle",
151
+ actions: (0, xstate_1.sendParent)({ type: "SPEAK_COMPLETE" }),
152
+ },
153
+ ],
154
+ },
155
+ states: {
156
+ Buffer: {
157
+ initial: "BufferIdle",
158
+ states: {
159
+ BufferIdle: {
160
+ id: "BufferIdle",
161
+ on: {
162
+ STREAMING_CHUNK: {
163
+ target: "Buffering",
164
+ },
165
+ },
166
+ },
167
+ Buffering: {
168
+ id: "Buffering",
169
+ on: {
170
+ STREAMING_CHUNK: [
171
+ {
172
+ target: "Buffering",
173
+ reenter: true,
174
+ },
175
+ ],
176
+ STREAMING_DONE: [
177
+ {
178
+ target: "BufferingDone",
179
+ },
180
+ ],
181
+ },
182
+ entry: [
183
+ (0, xstate_1.assign)({
184
+ buffer: ({ context, event }) => context.buffer + event.value,
185
+ }),
186
+ ],
187
+ },
188
+ BufferingDone: {
189
+ id: "BufferingDone",
190
+ },
191
+ },
192
+ },
193
+ Speaker: {
194
+ initial: "SpeakingIdle",
195
+ states: {
196
+ SpeakingIdle: {
197
+ always: [
198
+ {
199
+ target: "Speak",
200
+ guard: (0, xstate_1.stateIn)("#BufferingDone"),
201
+ actions: (0, xstate_1.assign)({
202
+ utteranceFromStream: ({ context }) => context.buffer,
203
+ }),
204
+ },
205
+ {
206
+ target: "PrepareSpeech",
207
+ guard: "bufferContainsUtterancePartReadyToBeSpoken",
208
+ },
209
+ ],
210
+ after: {
211
+ FILLER_DELAY: {
212
+ target: "SpeakingIdle",
213
+ reenter: true,
214
+ actions: "addFiller",
215
+ guard: ({ context }) => context.buffer.includes(" "),
216
+ },
217
+ },
218
+ },
219
+ PrepareSpeech: {
220
+ entry: [
221
+ (0, xstate_1.assign)(({ context }) => {
222
+ let utterancePart;
223
+ let restOfBuffer;
224
+ const match = context.buffer.match(UTTERANCE_CHUNK_REGEX);
225
+ utterancePart = match[0];
226
+ restOfBuffer = context.buffer.substring(utterancePart.length);
227
+ return {
228
+ buffer: restOfBuffer,
229
+ utteranceFromStream: utterancePart,
230
+ };
231
+ }),
232
+ ],
233
+ always: [
234
+ {
235
+ target: "Speak",
236
+ },
237
+ ],
238
+ },
239
+ Speak: {
240
+ initial: "Go",
241
+ on: {
242
+ TTS_STARTED: {
243
+ actions: (0, xstate_1.sendParent)({ type: "TTS_STARTED" }),
244
+ },
245
+ SPEAK_COMPLETE: [
246
+ {
247
+ guard: (0, xstate_1.stateIn)("#Buffering"),
248
+ target: "SpeakingIdle",
249
+ },
250
+ ],
251
+ },
252
+ states: {
253
+ Go: {
254
+ invoke: {
255
+ src: "start",
256
+ input: ({ context }) => ({
257
+ wsaTTS: context.wsaTTS,
258
+ wsaUtt: context.wsaUtt,
259
+ ttsLexicon: context.ttsLexicon,
260
+ voice: context.agenda.voice || context.ttsDefaultVoice,
261
+ utterance: context.utteranceFromStream,
262
+ }),
263
+ },
264
+ on: {
265
+ CONTROL: "Paused",
266
+ },
267
+ exit: "ttsStop",
268
+ },
269
+ Paused: {
270
+ on: {
271
+ CONTROL: "Go",
272
+ },
273
+ },
274
+ },
275
+ },
276
+ },
39
277
  },
40
278
  },
41
279
  },
@@ -113,61 +351,6 @@ exports.ttsMachine = (0, xstate_1.createMachine)({
113
351
  },
114
352
  },
115
353
  },
116
- }, {
117
- actions: {
118
- ttsStop: ({ context }) => {
119
- context.wsaTTS.cancel();
120
- },
121
- },
122
- actors: {
123
- getToken: getToken_1.getToken,
124
- ponyfill: (0, xstate_1.fromCallback)(({ sendBack, input }) => {
125
- const ponyfill = (0, TextToSpeech_1.default)({
126
- audioContext: input.audioContext,
127
- credentials: {
128
- region: REGION,
129
- authorizationToken: input.azureAuthorizationToken,
130
- },
131
- });
132
- const { speechSynthesis, SpeechSynthesisUtterance } = ponyfill;
133
- const tts = speechSynthesis;
134
- const ttsUtterance = SpeechSynthesisUtterance;
135
- tts.addEventListener("voiceschanged", () => {
136
- const voices = tts.getVoices();
137
- if (voices.length > 0) {
138
- console.debug("[TTS] READY");
139
- sendBack({
140
- type: "READY",
141
- value: { wsaTTS: tts, wsaUtt: ttsUtterance },
142
- });
143
- }
144
- else {
145
- console.error("[TTS] No voices available");
146
- sendBack({ type: "ERROR" });
147
- }
148
- });
149
- }),
150
- start: (0, xstate_1.fromCallback)(({ sendBack, input }) => {
151
- if (["", " "].includes(input.utterance)) {
152
- console.debug("[TTS] SPEAK: ", input.utterance);
153
- input.wsaTTS.speak("");
154
- }
155
- else {
156
- console.debug("[TTS] SPEAK: ", input.utterance);
157
- const content = wrapSSML(input.utterance, input.voice, input.ttsLexicon, 1); // todo speech rate;
158
- const utterance = new input.wsaUtt(content);
159
- utterance.addEventListener("start", () => {
160
- sendBack({ type: "TTS_STARTED" });
161
- console.debug("[TTS] TTS_STARTED");
162
- });
163
- utterance.addEventListener("end", () => {
164
- sendBack({ type: "SPEAK_COMPLETE" });
165
- console.debug("[TTS] SPEAK_COMPLETE");
166
- });
167
- input.wsaTTS.speak(utterance);
168
- }
169
- }),
170
- },
171
354
  });
172
355
  const wrapSSML = (text, voice, lexicon, speechRate) => {
173
356
  let content = `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xml:lang="en-US"><voice name="${voice}">`;
package/dist/types.d.ts CHANGED
@@ -1,18 +1,32 @@
1
- export interface AzureCredentials {
1
+ export interface AzureSpeechCredentials {
2
2
  endpoint: string;
3
3
  key: string;
4
4
  }
5
+ /**
6
+ * @deprecated use `AzureSpeechCredentials` instead
7
+ */
8
+ export interface AzureCredentials extends AzureSpeechCredentials {
9
+ }
10
+ export interface AzureLanguageCredentials {
11
+ endpoint: string;
12
+ key: string;
13
+ projectName: string;
14
+ deploymentName: string;
15
+ }
5
16
  export interface Settings {
6
- locale: string;
7
- azureCredentials: string | AzureCredentials;
8
- asrDefaultCompleteTimeout: number;
9
- asrDefaultNoInputTimeout: number;
10
- ttsDefaultVoice: string;
17
+ locale?: string;
18
+ azureCredentials: string | AzureCredentials | AzureSpeechCredentials;
19
+ azureLanguageCredentials?: AzureLanguageCredentials;
20
+ asrDefaultCompleteTimeout?: number;
21
+ asrDefaultNoInputTimeout?: number;
22
+ ttsDefaultVoice?: string;
23
+ speechRecognitionEndpointId?: string;
11
24
  }
12
25
  export interface Agenda {
13
26
  utterance: string;
14
27
  voice?: string;
15
- stream?: ReadableStream<string>;
28
+ stream?: string;
29
+ fillerDelay?: number;
16
30
  }
17
31
  export interface Hypothesis {
18
32
  utterance: string;
@@ -23,5 +37,6 @@ export interface RecogniseParameters {
23
37
  completeTimeout?: number;
24
38
  locale?: string;
25
39
  hints?: string[];
40
+ nlu?: boolean | AzureLanguageCredentials;
26
41
  }
27
42
  //# sourceMappingURL=types.d.ts.map