jevstrudel.git / packages / core / speak.mjs
1/*
2speak.mjs - <short description TODO>
3Copyright (C) 2022 Strudel contributors - see <https://codeberg.org/uzu/strudel/src/branch/main/packages/core/speak.mjs>
4This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program.  If not, see <https://www.gnu.org/licenses/>.
5*/
6
7import { register } from './index.mjs';
8
9let synth;
10try {
11  synth = window?.speechSynthesis;
12} catch (err) {
13  console.warn('cannot use window: not in browser?');
14}
15
16let allVoices = synth?.getVoices();
17// console.log('voices', allVoices);
18
19function triggerSpeech(words, lang, voice) {
20  synth.cancel();
21  const utterance = new SpeechSynthesisUtterance(words);
22  utterance.lang = lang;
23  allVoices = synth.getVoices();
24  const voices = allVoices.filter((v) => v.lang.includes(lang));
25  if (typeof voice === 'number') {
26    utterance.voice = voices[voice % voices.length];
27  } else if (typeof voice === 'string') {
28    utterance.voice = voices.find((voice) => voice.name === voice);
29  }
30  // console.log(utterance.voice?.name, utterance.voice?.lang);
31  speechSynthesis.speak(utterance);
32}
33
34export const speak = register('speak', function (lang, voice, pat) {
35  return pat.onTrigger((hap) => {
36    triggerSpeech(hap.value, lang, voice);
37  });
38});