Updated set-voice because we no longer need variable for se and grep, we also save everything thus far in the same bottle so no need for bottle select. Small test shows it working.

This commit is contained in:
Storm Dragon
2025-12-08 05:04:46 -05:00
parent 20e55ddc4e
commit 55ca53cba6

View File

@@ -1,15 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Set Voice - Fixed version for audiogame-manager # Set Voice - Fixed version for audiogame-manager
# Set a variable to make mac compatibility easier...
sed="sed"
grep="grep"
if [[ "$(uname)" == "Darwin" ]]; then
sed="gsed"
grep="ggrep"
fi
export grep
export sed
# Settings to improve accessibility of dialog. # Settings to improve accessibility of dialog.
export DIALOGOPTS='--insecure --no-lines --visit-items' export DIALOGOPTS='--insecure --no-lines --visit-items'
@@ -22,7 +13,6 @@ fi
# Handle arguments # Handle arguments
declare -A command=( declare -A command=(
[b:]="the wine bottle to use."
[h]="This help screen." [h]="This help screen."
[r:]="Specify voice rate, default is 7, options are 0-9 or A for fastest." [r:]="Specify voice rate, default is 7, options are 0-9 or A for fastest."
[v:]="Voice name, the voice to use, same as in the menu." [v:]="Voice name, the voice to use, same as in the menu."
@@ -40,9 +30,6 @@ help() {
exit 0 exit 0
} }
msgbox() {
dialog --clear --msgbox "$*" 0 0
}
menulist() { menulist() {
declare -a menuList declare -a menuList
@@ -60,8 +47,8 @@ menulist() {
restore_voice() { restore_voice() {
if [[ $doRestore -eq 0 ]]; then if [[ $doRestore -eq 0 ]]; then
${wine}server -k wineserver -k
$sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="'"${oldVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg" sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="'"${oldVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg"
fi fi
} }
@@ -72,16 +59,17 @@ set_voice() {
local counter=0 local counter=0
for x in "${voiceList[@]}" ; do for x in "${voiceList[@]}" ; do
[[ "$x" = "$tmp" ]] && break [[ "$x" = "$tmp" ]] && break
counter=$(( $counter + 1 )) counter=$((counter + 1))
done done
local RHVoiceName="$(find "${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/" -maxdepth 1 -type d 2>/dev/null | head -1)" local RHVoiceName
RHVoiceName="$(find "${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/" -maxdepth 1 -type d 2>/dev/null | head -1)"
RHVoiceName="${RHVoiceName##*/}" RHVoiceName="${RHVoiceName##*/}"
fullVoice="${voiceListFullName[$counter]}" fullVoice="${voiceListFullName[$counter]}"
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}" fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
${wine}server -k wineserver -k
# Remove any existing rate change for voices # Remove any existing rate change for voices
$sed -i '/"DefaultTTSRate"=dword:/d' "${WINEPREFIX}/user.reg" sed -i '/"DefaultTTSRate"=dword:/d' "${WINEPREFIX}/user.reg"
$sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"\n"DefaultTTSRate"=dword:0000000'${rate:-7}'/g' "${WINEPREFIX}/user.reg" sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"\n"DefaultTTSRate"=dword:0000000'"${rate:-7}"'/g' "${WINEPREFIX}/user.reg"
} }
test_voice() { test_voice() {
@@ -90,21 +78,22 @@ test_voice() {
local fullVoice local fullVoice
local counter=0 local counter=0
for x in "${voiceList[@]}" ; do for x in "${voiceList[@]}" ; do
[ "$x" = "$tmp" ] && break [[ "$x" = "$tmp" ]] && break
counter=$(( $counter + 1 )) counter=$((counter + 1))
done done
local RHVoiceName="$(find "${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/" -maxdepth 1 -type d 2>/dev/null | head -1)" local RHVoiceName
RHVoiceName="$(find "${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/" -maxdepth 1 -type d 2>/dev/null | head -1)"
RHVoiceName="${RHVoiceName##*/}" RHVoiceName="${RHVoiceName##*/}"
fullVoice="${voiceListFullName[$counter]}" fullVoice="${voiceListFullName[$counter]}"
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}" fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
${wine}server -k wineserver -k
$sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg" sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg"
cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs" cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs"
dim speechobject dim speechobject
set speechobject=createobject("sapi.spvoice") set speechobject=createobject("sapi.spvoice")
speechobject.speak "This is a test of your chosen voice. It contains multiple sentences and punctuation, and is designed to give a full representation of this voices qualities." speechobject.speak "This is a test of your chosen voice. It contains multiple sentences and punctuation, and is designed to give a full representation of this voices qualities."
EOF EOF
${wine} cscript "c:\windows\temp\speak.vbs" wine cscript "c:\windows\temp\speak.vbs"
} }
# Handle voice restore, but only if voice changed # Handle voice restore, but only if voice changed
@@ -116,14 +105,6 @@ args="${!command[*]}"
args="${args//[[:space:]]/}" args="${args//[[:space:]]/}"
while getopts "${args}" i ; do while getopts "${args}" i ; do
case "$i" in case "$i" in
b)
if ! [[ -d ~/".local/wine/${OPTARG}" ]]; then
echo "Invalid wine bottle specified."
exit 1
fi
export bottle=~/".local/wine/${OPTARG}"
export WINEPREFIX=~/".local/wine/${OPTARG}"
;;
h) help;; h) help;;
r) r)
if ! [[ "${OPTARG}" =~ ^[0-9A]$ ]]; then if ! [[ "${OPTARG}" =~ ^[0-9A]$ ]]; then
@@ -136,39 +117,12 @@ while getopts "${args}" i ; do
esac esac
done done
# Get the desired wine bottle # Set wine bottle path to fixed location
# Offer a list of wine bottles if one isn't specified on the command line.
if [[ -z "${bottle}" ]]; then
declare -a bottle
for i in $(find ~/.local/wine/ -maxdepth 1 -type d -not -name 'wine' | sort) ; do
bottle+=("$i" "${i##*/}")
done
export WINEPREFIX="$(dialog --backtitle "Use the up and down arrow keys to find the option you want, then press enter to select it." \
--clear \
--no-tags \
--menu "Select A Wine Bottle" 0 0 0 "${bottle[@]}" --stdout)"
fi
if [[ -z "${WINEPREFIX}" ]]; then export WINEPREFIX="$HOME/.local/wine64"
exit 0
fi
export bottle="$WINEPREFIX" export bottle="$WINEPREFIX"
# Get wine version if available - Use wine32 for SAPI games
if [[ -r "${WINEPREFIX}/agm.conf" ]]; then
source "${WINEPREFIX}/agm.conf"
export WINE
export WINESERVER
fi
# Use wine32 installation from audiogame-manager
wine32Dir="${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/wine32"
if [[ -f "$wine32Dir/bin/wine" ]]; then
wine="$wine32Dir/bin/wine"
else
wine="${WINE:-$(command -v wine)}"
fi
# In case the user hasn't run a game using sapi in this prefix yet, let's try to initialize all the registry keys properly. # In case the user hasn't run a game using sapi in this prefix yet, let's try to initialize all the registry keys properly.
cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs" cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs"
@@ -176,18 +130,18 @@ dim speechobject
set speechobject=createobject("sapi.spvoice") set speechobject=createobject("sapi.spvoice")
speechobject.speak "" speechobject.speak ""
EOF EOF
${wine} cscript "c:\windows\temp\speak.vbs" wine cscript "c:\windows\temp\speak.vbs"
# Create an array of available voices. # Create an array of available voices.
ifs="$IFS" ifs="$IFS"
IFS=$'\n' IFS=$'\n'
voiceListFullName=($($grep -P '\[Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^\\]+\].*' "${WINEPREFIX}/system.reg" | $sed -E -e 's/\[([^]]+)\].*/\1/g')) mapfile -t voiceListFullName < <(grep -P '\[Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^\\]+\].*' "${WINEPREFIX}/system.reg" | sed -E -e 's/\[([^]]+)\].*/\1/g')
IFS="$ifs" IFS="$ifs"
voiceList=() voiceList=()
for x in "${voiceListFullName[@]}" ; do for x in "${voiceListFullName[@]}" ; do
voiceList+=("$(echo "$x" | $sed -E -e 's/Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\(.+)/\3/g')") voiceList+=("$(echo "$x" | sed -E -e 's/Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\(.+)/\3/g')")
done done
oldVoice="$($grep -P '"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"' "${WINEPREFIX}/user.reg" | $sed -E -e 's/"DefaultTokenId"="([^"]+)"/\1/g')" oldVoice="$(grep -P '"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"' "${WINEPREFIX}/user.reg" | sed -E -e 's/"DefaultTokenId"="([^"]+)"/\1/g')"
exit=1 exit=1
if [[ "${#voiceList[@]}" -eq 0 ]]; then if [[ "${#voiceList[@]}" -eq 0 ]]; then
dialog --msgbox "No voices found." -1 -1 dialog --msgbox "No voices found." -1 -1