sapo/Sapo.sh

292 lines
12 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#! /bin/bash
# ▗▄▖
#▗▛▀▜
#▐▙ ▟██▖▐▙█▙ ▟█▙
# ▜█▙ ▘▄▟▌▐▛ ▜▌▐▛ ▜▌
# ▜▌▗█▀▜▌▐▌ ▐▌▐▌ ▐▌
#▐▄▄▟▘▐▙▄█▌▐█▄█▘▝█▄█▘
# ▀▀▘ ▀▀▝▘▐▌▀▘ ▝▀▘
# ▐▌
# a tts bash script by Christos Angelopoulos, February 2022
#converts txt to wav
#using the all powerful https://github.com/coqui-ai/TTS
FILE="$(yad --file-selection --filename=Desktop --height='400' --width='800' --title='Sapo - Select File to Read' --window-icon=$HOME/git/sapo/sapo.png --hscroll-policy=never --vscroll-policy=never)"
case $? in
0)
;;
1) exit
;;
esac
DIRECTORY=${FILE%/*}/
NAME=${FILE##*/}
echo "FILE : ""$FILE"
mkdir "$DIRECTORY""Sapo_""$NAME"/
sed "s/—/\,\n/g;
s/^ *//g;
s/^\;$//g;
s/^\.$//g;
s/\…/\,/g;
s/\/\'/g;
s/(/\,\n(/g;
s/)/),\n/g;
s/\./\.\n/g;
s/\?/\?\n/g;
s/\:/\:\n/g;
s/\!/\!\n/g;
s/\;/\;\n/g;
s/\.\.\./\.\n/g" "$FILE" >"$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
sed -i "/^$/d" "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt #get rid of empty lines
sed -i -f $HOME/git/sapo/letters.sed "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
sed -i -f $HOME/git/sapo/abbreviations.sed "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
sed -i -f $HOME/git/sapo/fonetix.sed "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
##################extra delimit to comma and space ###################################
DELIM=$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|wc -l)
while [ $DELIM -ge 1 ]
do
CUR_DELIM_LINE=$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|head -$DELIM|tail +$DELIM)
CHAR_COUNT=$(echo "$CUR_DELIM_LINE"|wc -m)
while [ $CHAR_COUNT -gt 290 ]
do
echo "character count : "$CHAR_COUNT
echo "characters > 290"
COMMA_COUNT=$(echo "$CUR_DELIM_LINE"| sed -e 's/\(.\)/\1\n/g' | grep "," | wc -l)
echo "comma count : "$COMMA_COUNT
if [ $COMMA_COUNT -gt 2 ]
then
echo "commas > 2"
echo $DELIM"s/\,/\,\n/"$(($COMMA_COUNT - 2))>"$DIRECTORY""Sapo_""$NAME"/script.sed
sed -i -f "$DIRECTORY""Sapo_""$NAME"/script.sed "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
fi
if [ $COMMA_COUNT -le 2 ]
then
echo "No commas to delimit to, proceed delimiting with spaces(limit 15)"
SPACE_COUNT=$(echo "$CUR_DELIM_LINE"| sed -e 's/\(.\)/\1\n/g' | grep " " | wc -l)
echo "Space count : "$SPACE_COUNT
echo $DELIM"s/\ /\|\n/"$(($SPACE_COUNT - 15))>"$DIRECTORY""Sapo_""$NAME"/script.sed
sed -i -f "$DIRECTORY""Sapo_""$NAME"/script.sed "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
fi
CUR_DELIM_LINE=$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|head -$DELIM|tail +$DELIM)
CHAR_COUNT=$(echo "$CUR_DELIM_LINE"|wc -m)
done
echo "Delimitation completed for line "$DELIM
((DELIM--))
done
####################### Extra substitutions
sed -i "s/^\,$//g;s/^ *'//g;s/^'//g;s/^ *//g;s/^//g " "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt
sed -i "/^$/d" "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt #get rid of empty lines
########################################
yad --image "$HOME/git/sapo/sapo.png" --height=40 --width=400 --title="${NAME} - Sapo" --button=gtk-cancel:1 --button=gtk-open:2 --button=gtk-ok:0 --text="The text is prepared, Press:
1. <span foreground='yellow'><b>Open </b></span>to edit the new file
2. <span foreground='yellow'><b>OK </b></span>to proceed to speech conversion." --window-icon=$HOME/git/sapo/sapo.png
case $? in
0)
;;
1) exit
;;
2) xed "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt & yad --image "$HOME/git/sapo/sapo.png" --height=40 --width=400 --title="${NAME} - Sapo" --button=gtk-cancel:1 --button=gtk-ok:0 --text="If you are done editing $NAME\sentenced.txt, <span foreground='yellow'><b>press OK</b></span> to continue!" --window-icon=$HOME/git/sapo/sapo.png
case $? in
0)
;;
1) exit
;;
esac
esac
TOTALLINES=$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|wc -l)
LINE=1
(
while [ $LINE -le $TOTALLINES ]
do
CURRENTLINE=$(head -$LINE "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|tail +$LINE)
FORMLINE="$(printf "%.6d" $LINE)"
tts --text "$CURRENTLINE" --out_path "$DIRECTORY""Sapo_""$NAME"/$FORMLINE.wav
### wav files of space delimited lines marked |$ are trimmed at the end!
if [[ "$CURRENTLINE" == *"|" ]]
then
sox "$DIRECTORY""Sapo_""$NAME"/$FORMLINE.wav "$DIRECTORY""Sapo_""$NAME"/temp.wav trim 0 -0.5;mv "$DIRECTORY""Sapo_""$NAME"/temp.wav "$DIRECTORY""Sapo_""$NAME"/$FORMLINE.wav
fi
####error detection routine######
CURRENTLINE_LENGTH=$(echo $CURRENTLINE|wc -m)
WAV_LENGTH=$(jq -n $(sox "$DIRECTORY""Sapo_""$NAME"/$FORMLINE.wav -n stat 2>&1 |sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')-0.660)
RATIO=$(jq -n $CURRENTLINE_LENGTH/$WAV_LENGTH|sed 's/\..*$//')
if [ $RATIO -le 8 ]
then
echo $LINE $FORMLINE.wav $CURRENTLINE_LENGTH $WAV_LENGTH $RATIO>>"$DIRECTORY""Sapo_""$NAME"/errors.tsv
fi
###################################
###Estimating Estimated time of arrival
### Character based percentage ######
TOTALCHARS=$(wc -m "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt |awk '{print $1}')
CHARSDONE=$(head -$LINE "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|wc -m)
CHARSLEFT=$(($TOTALCHARS - $CHARSDONE))
SECONDS=$(( $CHARSLEFT / 4 ))
CHARSDONE100=$(($CHARSDONE * 100))
PERCENTAGE=$(( $CHARSDONE100 / $TOTALCHARS))
HOURS=$(( SECONDS / 3600 ))
SECHLEFT=$(( $SECONDS - $((HOURS * 3600 )) ))
MINUTES=$(( $SECHLEFT / 60 ))
SECMLEFT=$(( $SECHLEFT - $((MINUTES * 60 )) ))
HOURSTRING="$HOURS"" hrs"
MINUTESTRING="$MINUTES"" mins"
## if hours / minutes left are 0 , they are not mentioned
if [ $HOURS -eq 0 ]
then
HOURSTRING=""
fi
if [ $MINUTES -eq 0 ]
then
MINUTESTRING=""
fi
#echo line starting with #, updated in the yad progress bar window
echo "# Reading line $(( $LINE + 1)) of $TOTALLINES from "$NAME" ($PERCENTAGE%). Roughly remaining : "$HOURSTRING" "$MINUTESTRING" " $SECMLEFT" secs"
echo "$PERCENTAGE"
((LINE++))
done
) |
yad --progress --height="40" \
--title="Sapo - Reading . . . ${NAME}" \
--percentage=0 \
--height=40 \
--width="500" \
--window-icon=$HOME/git/sapo/sapo.png \
--image "$HOME/git/sapo/sapo_progress.png" \
--auto-close
#--text="Preparing to read..." \
case $? in
0)
;;
1) exit
;;
esac
##### Error correction routine ######
(
TOTAL_ERRORS=$(cat "$DIRECTORY""Sapo_""$NAME"/errors.tsv|wc -l)
ERROR_LINE=1
while [ $ERROR_LINE -le $TOTAL_ERRORS ]
do
CURRENT_ERROR_LINE=$(cat "$DIRECTORY""Sapo_""$NAME"/errors.tsv|head -$ERROR_LINE|tail +$ERROR_LINE)
ERROR_TEXT_LINE=$(echo $CURRENT_ERROR_LINE|awk '{print $1}')
ERROR_WAV=$(echo $CURRENT_ERROR_LINE|awk '{print $2}')
echo "#Attempting to fix error $ERROR_LINE of $TOTAL_ERRORS, line $ERROR_TEXT_LINE from $NAME.sentenced.txt"
###################################
ERROR_LINE100=$(( $ERROR_LINE * 100 ))
ERROR_PERCENTAGE=$(( $ERROR_LINE100 / $TOTAL_ERRORS))
echo "$ERROR_PERCENTAGE"
tts --text "$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|head -$ERROR_TEXT_LINE|tail +$ERROR_TEXT_LINE)" --out_path "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV
((ERROR_LINE++))
done
)|
yad --progress --height="40" \
--title="Sapo - Fixing Errors . . . ${NAME}" \
--percentage=0 \
--height=40 \
--width="500" \
--window-icon=$HOME/git/sapo/sapo.png \
--image "$HOME/git/sapo/sapo_progress.png" \
--auto-close
####### FIXING ERRORS ONE BY ONE or EDIT THE FILE LINE BY LINE############
yad --image "$HOME/git/sapo/sapo.png" \
--height=40 --width=200 --title="${NAME} - Sapo" \
--text="Which lines do you want to fix?" \
--button=gtk-cancel:1 \
--button='All Lines':2 \
--button='Just Errors':3 \
--window-icon=$HOME/git/sapo/sapo.png
case $? in
1) exit
;;
2) LINES_TO_EDIT="ALL"
;;
3) LINES_TO_EDIT="ERRORS"
;;
esac
if [[ $LINES_TO_EDIT == "ALL" ]]
then
TOTAL_ERRORS=$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|wc -l)
else
TOTAL_ERRORS=$(cat "$DIRECTORY""Sapo_""$NAME"/errors.tsv|wc -l)
fi
ERROR_LINE=1
BROWSE_NEXT=false
while [ $ERROR_LINE -le $TOTAL_ERRORS ]
do
if [[ $LINES_TO_EDIT == "ALL" ]]
then
CURRENT_ERROR_LINE=$ERROR_LINE
ERROR_TEXT_LINE=$ERROR_LINE
else
CURRENT_ERROR_LINE=$(cat "$DIRECTORY""Sapo_""$NAME"/errors.tsv|head -$ERROR_LINE|tail +$ERROR_LINE)
ERROR_TEXT_LINE=$(echo $CURRENT_ERROR_LINE|awk '{print $1}')
fi
ERROR_WAV="$(printf "%.6d" $ERROR_TEXT_LINE)".wav
TEXT_TO_CORRECT="$(cat "$DIRECTORY""Sapo_""$NAME"/"$NAME"sentenced.txt|head -$ERROR_TEXT_LINE|tail +$ERROR_TEXT_LINE)"
GO=false
while [[ $GO == false ]]
do
if [[ $BROWSE_NEXT == true ]]
then
killall mplayer;mplayer "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV &
fi
BROWSE_NEXT=false
yad --image "$HOME/git/sapo/sapo.png" \
--height=40 --width=400 \
--title="Line $ERROR_TEXT_LINE ( of $TOTAL_ERRORS )- $NAME" \
--button=gtk-cancel:1 \
--button='▶️ Play':2 \
--button='🔃 Render':3 \
--button='✂️ Trim':4 \
--button='🪚 Split':5 \
--button='🛠️ Edit':7 \
--button='❌ Remove':6 \
--button='⬅️ Previous':8 \
--button='➡️ Next':0 \
--button='👉 Go To':10 \
--button='⏩ Browse':9 \
--text="Text of line $ERROR_TEXT_LINE ( of $TOTAL_ERRORS ):
<span foreground='yellow'><b>$TEXT_TO_CORRECT</b></span>
-What would you like to do?" \
--window-icon=$HOME/git/sapo/sapo.png
case $? in
0) GO=true
;;
1) exit
;;
2) if [[ -e "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV ]];then killall mplayer;mplayer "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV & else notify-send "There is no file ""$DIRECTORY""Sapo_""$NAME"/"$ERROR_WAV"".";fi
;;
3) killall mplayer;s="$(yad --entry --width="600" --text="This is the original text of the line $ERROR_TEXT_LINE.
Edit as you wish, then hit OK to render." --entry-text="$TEXT_TO_CORRECT" --window-icon=$HOME/git/sapo/sapo.png --title="Line $ERROR_TEXT_LINE - $NAME")";tts --text "$s" --out_path "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV
;;
4)killall mplayer;sox -V3 "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV "$DIRECTORY""Sapo_""$NAME"/temp.wav silence 1 0.50 0.1% 1 0.5 0.1%;sox "$DIRECTORY""Sapo_""$NAME"/temp.wav "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV pad 0 0.5;rm "$DIRECTORY""Sapo_""$NAME"/temp.wav
;;
5)killall mplayer;s="$(yad --entry --width="600" --text="Split the printed text roughly in half with the pipe symbol (|), so that it can be rendered in two batches: " --entry-text="$TEXT_TO_CORRECT" --window-icon=$HOME/git/sapo/sapo.png --title="Line $ERROR_TEXT_LINE - $NAME")";s1="$(echo $s|sed 's/|.*$//')";s2="$(echo $s|sed 's/^.*|//')"; echo $s1;echo $s2 ; tts --text "$s1" --out_path "$DIRECTORY""Sapo_""$NAME"/1temp.wav; tts --text "$s2" --out_path "$DIRECTORY""Sapo_""$NAME"/2temp.wav;sox "$DIRECTORY""Sapo_""$NAME"/1temp.wav "$DIRECTORY""Sapo_""$NAME"/2temp.wav "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV ; rm "$DIRECTORY""Sapo_""$NAME"/1temp.wav "$DIRECTORY""Sapo_""$NAME"/2temp.wav
;;
6) if [[ -e "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV ]];then rm "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV;notify-send "$DIRECTORY""Sapo_""$NAME"/"$ERROR_WAV"" has been deleted."; else notify-send "There is no file ""$DIRECTORY""Sapo_""$NAME"/"$ERROR_WAV"". Already deleted?";fi;GO=true
;;
7)killall mplayer;audacity "$DIRECTORY""Sapo_""$NAME"/$ERROR_WAV
;;
8)killall mplayer; GO=true; ERROR_LINE=$(($ERROR_LINE - 2))
;;
9) BROWSE_NEXT=true; GO=true
;;
10) killall mplayer;ERROR_LINE="$(yad --entry --height=40 --width=400 --text="Go To Line:" --entry-text="$ERROR_LINE" --window-icon=$HOME/git/sapo/sapo.png --title="Go To Line ")";((ERROR_LINE--));GO=true
esac
done
((ERROR_LINE++))
done
sox "$DIRECTORY""Sapo_""$NAME"/*.wav "$DIRECTORY""Sapo_""$NAME"/"$NAME".wav
yad --image "$HOME/git/sapo/sapo.png" --height=40 --width=400 --title="${NAME} - Sapo" --text="Reading of ""$NAME"" is complete!" --window-icon=$HOME/git/sapo/sapo.png