Make it easy to configure the default voice for wine prefixes.
This commit is contained in:
		
							
								
								
									
										162
									
								
								set-voice.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										162
									
								
								set-voice.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,162 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # Set Voice | ||||||
|  | # Set the default wine voice based on installed options. | ||||||
|  | # | ||||||
|  | # Copyright 2020, Storm Dragon, <storm_dragon@linux-a11y.org> | ||||||
|  | # | ||||||
|  | # This is free software; you can redistribute it and/or modify it under the | ||||||
|  | # terms of the GNU General Public License as published by the Free | ||||||
|  | # Software Foundation; either version 3, or (at your option) any later | ||||||
|  | # version. | ||||||
|  | # | ||||||
|  | # This software is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  | # General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this package; see the file COPYING.  If not, write to the Free | ||||||
|  | # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||||
|  | # 02110-1301, USA. | ||||||
|  | # | ||||||
|  | #--code-- | ||||||
|  |  | ||||||
|  | # Settings to improve accessibility of dialog. | ||||||
|  | export DIALOGOPTS='--insecure --no-lines --visit-items' | ||||||
|  |  | ||||||
|  | # Get the desired wine bottle | ||||||
|  |  | ||||||
|  | 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)" | ||||||
|  |                                                                                                                                                                            | ||||||
|  | if [[ -z "${WINEPREFIX}" ]]; then | ||||||
|  |     exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo "wineprefix = $WINEPREFIX" | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  |     dialog --backtitle "$(gettext "Use the up and down arrow keys to find the option you want, then press enter to select it.")" \ | ||||||
|  |         --clear \ | ||||||
|  |         --extra-button \ | ||||||
|  |         --extra-label "$(gettext "Test Voice")" \ | ||||||
|  |         --no-tags \ | ||||||
|  |         --menu "$(gettext "Please select one")" 0 0 0 "${menuList[@]}" --stdout | ||||||
|  |     return $? | ||||||
|  | } | ||||||
|  |  | ||||||
|  | restore_voice() { | ||||||
|  |     if [[ $doRestore -eq 0 ]]; then | ||||||
|  |         wineserver -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely | ||||||
|  |         sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Tokens\\\\[^"]+"/"DefaultTokenId"="'"${oldVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg" | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | set_voice() { | ||||||
|  |     doRestore=1 | ||||||
|  |     local tmp="$1" | ||||||
|  |     local fullVoice | ||||||
|  |     local counter=0 | ||||||
|  |     for x in ${voiceList[@]} ; do | ||||||
|  |         [ "$x" = "$tmp" ] && break | ||||||
|  |         counter=$(( $counter + 1 )) | ||||||
|  |     done | ||||||
|  |     fullVoice=${voiceListFullName[$counter]} | ||||||
|  |     wineserver -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely | ||||||
|  |     sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Tokens\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | test_voice() { | ||||||
|  |     doRestore=0 | ||||||
|  |     local tmp="$1" | ||||||
|  |     local fullVoice | ||||||
|  |     local counter=0 | ||||||
|  |     for x in ${voiceList[@]} ; do | ||||||
|  |         [ "$x" = "$tmp" ] && break | ||||||
|  |         counter=$(( $counter + 1 )) | ||||||
|  |     done | ||||||
|  |     fullVoice=${voiceListFullName[$counter]} | ||||||
|  |     wineserver -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely | ||||||
|  |     sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Tokens\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg" | ||||||
|  |     cat << "EOF" > /tmp/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 "z:\tmp\speak.vbs" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Handle voice restore, but only if voice changed | ||||||
|  | doRestore=1 | ||||||
|  | trap restore_voice SIGINT | ||||||
|  |  | ||||||
|  | # Create an array of available voices. | ||||||
|  | ifs="$IFS" | ||||||
|  | IFS=$'\n' | ||||||
|  | voiceListFullName=($(grep -P '\[Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Tokens\\\\[^\\]+\].*' "${WINEPREFIX}/system.reg" | sed -E -e 's/\[([^]]+)\].*/\1/g')) | ||||||
|  | IFS="$ifs" | ||||||
|  | voiceList=() | ||||||
|  | for x in "${voiceListFullName[@]}" ; do | ||||||
|  |     voiceList+=("$(echo "$x" | rev | cut -d\\ -f1 | rev)") | ||||||
|  | done | ||||||
|  | oldVoice="$(grep -P '"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Tokens\\\\[^"]+"' "${WINEPREFIX}/user.reg" | sed -E -e 's/"DefaultTokenId"="([^"]+)"/\1/g')" | ||||||
|  | echo "oldVoice: ${oldVoice}" | ||||||
|  | echo "voiceList: ${voiceList[@]}" | ||||||
|  | echo "voiceListFullName: ${voiceListFullName[@]}" | ||||||
|  | #exit 1 | ||||||
|  | exit=1 | ||||||
|  | while [[ $exit -ne 0 ]] ; do | ||||||
|  | voice="$(menulist ${voiceList[@]})" | ||||||
|  |  | ||||||
|  | case $? in | ||||||
|  |     0) | ||||||
|  |             set_voice "$voice" ; exit=0 ;; | ||||||
|  |     3) | ||||||
|  |             test_voice "$voice";; | ||||||
|  |     *) | ||||||
|  |             restore_voice ; exit=0 ;; | ||||||
|  | esac | ||||||
|  | done | ||||||
|  |  | ||||||
|  | exit 0 | ||||||
		Reference in New Issue
	
	Block a user