Skip to content

Instantly share code, notes, and snippets.

@guest271314
Created July 14, 2024 19:48
Show Gist options
  • Save guest271314/9f09ab899df11e344c568a7b93f544c3 to your computer and use it in GitHub Desktop.
Save guest271314/9f09ab899df11e344c568a7b93f544c3 to your computer and use it in GitHub Desktop.
Adding piper module and voices to Speech Dispatcher for Web Speech API

An option for using piper and onnx voices in the browser is through Speech Dispatcher, which Chromium-based browsers (Chrome, Brave, Opera, Edge) and Firefox use for Web Speech API.

I have added the piper module to Speech Dispatcher following the instructions here module request: piper #866.

Tested on Chromium Version 128.0.6586.0 (Developer Build) (64-bit) and Firefox Nightly 130.0a1. Chromium works. Firefox does not load the piper voices.

In pertinent part.

Download the piper executable from releases, extract the contents and save to ~/.local/opt/piper.

Download a couple .onnx files and save to ~/.local/share/piper/voices.

Create a symbolic link to piper executable in ~/.local/bin, ln -s ~/.local/opt/piper/piper piper.

Install python3-speechd

sudo apt install python3-speechd
spd-conf -u

Modify ~/.config/speech-dispatcher/speechd.conf to add the piper module

 AddModule "piper"                     "sd_generic"   "piper.conf"

or set piper as the default module

 DefaultModule espeak-ng
 # piper

Create ~/.config/speech-dispatcher/modules/piper.conf

Debug 0

GenericExecuteSynth "printf %s \'$DATA\' | /home/xubuntu/.local/bin/piper --length_scale 1 --sentence_silence 0  --model ~/.local/share/piper/voices/$VOICE --output-raw | aplay -r 22050 -f S16_LE -t raw -"

# only use medium quality voices to respect the 22050 rate for aplay in the command above.

GenericCmdDependency "piper"
GenericCmdDependency "aplay"
GenericCmdDependency "printf"
GenericSoundIconFolder "/usr/share/sounds/sound-icons/"

GenericPunctNone ""
GenericPunctSome "--punct=\"()<>[]{}\""
GenericPunctMost "--punct=\"()[]{};:\""
GenericPunctAll "--punct"

#GenericStripPunctChars  ""

GenericLanguage  "en" "en_US" "utf-8"

AddVoice        "en"    "MALE1"         "en_US-hfc_male-medium.onnx"
AddVoice        "en"    "FEMALE1"       "en_US-hfc_female-medium.onnx"

DefaultVoice    "en_US-hfc_male-medium.onnx"

#GenericRateForceInteger 1
#GenericRateAdd 1
#GenericRateMultiply 100

Restart speech-dispatcher with speech-dispatcher restart.

Terminate and restart chrome, killall -9 chrome.

Open DevTools, test in console

var voices = speechSynthesis.getVoices().filter(({name}) => name.includes("piper"));
var u = new SpeechSynthesisUtterance();
u.voice = voices[0];
u.text = "Test, test, test. Test to the point it breaks.";
speechSynthesis.speak(u);

console.log(JSON.stringify(voices.map(({default:_default, lang, localService, name, voiceURI}) => ({_default, lang, localService, name, voiceURI})), null, 2));

VM924:6 [
  {
    "_default": false,
    "lang": "en",
    "localService": true,
    "name": "en_US-hfc_female-medium.onnx piper",
    "voiceURI": "en_US-hfc_female-medium.onnx piper"
  },
  {
    "_default": false,
    "lang": "en",
    "localService": true,
    "name": "en_US-hfc_male-medium.onnx piper",
    "voiceURI": "en_US-hfc_male-medium.onnx piper"
  }
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment