zenity script for stdout of piper text to speech

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
Coffeeee
Level 2
Level 2
Posts: 98
Joined: Sun Mar 13, 2022 8:30 am
Location: virgo supercluster, milky way galaxy, solar system, earth

zenity script for stdout of piper text to speech

Post by Coffeeee »

I was looking for a good tts and found piper tts.
You can hear voice samples here
https://rhasspy.github.io/piper-samples/

Easiest to use the binary
https://github.com/rhasspy/piper#installation

Needs jq installed
sudo apt install jq

put this script in the same directory as the binary

Code: Select all

#!/bin/bash

cd "$(dirname "$0")"

while true; do

TEXT_IN=$( zenity --entry --title="piper_tts" --text="enter/paste text to read" --cancel-label=exit --ok-label=read --extra-button "read clipboard" --extra-button pause --extra-button resume --extra-button kill)

if [ $? = 0 ] # check if the user click ok on the zenity form
then
	echo "$TEXT_IN" | ./piper --model en_GB-vctk-medium.onnx --length_scale 1.9 --noise_scale 0.333 --noise_w 0.33 --output-raw | aplay -r 20000 -f S16_LE -t raw - &
  elif [[ $TEXT_IN = "read clipboard" ]]
   then
		echo $(xclip -o) | ./piper --model en_GB-vctk-medium.onnx --length_scale 1.9 --noise_scale 0.333 --noise_w 0.33 --output-raw | aplay -r 20000 -f S16_LE -t raw - &
  elif [[ $TEXT_IN = "pause" ]]
   then
        pid=$(pidof piper); kill -STOP $pid;
  elif [[ $TEXT_IN = "resume" ]]
   then
        pid=$(pidof piper); kill -CONT $pid;
  elif [[ $TEXT_IN = "kill" ]]
   then
        killall piper;
else
    exit
fi

done

#    x_low - 16Khz audio, 5-7M params
#    low - 16Khz audio, 15-20M params
#    medium - 22.05Khz audio, 15-20 params
#    high - 22.05Khz audio, 28-32M params
if you understand how to use wmctrl then use below (keep window on top, set position)

Code: Select all

#!/bin/bash

cd "$(dirname "$0")"

while true; do

sleep 0.4 &&
wmctrl -F -a "piper_tts" -b add,above &&
wmctrl -r "piper_tts" -e 0,2300,90,100,100 &
TEXT_IN=$( zenity --entry --title="piper_tts" --text="enter/paste text to read" --cancel-label=exit --ok-label=read --extra-button "read clipboard" --extra-button pause --extra-button resume --extra-button kill)

if [ $? = 0 ] # check if the user click ok on the zenity form
then
	echo "$TEXT_IN" | ./piper --model en_GB-vctk-medium.onnx --length_scale 1.9 --noise_scale 0.333 --noise_w 0.33 --output-raw | aplay -r 20000 -f S16_LE -t raw - &
  elif [[ $TEXT_IN = "read clipboard" ]]
   then
#		xclip -o > ~/piper.txt
#		sed -i 's/~/-/g' ~/piper.txt
#		cat ~/piper.txt | xclip;
		echo $(xclip -o) | ./piper --model en_GB-vctk-medium.onnx --length_scale 1.9 --noise_scale 0.333 --noise_w 0.33 --output-raw | aplay -r 20000 -f S16_LE -t raw - &
  elif [[ $TEXT_IN = "pause" ]]
   then
        pid=$(pidof piper); kill -STOP $pid;
  elif [[ $TEXT_IN = "resume" ]]
   then
        pid=$(pidof piper); kill -CONT $pid;
  elif [[ $TEXT_IN = "kill" ]]
   then
        killall piper;
else
    exit
fi

done

#    x_low - 16Khz audio, 5-7M params
#    low - 16Khz audio, 15-20M params
#    medium - 22.05Khz audio, 15-20 params
#    high - 22.05Khz audio, 28-32M params
I did try the Speech Note flatpak but it writes all output to wav files wearing the disk. Flatpaks also don't work with dark themes.
Last edited by LockBot on Thu Apr 25, 2024 10:00 pm, edited 3 times in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
Coffeeee
Level 2
Level 2
Posts: 98
Joined: Sun Mar 13, 2022 8:30 am
Location: virgo supercluster, milky way galaxy, solar system, earth

Re: zenity script for stdout of piper text to speech

Post by Coffeeee »

I just found out how to alter the speed

echo "$TEXT_IN" | ./piper --model en_GB-vctk-medium.onnx --length_scale 1.9 --noise_scale 0.333 --noise_w 0.33 --output-raw | aplay -r 22050 -f S16_LE -t raw -

you can get this information inside the json file matching the voice (onnx)

# --noise_scale NUM generator noise (default: 0.667)
# --length_scale NUM phoneme length (default: 1.0), this controls speed.
# --noise_w NUM phoneme width noise (default: 0.8)
# --sentence_silence NUM seconds of silence after each sentence (default: 0.2)
Coffeeee
Level 2
Level 2
Posts: 98
Joined: Sun Mar 13, 2022 8:30 am
Location: virgo supercluster, milky way galaxy, solar system, earth

Re: zenity script for stdout of piper text to speech

Post by Coffeeee »

accidental post, updated anyway.

Code: Select all

#!/bin/bash

cd "$(dirname "$0")"

## piper json settings
model=en_US-libritts_r-medium.onnx						### MUST BE SET BY USER ###
config=$model.json
length_scale=$(grep length_scale $config | cut -d , -f1 | awk '{print $2}')
frequency=$(grep sample_rate $config | cut -d , -f1 | awk '{print $2}')

## override piper json settings
#length_scale=1.35	# adjusts reading speed. start between 1-2		### ADJUST FOR COMFORT ###
#frequency=20000	# adjusts audio frequency					### ADJUST FOR COMFORT ###
					# x_low & low quality model uses 16Khz audio
					# medium & high quality 22.05Khz
					# adjust for comfort e.g. 22050 at 20000 lowers pitch and speed.

## window position
vertical=90									### MUST BE SET BY USER ###
horizontal=2300								### MUST BE SET BY USER ###

while true; do

sleep 0.5 &&
wmctrl -F -a "piper_tts" -b add,above &&
wmctrl -r "piper_tts" -e 0,$horizontal,$vertical,100,100 &
TEXT_IN=$( zenity --entry --title="piper_tts" --text="enter/paste text to read" --cancel-label="read clipboard" --ok-label=read --extra-button pause --extra-button kill --extra-button clip2wav --extra-button exit)

if [ $? = 0 ] # check if the user click ok on the zenity form
then
	echo "$TEXT_IN" | ./piper --model $model --config $config --length_scale $length_scale --output-raw | aplay -r $frequency -f S16_LE -t raw - &

	elif [[ $TEXT_IN = "pause" ]]
	 then
	  pid=$(pidof piper); kill -STOP $pid;
	  sleep 0.5 &&
	  wmctrl -F -a "piper_tts_resume" -b add,above &&
	  wmctrl -r "piper_tts_resume" -e 0,$horizontal,$vertical,100,100 &
	  zenity --question --title="piper_tts_resume" --text="Piper is paused.\nResume piper?" --cancel-label=kill --ok-label=resume

		if [ $? = 0 ] # check if the user click ok on the zenity form
		 then
		  pid=$(pidof piper); kill -CONT $pid
		 else
		  killall piper;
		fi

  	elif [[ $TEXT_IN = "kill" ]]
  	 then
	  killall piper;
	  
	elif [[ $TEXT_IN = "clip2wav" ]]
  	 then
  	 	fix_clip=$(xclip -o -sel clip | sed -e 's/-chan/-chun/g' -e 's/ LV/ level /ig' -e 's/LV/ level /g' -e 's/-senpai/-senpie/g' -e 's/pyon/p-yon/ig' -e 's/-kun/-/g' -e 's/~/-/g')
		fname=$(zenity --file-selection --save --title="Save wav" --confirm-overwrite --filename="*.wav")
			echo "$fix_clip" | ./piper --model $model --config $config  --length_scale $length_scale  --output_file "$fname"
	elif [[ $TEXT_IN = "exit" ]]
	 then
	  exit
		else
		xclip -o -sel clip | sed -e 's/-chan/-chun/g' \
		-e 's/ LV/ level /ig' \
		-e 's/LV/ level /g' \
		-e 's/-senpai/-senpie/g' \
		-e 's/pyon/p-yon/ig' \
		-e 's/-kun/-/g' \
		-e 's/~/-/g' | ./piper --model $model --config $config  --length_scale $length_scale --output-raw | aplay -r $frequency -f S16_LE -t raw - &
fi

done
Locked

Return to “Scripts & Bash”