205
if (this.ttsStream.chunks.length == 0) return;
206
207
// if stream was already running, just updating chunks is enough
208
+ // The running loop will pick up the new chunks automatically
209
if (this.ttsStream.running) return;
210
else this.ttsStream.running = true; // proceed to running phase
211
215
216
const spoken = [];
217
217
- // loop chunks from last spoken chunk index
218
- for (
219
- let i = this.ttsStream.lastChunkIndex + 1;
220
- i < this.ttsStream.chunks.length;
221
- i++
222
- ) {
218
+ // continuously loop until all chunks are spoken and stream is finished
219
+ while (true) {
220
+ // check if we should stop
221
+ if (terminator()) break;
222
+
223
+ // get the next chunk index to speak
224
+ const nextIndex = this.ttsStream.lastChunkIndex + 1;
225
+
226
+ // if no more chunks available, check if we should wait or exit
227
+ if (nextIndex >= this.ttsStream.chunks.length) {
228
+ // if stream is finished, we're done
229
+ if (this.ttsStream.finished) break;
230
+ // otherwise wait a bit for more chunks to arrive
231
+ await new Promise((resolve) => setTimeout(resolve, 50));
232
+ continue;
233
+ }
234
+
235
// do not speak the last chunk until finished (it is being generated)
224
- if (i == this.ttsStream.chunks.length - 1 && !this.ttsStream.finished)
225
- break;
236
+ if (
237
+ nextIndex == this.ttsStream.chunks.length - 1 &&
238
+ !this.ttsStream.finished
239
+ ) {
240
+ // wait a bit for more content or finish signal
241
+ await new Promise((resolve) => setTimeout(resolve, 50));
242
+ continue;
243
+ }
244
245
// set the index of last spoken chunk
228
- this.ttsStream.lastChunkIndex = i;
246
+ this.ttsStream.lastChunkIndex = nextIndex;
247
248
// speak the chunk
231
- spoken.push(this.ttsStream.chunks[i]);
232
- await this._speak(this.ttsStream.chunks[i], i > 0, () => terminator());
249
+ const chunk = this.ttsStream.chunks[nextIndex];
250
+ spoken.push(chunk);
251
+ await this._speak(chunk, nextIndex > 0, () => terminator());
252
}
253
254
// at the end, finish stream data
405
while (waitForPrevious && this.isSpeaking) await sleep(25);
406
if (terminator && terminator()) return;
407
389
- // stop previous if any
390
- this.stopAudio();
408
+ // stop previous only if not waiting for it
409
+ if (!waitForPrevious) this.stopAudio();
410
411
this.browserUtterance = new SpeechSynthesisUtterance(text);
412
this.browserUtterance.onstart = () => {
429
while (waitForPrevious && this.isSpeaking) await sleep(25);
430
if (terminator && terminator()) return;
431
413
- // stop previous if any
414
- this.stopAudio();
432
+ // stop previous only if not waiting for it
433
+ if (!waitForPrevious) this.stopAudio();
434
435
if (response.success) {
436
if (response.audio_parts) {