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
# 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.
export DIALOGOPTS='--insecure --no-lines --visit-items'
@@ -22,7 +13,6 @@ fi
# Handle arguments
declare -A command=(
[b:]="the wine bottle to use."
[h]="This help screen."
[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."
@@ -40,9 +30,6 @@ help() {
exit 0
}
msgbox() {
dialog --clear --msgbox "$*" 0 0
}
menulist() {
declare -a menuList
@@ -60,8 +47,8 @@ menulist() {
restore_voice() {
if [[ $doRestore -eq 0 ]]; then
${wine}server -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"
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"
fi
}
@@ -72,16 +59,17 @@ set_voice() {
local counter=0
for x in "${voiceList[@]}" ; do
[[ "$x" = "$tmp" ]] && break
counter=$(( $counter + 1 ))
counter=$((counter + 1))
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##*/}"
fullVoice="${voiceListFullName[$counter]}"
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
${wine}server -k
wineserver -k
# Remove any existing rate change for voices
$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 '/"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"
}
test_voice() {
@@ -90,21 +78,22 @@ test_voice() {
local fullVoice
local counter=0
for x in "${voiceList[@]}" ; do
[ "$x" = "$tmp" ] && break
counter=$(( $counter + 1 ))
[[ "$x" = "$tmp" ]] && break
counter=$((counter + 1))
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##*/}"
fullVoice="${voiceListFullName[$counter]}"
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
${wine}server -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"
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"
cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs"
dim speechobject
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."
EOF
${wine} cscript "c:\windows\temp\speak.vbs"
wine cscript "c:\windows\temp\speak.vbs"
}
# Handle voice restore, but only if voice changed
@@ -116,14 +105,6 @@ args="${!command[*]}"
args="${args//[[:space:]]/}"
while getopts "${args}" i ; do
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;;
r)
if ! [[ "${OPTARG}" =~ ^[0-9A]$ ]]; then
@@ -136,39 +117,12 @@ while getopts "${args}" i ; do
esac
done
# Get the desired wine bottle
# 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
# Set wine bottle path to fixed location
if [[ -z "${WINEPREFIX}" ]]; then
exit 0
fi
export WINEPREFIX="$HOME/.local/wine64"
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.
cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs"
@@ -176,18 +130,18 @@ dim speechobject
set speechobject=createobject("sapi.spvoice")
speechobject.speak ""
EOF
${wine} cscript "c:\windows\temp\speak.vbs"
wine cscript "c:\windows\temp\speak.vbs"
# Create an array of available voices.
ifs="$IFS"
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"
voiceList=()
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
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
if [[ "${#voiceList[@]}" -eq 0 ]]; then
dialog --msgbox "No voices found." -1 -1