Hlasový výstup – čtení textového souboru
Zdroje: http://forum.ubuntu.cz/index.php?topic=29092.0
Příprava
apt-get install xclip festival festival-czech festvox-czech-ph libicu-dev
libnotify-bin
http://mirrors.kernel.org/ubuntu/pool/universe/e/epos/epos_2.5.37-8_amd64.deb
Nainstalujeme hlasy:
http://switch.dl.sourceforge.net/sourceforge/epos/epos-tdp.tgz
nebo zde:
http://epos.ure.cas.cz/
A rozbalíme do /usr/share/epos/inv a/nebo /usr/share/epos/inv/tdp
zapneme violku
eposd --voice violka -D
a vyzkoušíme say-epos nazdar případně
padsp eposd --voice violka -D
killall eposd A nyní skript (nelze spouštět jako root): #!/bin/bash # skript na cteni textu ze schranky pomoci TTS programu Epos hlasem violka # potreba je: gawk, xsel, sox, cstocs, epos, VLC # hlasy z http://epos.ufe.cz/download/inv/epos-tdp.tgz rozbalit do /usr/share/epos/inv/ # neni nutne,ale hodi se k zobrazovani bublinovych informaci: libnotify-bin #TODO # pro chybe zkontrolovat, elsi vse nainsatlovane; / instalacni skript ? # zmensit i éíáščě kapitalky? - awk - Je potreba? # function s vicesovnymi argumenty - zbytecne # Plocha/Desktop atd. - unverzalni nazev # backup mode - ukoncit VLC / nahradit jeho Playlist aktualnim umistenim souboru. # backup mode - sloucit vysledek do jednoho souboru a enkodovat do ogg/mp3. # pri ukonceni VLC v prubehu zpracovani prerusit dalsi zpracovavani textu. echo '- Jde se na vec:-)' echo '- Nastaveni promennych' icon="/usr/share/icons/Humanity/devices/48/audio-input-microphone.svg" # ikona zobrazena v bublinove napovede Jmeno=$(basename "$0") # nazev souboru skriptu time=$(date +%d.%m_%T) # cas spusteni skriptu l=5k # text bude delen na casti po "l" bytech. 1 kB textu ~ 915 znaků ~ 1 min zvuku ~ 4 MB zvukoveho zaznamu ve .wav formatu n=5 # pocet pokusu o prevedeni textu na zvuk, nez to skript vzda echo '- Nastaveni adresare pro docasne soubory' mkdir -p /tmp/$Jmeno/ cd /tmp/$Jmeno echo '- Zacatek logovani chyb' #exec 1>log 2>&1 #exec 2>log #exec 2>&1 | tee -a log #exec 3>&1 > >(tee -a /dev/fd/3 | logger -p "$LOG_FACILITY" -t "$LOG_TOPIC_OUT" ) exec 2> >(tee -a log) # Overime, zda skript byl minule ukoncen normalnim zpusobem if [ -e /tmp/$Jmeno/$Jmeno.pid ]; then echo '! Po predchozim spusteni nebyl skript korektne ukoncen' # notify-send --urgency=low --icon=$icon "Naposledy nebyl skript korektně ukončen" "Pokusím se obnovit data z minula" PID1=$(ps -p $(cat $Jmeno.pid)) # zjisti, zda je zjistene PID aktivni # echo '- PID1 = '$PID1 PID2=$(echo $PID1 | gawk '{print $8}') # zjisti nazev programu s danym PID # echo '- PID2 = '$PID2 PID3=$(echo $Jmeno | gawk '{print substr($(basename "$0"),1,15)}') # oreze na 15 znaku (protoze 'ps' mi vyhazuje nazev kdoviproc zkraceny) # echo '- PID3 = '$PID3 if [ "$PID2" == "$PID3" ]; then # porovnanim overi, zda se pod danym PID neskryva jiz jiny program echo ' ! Skript jiz jednou bezi s PID '$(cat $Jmeno.pid)', pred pokracovanim je nutno ho sestrelit' kill -9 $(cat $Jmeno.pid) echo ' - Prave se tak stalo, muzeme pokracovat' fi fi # Skript stoprocentne bezi pouze jednou, nastala vhodna chvile se podepsat echo $$ > $Jmeno.pid # FUNKCE # pauza pro odhmyzovaci ucely function pauza(){ read -p “$*” } # osekani moc dlouhych pauz function trim() { echo '- Osekani zbytecne dlouhych mezer na konci kazde vety' #sox said.wav $1.wav silence 0 -1 00:00:00.9 1% sox said.wav $1 silence -l 1 0.1 1% -1 0.6 1% # vysvetleni parametru modulu silence: -l = orezat mezery na jistou mez, 1 = oriznout pripadnou mezeru na zacatku zvukove stopy, 0.1 = minimalni delka zvuku, po niz se prestava orezavat, 1% = prah citlivost k sumu, -1 = odstranovat vsechny ostatni mezery az do konce, 0.6 = nastaveni delky ponechaneho useku ticha, 1% = prah citlivosti k sumu } # zpracovani hlasu 1 - nacteni function Voice_read() { nn=$n echo '- Zacina synteza zvuku. Obcas to nevyjde napoprve, zkusime to nanejvys '$nn' krat.' while [ $nn -gt 0 ]; do echo '- Zbyva' $nn 'pokusu' #let n=n-1 let nn=nn-1 echo '- Spusteni eposd' eposd --voice violka echo '- Vygenerovani wav' cstocs utf8 il2 $1 | say-epos -w - echo '- Pokus o syntezu ukoncen' if [ -e said.wav ]; then echo '- Surovy zvukovy zaznam je hotov' nn=0; fi done; } # zpracovani hlasu 2 - zkraceni mezer a vlozeni do fronty k prehrani function Voice_process() { if [ -z $1 ]; then echo '! Chybi vstupni parameter s nazvem souboru ke zpracovani, zkusime vychozi surovy zaznam.' set 1=said.wav fi if [ ! -e $1 ]; then echo '- Pokus o zpracovani '$1 trim $1 if [ -e $1 ]; then echo '- Finalni zaznam '$1' je hotovy, nyni bude prehran' vlc --started-from-file --playlist-enqueue "/tmp/$Jmeno/$1" & # Spust v rezimu jedine instance, pridej do playlistu a pokracuj if [ -z "$pid_player" ]; then pid_player=$! echo '- Spusten prehravac s PID='$pid_player fi else chyba=$(sed 2q log) notify-send --urgency=low --icon=$icon "Text se nepodařilo převést na hlas" "$chyba" cp -u log ~/Plocha/Precti_to_log_$time notify-send --urgency=low --icon=$icon "Chyby byly zaznamenány do logu" "Právě byl zálohován na plochu pod jménem 'Precti_to_log_$time'" fi else echo '! Nalezen z minula zvuk jiz uspesne upraveny do finalni podoby' if [ ! "$backup" = "1" ]; then echo ' - prepnuto do modu zalohovani' backup=1 mkdir -p ~/Plocha/$Jmeno-$time/ notify-send --urgency=low --icon=$icon "Z minula zůstal zvukový záznam" "Zpracovaný záznam bude zálohován na Plochu do adresáře jménem '$Jmeno-$time'" fi fi #pauza 'enter' } # zobrazeni bublinove zpravy #function notify() { # notify-send --urgency=$1 --icon=$icon $2 $3 #} #HLAVNI CAST if [ ! -e $Jmeno ]; then echo '- Ziskani obsahu clipboardu' xsel -o > $Jmeno # Pokud by nefungovalo, "Kocuro Pablo" by misto tohoto pouzil nasledujici radek # xsel -o -b -t 1500 > $Jmeno text=$(sed 2q $Jmeno) # oznameni, co se bude predcitat notify-send --urgency=low --icon=$icon "Bude přečten text:" "$text" else echo '! Nalezen surovy text z minula' text=$(sed 2q $Jmeno) # oznameni, co se bude predcitat notify-send --urgency=low --icon=$icon "Bude obnoven text:" "$text" fi #pauza 'enter' if [ ! -e $Jmeno.2 ]; then echo '- Upravy textu pro srozumitelnejsi prednes' # všechno malým, ať Violka nehláskuje? #tr '[:upper:]' '[:lower:]' < $Jmeno > $Jmeno.1 awk '{print tolower($0)}' < $Jmeno > $Jmeno.1 sed -e :a -e '$!N;s/\n/. /;ta' -e 'P;D' $Jmeno.1 | sed 's/"/ /g;s/(/ /g;s/)/ /g;s/atd\./ a tak dále /g;s/mj\./ mimo jiné /g;s/apod\./ a podobně /g;s/aj\./ a jiné /g' > $Jmeno.2 # Nahrazeni koncu radku teckou, nahrada nekterych obvyklych zkratek celymi frazemi, odstraneni zavorek, uvozovek... else echo '! Nalezen upraveny text z minula' fi #pauza 'enter' if [ ! -e $Jmeno.2.aa ]; then echo '- Rozdeleni textu na casti po '$l' bytech' split --bytes=$l $Jmeno.2 $Jmeno.2. else echo '! Nalezen rozdeleny text z minula' fi #pauza 'enter' for f in $Jmeno.2.??; do rm -rf /tmp/$Jmeno/said.wav if [ ! -e $f.wav ]; then Voice_read $f fi Voice_process $f.wav if [ "$backup" = "1" ]; then echo ' - Zaznam zkopirovan do ~/Plocha/'$Jmeno'-'$time'/'$f'.wav' cp $f.wav ~/Plocha/$Jmeno-$time/$f.wav fi done #pauza 'enter' echo '- Ceka se na ukonceni prehravace s PID='$pid_player wait $pid_player echo '- Prehravac ukoncen' echo '- Zacinaji uklidove prace' echo '- Ukonceni zbylych procesu' killall say-epos #killall eposd echo '- Odstraneni nepotrebnych souboru' rm -rf /tmp/$Jmeno/ echo '- Tak zase nekdy...' exit ------------------- Poznámka:
pokud by někdo měl problém se změnou hlasu – typicky při say-epos –voice violka to čte stále výchozím mužským hlasem –
tak ať se podívá do /etc/epos/restr.ini a zakomentuje příslušný parametr.
Sám nevím který, teď to zkoušet nebudu – soubor jsem přejmenoval celý na restr.ini.old a parametr pro změnu hlasu z say-epos funguje. Tento můj líný hack (povolí měnit všechny parametry z klienta) může teoreticky kompromitovat bezpečnost… takže pokud máte více času tak si zkuste
1. zakomentovat všechny (středník),
2. restartovat epos /etc/init.d/epos restart
3. vyzkoušet say-epos –voice violka…
4. pokud bude opět skřehotat mužským hlasem tak poslední odkomentovaný parametr je ten který brání změně hlasu
5. jeden parametr odkomentovat
5. pokračovat bodem 2.
nebo se prokousejte dost podrobným manuálem /usr/share/doc/epos/html/epos.html