2020-12-12 02:21:35 -05:00
#!/usr/bin/env bash
2020-09-20 14:31:11 -04:00
# Set Voice
2022-08-23 12:56:20 -04:00
# Set the default wine voice ba$sed on installed options.
2020-10-04 12:27:36 -04:00
# Rate can be specified as a numeric argument to this script, 1 through 9.
2021-07-06 13:53:41 -04:00
# The default rate is 7
2020-12-16 14:45:14 -05:00
#
# ■The contents of this file are subject to the Common Public Attribution
# License Version 1.0 (the ■License■); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
2022-08-23 12:56:20 -04:00
# https://opensource.org/licenses/CPAL-1.0. The License is ba$sed on the Mozilla Public License Version
2020-12-16 14:45:14 -05:00
# 1.1 but Sections 14 and 15 have been added to cover use of software over a
# computer network and provide for limited attribution for the Original
# Developer. In addition, Exhibit A has been modified to be consistent with
# Exhibit B.
#
# Software distributed under the License is distributed on an ■AS IS■ basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
2020-12-16 16:36:05 -05:00
# The Original Code is audiogame manager.
2020-12-16 14:45:14 -05:00
#
# The Original Developer is not the Initial Developer and is . If
# left blank, the Original Developer is the Initial Developer.
2020-09-20 14:31:11 -04:00
#
2020-12-16 14:45:14 -05:00
# The Initial Developer of the Original Code is Billy "Storm Dragon" Wolfe. All portions of
# the code written by Billy Wolfe are Copyright (c) 2020. All Rights
# Reserved.
2020-09-20 14:31:11 -04:00
#
2020-12-16 14:45:14 -05:00
# Contributor Michael Taboada.
2020-09-20 14:31:11 -04:00
#
2020-12-16 16:36:05 -05:00
# Attribution Copyright Notice: Audiogame manager copyright 2020 Storm Dragon. All rights reserved.
2020-09-20 14:31:11 -04:00
#
2020-12-16 17:16:16 -05:00
# Attribution Phrase (not exceeding 10 words): A Stormux project
2020-12-16 14:45:14 -05:00
#
# Attribution URL: https://stormgames.wolfe.casa
#
# Graphic Image as provided in the Covered Code, if any.
#
# Display of Attribution Information is required in Larger
# Works which are defined in the CPAL as a work which combines Covered Code
# or portions thereof with code not governed by the terms of the CPAL.
2020-09-20 14:31:11 -04:00
#--code--
2022-08-23 12:56:20 -04:00
# Set a variable to make mac compatibility easier...
sed = "sed"
grep = "grep"
if [ [ " $( uname) " = = "Darwin" ] ] ; then
sed = "gsed"
grep = "ggrep"
fi
2022-08-23 13:19:52 -04:00
export grep
export sed
2020-09-20 14:31:11 -04:00
# Settings to improve accessibility of dialog.
export DIALOGOPTS = '--insecure --no-lines --visit-items'
2021-05-12 04:43:49 -04:00
# Turn off debug messages
export WINEDEBUG = "-all"
# Set DISPLAY, as needed
if [ -z " $DISPLAY " ] ; then
export DISPLAY = :0
fi
2020-09-20 14:31:11 -04:00
# Get the desired wine bottle
declare -a bottle
2021-05-12 03:50:33 -04:00
for i in $( find ~/.local/wine/ -maxdepth 1 -type d -not -name 'wine' | sort) ; do
2020-09-20 14:31:11 -04:00
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) "
if [ [ -z " ${ WINEPREFIX } " ] ] ; then
exit 0
fi
2023-02-05 15:37:57 -05:00
# Get wine version if available
if [ [ -r " ${ WINEPREFIX } /agm.conf " ] ] ; then
source " ${ WINEPREFIX } /agm.conf "
export WINE
export WINESERVER
fi
wine = " ${ WINE :- $( command -v wine) } "
2020-09-20 14:31:11 -04:00
msgbox( ) {
# Returns: None
# Shows the provided message on the screen with an ok button.
dialog --clear --msgbox " $* " 0 0
}
infobox( ) {
# Returns: None
# Shows the provided message on the screen with no buttons.
local timeout = 3
dialog --infobox " $* " 0 0
read -n1 -t $timeout continue
# Clear any keypresses from the buffer
read -t 0.01 continue
}
yesno( ) {
# Returns: Yes or No
# Args: Question to user.
# Called in if $(yesno) == "Yes"
# Or variable=$(yesno)
dialog --clear --backtitle "Press 'Enter' for " yes" or 'Escape' for " no"." --yesno " $* " 0 0 --stdout
if [ [ $? -eq 0 ] ] ; then
echo "Yes"
else
echo "No"
fi
}
menulist( ) {
# Args: List of items for menu.
# returns: selected tag
declare -a menuList
for i in " ${ @ } " ; do
menuList += ( " $i " " $i " )
done
2022-12-05 23:58:48 -05:00
dialog --backtitle "Use the up and down arrow keys to find the option you want, then press enter to select it." \
2020-09-20 14:31:11 -04:00
--clear \
--extra-button \
2022-12-05 23:58:48 -05:00
--extra-label "Test Voice" \
2020-09-20 14:31:11 -04:00
--no-tags \
2022-12-05 23:58:48 -05:00
--menu "Please select one" 0 0 0 " ${ menuList [@] } " --stdout
2020-09-20 14:31:11 -04:00
return $?
}
restore_voice( ) {
if [ [ $doRestore -eq 0 ] ] ; then
2023-02-05 15:37:57 -05:00
${ wine } server -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely
2022-08-23 12:56:20 -04:00
$sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="' " ${ oldVoice // \\ / \\ \\ } " '"/g' " ${ WINEPREFIX } /user.reg "
2020-09-20 14:31:11 -04:00
fi
}
set_voice( ) {
doRestore = 1
local tmp = " $1 "
local fullVoice
local counter = 0
2020-11-20 20:10:28 -05:00
for x in " ${ voiceList [@] } " ; do
2020-09-20 14:31:11 -04:00
[ " $x " = " $tmp " ] && break
counter = $(( $counter + 1 ))
done
2022-08-23 13:19:52 -04:00
local RHVoiceName = " $( find " ${ WINEPREFIX } /drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/ " -maxdepth 1 -type d) "
RHVoiceName = " ${ RHVoiceName ##*/ } "
2020-11-20 20:10:28 -05:00
fullVoice = " ${ voiceListFullName [ $counter ] } "
2022-08-23 13:19:52 -04:00
fullVoice = " ${ fullVoice /RHVoice/RHVoice \\ \\ ${ RHVoiceName } } "
2023-02-05 15:37:57 -05:00
${ wine } server -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely
2020-10-04 12:27:36 -04:00
# Remove any existing rate change for voices
2022-08-23 12:56:20 -04:00
$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' ${ 2 :- 7 } '/g' " ${ WINEPREFIX } /user.reg "
2020-09-20 14:31:11 -04:00
}
test_voice( ) {
doRestore = 0
local tmp = " $1 "
local fullVoice
local counter = 0
2020-11-20 20:10:28 -05:00
for x in " ${ voiceList [@] } " ; do
2020-09-20 14:31:11 -04:00
[ " $x " = " $tmp " ] && break
counter = $(( $counter + 1 ))
done
2022-08-23 13:19:52 -04:00
local RHVoiceName = " $( find " ${ WINEPREFIX } /drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/ " -maxdepth 1 -type d) "
RHVoiceName = " ${ RHVoiceName ##*/ } "
2020-11-20 20:10:28 -05:00
fullVoice = " ${ voiceListFullName [ $counter ] } "
2022-08-23 13:19:52 -04:00
fullVoice = " ${ fullVoice /RHVoice/RHVoice \\ \\ ${ RHVoiceName } } "
2023-02-05 15:37:57 -05:00
${ wine } server -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely
2022-08-23 12:56:20 -04:00
$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 "
2022-12-23 02:12:34 -05:00
cat << "EOF" > " ${ bottle } /drive_c/windows/temp/speak.vbs "
2020-09-20 14:31:11 -04:00
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
2023-02-05 15:37:57 -05:00
${ wine } cscript "c:\windows\temp\speak.vbs"
2020-09-20 14:31:11 -04:00
}
# Handle voice restore, but only if voice changed
doRestore = 1
trap restore_voice SIGINT
2021-05-12 04:43:49 -04:00
# 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.
2022-12-23 02:12:34 -05:00
cat << "EOF" > " ${ bottle } /drive_c/windows/temp/speak.vbs "
2021-05-12 04:43:49 -04:00
dim speechobject
set speechobject = createobject( "sapi.spvoice" )
speechobject.speak ""
EOF
2023-02-05 15:37:57 -05:00
${ wine } cscript "c:\windows\temp\speak.vbs"
2021-05-12 04:43:49 -04:00
2020-09-20 14:31:11 -04:00
# Create an array of available voices.
ifs = " $IFS "
IFS = $'\n'
2022-08-23 12:56:20 -04:00
voiceListFullName = ( $( $grep -P '\[Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^\\]+\].*' " ${ WINEPREFIX } /system.reg " | $sed -E -e 's/\[([^]]+)\].*/\1/g' ) )
2020-09-20 14:31:11 -04:00
IFS = " $ifs "
voiceList = ( )
for x in " ${ voiceListFullName [@] } " ; do
2022-08-23 13:19:52 -04:00
voiceList += ( " $( echo " $x " | $sed -E -e 's/Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\(.+)/\3/g' ) " )
2020-09-20 14:31:11 -04:00
done
2022-08-23 12:56:20 -04:00
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' ) "
2020-09-20 14:31:11 -04:00
exit = 1
2022-12-06 01:15:23 -05:00
if [ [ " ${# voiceList [@] } " -eq 0 ] ] ; then
2022-08-24 12:08:16 -04:00
dialog --msgbox "No voices found." -1 -1
exit 1
fi
2020-09-20 14:31:11 -04:00
while [ [ $exit -ne 0 ] ] ; do
2020-11-20 20:10:28 -05:00
voice = " $( menulist " ${ voiceList [@] } " ) "
2020-09-20 14:31:11 -04:00
case $? in
0)
2020-10-04 12:27:36 -04:00
set_voice " $voice " " $1 " ; exit = 0 ; ;
2020-09-20 14:31:11 -04:00
3)
test_voice " $voice " ; ;
*)
restore_voice ; exit = 0 ; ;
esac
done
exit 0