X-Git-Url: https://zdv2.bktei.com/gitweb/BK-2020-03.git/blobdiff_plain/a38d55c878b5366749b0ee21adffa47afc9c4271..75c5aa780fc104dfe4ad9e42d917078c89c5eca5:/unitproc/bkipas?ds=sidebyside diff --git a/unitproc/bkipas b/unitproc/bkipas new file mode 100644 index 0000000..0f23482 --- /dev/null +++ b/unitproc/bkipas @@ -0,0 +1,305 @@ +#!/bin/bash +# Desc: Convert IPA string into audio file + +#==BEGIN Define script parameters== +#===BEGIN Initialize variables=== + +# Script Metadata +scriptName="bkipas"; # Define basename of script file. +scriptVersion="0.1.0"; # Define version of script. +scriptTimeStart="$(date +%Y%m%dT%H%M%S.%N)"; # YYYYmmddTHHMMSS.NNNNNNNNN +scriptURL="https://zdv2.bktei.com/gitweb/baltakatei-exdev.git"; # Define website hosting this script. +scriptHostname=$(hostname); # Save hostname of system running this script. +PATH="$HOME/.local/bin:$PATH"; # Add "$(systemd-path user-binaries)" path in case user apps saved there + +# Arrays +declare -Ag appRollCall # Associative array for storing app status +declare -Ag fileRollCall # Associative array for storing file status +declare -Ag dirRollCall # Associative array for storing dir status + +# Variables +optionVerbose=""; optionOutputDir=""; optionInputString=""; argStrIn=""; argDirOut=""; pathOut=""; + +#===END Initialize variables=== +#===BEGIN Declare local script functions=== + + +# Initialize variables and functions +yell() { echo "$0: $*" >&2; } #o Yell, Die, Try Three-Fingered Claw technique +die() { yell "$*"; exit 111; } #o Ref/Attrib: https://stackoverflow.com/a/25515370 +try() { "$@" || die "cannot $*"; } #o +vbm() { + # Description: Prints verbose message ("vbm") to stderr if optionVerbose is set to "true". + # Usage: vbm "DEBUG :verbose message here" + # Version 0.1.3 + # Input: arg1: string + # vars: optionVerbose + # Output: stderr + # Depends: bash 5.0.3, echo 8.30, date 8.30 + + if [ "$optionVerbose" = "true" ]; then + functionTime=$(date --iso-8601=ns); # Save current time in nano seconds. + echo "[$functionTime]:$0:""$*" 1>&2; # Display argument text. + fi + + # End function + return 0; # Function finished. +} # Displays message if optionVerbose true +processArguments() { + while [ ! $# -eq 0 ]; do # While number of arguments ($#) is not (!) equal to (-eq) zero (0). + case "$1" in + -v | --verbose) optionVerbose="true"; vbm "DEBUG :Verbose mode enabled.";; # Enable verbose mode. + -h | --help) showUsage; exit 1;; # Display usage. + --version) showVersion; exit 1;; # Show version. + -i | --input-string) optionInputString="true"; if [[ ! -z "$2" ]]; then argStrIn="$2"; vbm "DEBUG :argStrIn:$argStrIn"; shift; fi ;; # Identify input string. + -o | --output-dir) optionOutputDir="true"; if [[ -d "$2" ]]; then argDirOut="$2"; vbm "DEBUG :argDirOut:$argDirOut"; shift; fi ;; # Define output directory. + *) yell "ERROR: Unrecognized argument: $1"; yell "STATUS:All arguments:$*"; exit 1;; # Handle unrecognized options. + esac + shift + done +} # Argument Processing +checkapp() { + # Desc: If arg is a command, save result in assoc array 'appRollCall' + # Usage: checkapp arg1 arg2 arg3 ... + # Version: 0.1.1 + # Input: global assoc. array 'appRollCall' + # Output: adds/updates key(value) to global assoc array 'appRollCall' + # Depends: bash 5.0.3 + local returnState + + #===Process Args=== + for arg in "$@"; do + if command -v "$arg" 1>/dev/null 2>&1; then # Check if arg is a valid command + appRollCall[$arg]="true"; + if ! [ "$returnState" = "false" ]; then returnState="true"; fi; + else + appRollCall[$arg]="false"; returnState="false"; + fi; + done; + + #===Determine function return code=== + if [ "$returnState" = "true" ]; then + return 0; + else + return 1; + fi; +} # Check that app exists +checkfile() { + # Desc: If arg is a file path, save result in assoc array 'fileRollCall' + # Usage: checkfile arg1 arg2 arg3 ... + # Version: 0.1.1 + # Input: global assoc. array 'fileRollCall' + # Output: adds/updates key(value) to global assoc array 'fileRollCall'; + # Output: returns 0 if app found, 1 otherwise + # Depends: bash 5.0.3 + local returnState + + #===Process Args=== + for arg in "$@"; do + if [ -f "$arg" ]; then + fileRollCall["$arg"]="true"; + if ! [ "$returnState" = "false" ]; then returnState="true"; fi; + else + fileRollCall["$arg"]="false"; returnState="false"; + fi; + done; + + #===Determine function return code=== + if [ "$returnState" = "true" ]; then + return 0; + else + return 1; + fi; +} # Check that file exists +checkdir() { + # Desc: If arg is a dir path, save result in assoc array 'dirRollCall' + # Usage: checkdir arg1 arg2 arg3 ... + # Version 0.1.1 + # Input: global assoc. array 'dirRollCall' + # Output: adds/updates key(value) to global assoc array 'dirRollCall'; + # Output: returns 0 if app found, 1 otherwise + # Depends: Bash 5.0.3 + local returnState + + #===Process Args=== + for arg in "$@"; do + if [ -d "$arg" ]; then + dirRollCall["$arg"]="true"; + if ! [ "$returnState" = "false" ]; then returnState="true"; fi + else + dirRollCall["$arg"]="false"; returnState="false"; + fi + done + + #===Determine function return code=== + if [ "$returnState" = "true" ]; then + return 0; + else + return 1; + fi +} # Check that dir exists +displayMissing() { + # Desc: Displays missing apps, files, and dirs + # Usage: displayMissing + # Version 0.1.1 + # Input: associative arrays: appRollCall, fileRollCall, dirRollCall + # Output: stderr: messages indicating missing apps, file, or dirs + # Depends: bash 5, checkAppFileDir() + local missingApps value appMissing missingFiles fileMissing + local missingDirs dirMissing + + #==BEGIN Display errors== + #===BEGIN Display Missing Apps=== + missingApps="Missing apps :"; + #for key in "${!appRollCall[@]}"; do echo "DEBUG :$key => ${appRollCall[$key]}"; done + for key in "${!appRollCall[@]}"; do + value="${appRollCall[$key]}"; + if [ "$value" = "false" ]; then + #echo "DEBUG :Missing apps: $key => $value"; + missingApps="$missingApps""$key "; + appMissing="true"; + fi; + done; + if [ "$appMissing" = "true" ]; then # Only indicate if an app is missing. + echo "$missingApps" 1>&2; + fi; + unset value; + #===END Display Missing Apps=== + + #===BEGIN Display Missing Files=== + missingFiles="Missing files:"; + #for key in "${!fileRollCall[@]}"; do echo "DEBUG :$key => ${fileRollCall[$key]}"; done + for key in "${!fileRollCall[@]}"; do + value="${fileRollCall[$key]}"; + if [ "$value" = "false" ]; then + #echo "DEBUG :Missing files: $key => $value"; + missingFiles="$missingFiles""$key "; + fileMissing="true"; + fi; + done; + if [ "$fileMissing" = "true" ]; then # Only indicate if an app is missing. + echo "$missingFiles" 1>&2; + fi; + unset value; + #===END Display Missing Files=== + + #===BEGIN Display Missing Directories=== + missingDirs="Missing dirs:"; + #for key in "${!dirRollCall[@]}"; do echo "DEBUG :$key => ${dirRollCall[$key]}"; done + for key in "${!dirRollCall[@]}"; do + value="${dirRollCall[$key]}"; + if [ "$value" = "false" ]; then + #echo "DEBUG :Missing dirs: $key => $value"; + missingDirs="$missingDirs""$key "; + dirMissing="true"; + fi; + done; + if [ "$dirMissing" = "true" ]; then # Only indicate if an dir is missing. + echo "$missingDirs" 1>&2; + fi; + unset value; + #===END Display Missing Directories=== + + #==END Display errors== +} # Display missing apps, files, dirs +showVersion() { + yell "$scriptVersion" + cat <<'EOF' +Copyright (C) 2020 Steven Baltakatei Sandoval +License GPLv3: GNU GPL version 3 +This is free software; you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + + lexconvert (https://github.com/ssb22/lexconvert commit 64a4837) + Copyright (C) 2020 Silas S. Brown + License GPLv3: GNU GPL version 3 +EOF +} # Display script version. +showUsage() { + cat <<'EOF' + USAGE: + bkipas [ options ] + + OPTIONS: + -h, --help + Display help information. + --version + Display script version. + -v, --verbose + Display debugging info. + -i, --input-string [ str input ] + Specify input IPA string. + -o, --output-dir [ path dir ] + Specify output directory path. + + EXAMPLES: + bkipas -i "təˈmeɪtoʊ" # same as: echo "[[t@'meItoU]]" | espeak + bkipas -i "təˈmeɪtoʊ" -o /tmp/ +EOF +} # Display information on how to use this script. + +main() { + # Desc: Main function + # Usage: main "$@" + # Inputs: many + # Outputs: file (pathout_tar) + # Depends: many + + # Debug:Get function name + fn="${FUNCNAME[0]}"; + + vbm "STATUS:$fn:Started function main()."; + # Process arguments + processArguments "$@"; + + # Specify expected lexconvert.py path + pathLexConvert="./bkipas.d/lexconvert.py" && vbm "DEBUG :$fn:pathLexConvert:$pathLexConvert"; + ## Note: lexconvert.py converts IPA into eSpeak phoneme mneumonics + ## See https://github.com/ssb22/lexconvert + ## See https://github.com/espeak-ng/espeak-ng/issues/539#issuecomment-536192362 + + # Check vital apps, files, dirs + if ! checkapp sed python3 espeak oggenc && ! checkfile "$pathLexConvert"; then + yell "ERROR:$fn:Critical components missing."; + displayMissing; yell "Exiting."; exit 1; fi; + + # Process input string + ## Remove '/' + strIn="$(echo "$argStrIn" | sed 's/\///g')"; + ## Check for empty string + if [[ -z "$strIn" ]]; then yell "ERROR:No IPA string provided."; exit 1; fi; + + # Determine output file name + if [[ "$optionOutputDir" = "true" ]]; then + #pathOut="$argDirOut/$scriptTimeStart".ogg && vbm "DEBUG :$fn:pathOut:$pathOut"; + pathOut="$argDirOut/$strIn".ogg && vbm "DEBUG :$fn:pathOut:$pathOut"; + else + #pathOut="$(pwd)/$scriptTimeStart".ogg && vbm "DEBUG :$fn:pathOut:$pathOut"; + pathOut="$(pwd)/$strIn".ogg && vbm "DEBUG :$fn:pathOut:$pathOut"; + fi; + + # Generate espeak phoneme mneumonic + espeakInput="$(python3 "$pathLexConvert" --phones2phones unicode-ipa espeak "$strIn")" && vbm "DEBUG :$fn:espeakInput:$espeakInput"; + + # Output pronunciation + if [[ "$optionOutputDir" = "true" ]]; then + ## Write to file if -o specified + echo "$espeakInput" | espeak --stdout | oggenc -o "$pathOut" - ; + else + ## Speak pronunciation via espeak + echo "$espeakInput" | espeak ; + fi; + +} # Main function + +#===END Declare local script functions=== +#==END Define script parameters== + +#==BEGIN Perform work and exit== +main "$@" # Run main function. +exit 0; +#==END Perform work and exit== + +# Author: Steven Baltakatei Sandoval; +# License: GPLv3 +