VOX: apply rate/pitch as vendor tags (NetTTS-style); full profile in both hives; docs
This commit is contained in:
+80
-23
@@ -159,19 +159,38 @@ if [ -f "$TEXTFILE" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build the engine arguments from the (possibly command-overridden) speed/pitch.
|
||||
# Build the engine controls from the (possibly command-overridden) speed/pitch.
|
||||
# Flextalk voices take sticky vendor tags relative to the registry profile, the
|
||||
# way NetTTS does it: \!R is a duration factor (smaller = faster, 1.0 neutral)
|
||||
# and \!% is a pitch multiplier (1.0 neutral). ITTSAttributes -s/-p would
|
||||
# override the profile and make presets sound fast and shallow, so tags are used
|
||||
# for Flextalk. MSTTS has no vendor tags and keeps -s/-p.
|
||||
SET_ARGS=""
|
||||
if [ -n "$SPEED" ]; then
|
||||
S=$(awk -v m="$SPEED" 'BEGIN{printf "%d", 150*m+0.5}')
|
||||
[ "$S" -lt 50 ] && S=50
|
||||
[ "$S" -gt "$SMAX" ] && S=$SMAX
|
||||
SET_ARGS="$SET_ARGS -s $S"
|
||||
fi
|
||||
if [ -n "$PITCH" ]; then
|
||||
P=$(awk -v st="$PITCH" -v nat="$NAT_PITCH" 'BEGIN{printf "%d", nat*exp(log(2)*st/12)+0.5}')
|
||||
[ "$P" -lt 50 ] && P=50
|
||||
[ "$P" -gt "$PMAX" ] && P=$PMAX
|
||||
SET_ARGS="$SET_ARGS -p $P"
|
||||
TAG_PREFIX=""
|
||||
if [ -n "$SPEAKER_GUID" ]; then
|
||||
if [ -n "$SPEED" ]; then
|
||||
# A neutral multiplier must not emit a tag: \!R1.00 means a 1.0x rate,
|
||||
# which would override the profile's own speaking rate.
|
||||
R=$(awk -v m="$SPEED" 'BEGIN{ if (m<=0) m=1; if (m==1) { exit } f=1/m; if (f<0.25) f=0.25; if (f>4) f=4; printf "%.2f", f }')
|
||||
[ -n "$R" ] && TAG_PREFIX="$TAG_PREFIX\\!R$R "
|
||||
fi
|
||||
if [ -n "$PITCH" ]; then
|
||||
PCT=$(awk -v st="$PITCH" 'BEGIN{ if (st==0) { exit } f=exp(log(2)*st/12); if (f<0.5) f=0.5; if (f>2) f=2; printf "%.2f", f }')
|
||||
[ -n "$PCT" ] && TAG_PREFIX="$TAG_PREFIX\\!%$PCT "
|
||||
fi
|
||||
else
|
||||
if [ -n "$SPEED" ]; then
|
||||
S=$(awk -v m="$SPEED" 'BEGIN{printf "%d", 150*m+0.5}')
|
||||
[ "$S" -lt 50 ] && S=50
|
||||
[ "$S" -gt "$SMAX" ] && S=$SMAX
|
||||
SET_ARGS="$SET_ARGS -s $S"
|
||||
fi
|
||||
if [ -n "$PITCH" ]; then
|
||||
P=$(awk -v st="$PITCH" -v nat="$NAT_PITCH" 'BEGIN{printf "%d", nat*exp(log(2)*st/12)+0.5}')
|
||||
[ "$P" -lt 50 ] && P=50
|
||||
[ "$P" -gt "$PMAX" ] && P=$PMAX
|
||||
SET_ARGS="$SET_ARGS -p $P"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Apply the Flextalk profile before synthesis. Profiles are read at voice load and
|
||||
@@ -244,19 +263,57 @@ if [ -n "$SPEAKER_GUID" ]; then
|
||||
esac
|
||||
done
|
||||
|
||||
REG_KEY="HKLM\\Software\\AT&T\\Watson\\2.0\\FlexTalk\\2.0\\Speakers\\$SPEAKER_GUID"
|
||||
# NetTTS's VOX profile also carries Gender, Line Mode, the text-class
|
||||
# switches and the default-speaker pointer. Write the full set for presets,
|
||||
# exactly like its nettts_flextalk_vox_profile.reg, in both hives.
|
||||
FULL_PROFILE=0
|
||||
if [ "$PRESET" = "vox" ] || [ "$PRESET" = "hev" ]; then
|
||||
if [ "$ENGVOICE" = "Keith Bell" ]; then FULL_PROFILE=1; fi
|
||||
fi
|
||||
|
||||
REG_ROOT='Software\AT&T\Watson\2.0\FlexTalk\2.0'
|
||||
# Use printf, not echo: dash's echo interprets \2 in the key path as an
|
||||
# escape (STX), which corrupts the key and makes the import a silent no-op.
|
||||
{
|
||||
printf 'Windows Registry Editor Version 5.00\n\n'
|
||||
printf '[%s]\n' "$REG_KEY"
|
||||
printf '"Pitch"=dword:%08x\n' "$P_PITCH"
|
||||
printf '"Speaking Rate"=dword:%08x\n' "$P_RATE"
|
||||
printf '"Volume"=dword:%08x\n' "$P_VOLUME"
|
||||
printf '"Expression"=dword:%08x\n' "$P_EXPR"
|
||||
printf '"Prominences"=dword:%08x\n' "$P_PROM"
|
||||
printf '"Head Size"=dword:%08x\n' "$P_HEAD"
|
||||
printf '"Lowering"=dword:%08x\n' "$P_LOWER"
|
||||
if [ "$FULL_PROFILE" = "1" ]; then
|
||||
printf '[HKEY_LOCAL_MACHINE\\%s]\n' "$REG_ROOT"
|
||||
printf '"Default Speaker"="%s"\n\n' "$SPEAKER_GUID"
|
||||
printf '[HKEY_CURRENT_USER\\%s]\n' "$REG_ROOT"
|
||||
printf '"Default Speaker"="%s"\n\n' "$SPEAKER_GUID"
|
||||
fi
|
||||
for hive in HKEY_LOCAL_MACHINE HKEY_CURRENT_USER; do
|
||||
printf '[%s\\%s\\Speakers\\%s]\n' "$hive" "$REG_ROOT" "$SPEAKER_GUID"
|
||||
printf '"Pitch"=dword:%08x\n' "$P_PITCH"
|
||||
printf '"Speaking Rate"=dword:%08x\n' "$P_RATE"
|
||||
printf '"Volume"=dword:%08x\n' "$P_VOLUME"
|
||||
printf '"Expression"=dword:%08x\n' "$P_EXPR"
|
||||
printf '"Prominences"=dword:%08x\n' "$P_PROM"
|
||||
printf '"Head Size"=dword:%08x\n' "$P_HEAD"
|
||||
printf '"Lowering"=dword:%08x\n' "$P_LOWER"
|
||||
if [ "$FULL_PROFILE" = "1" ]; then
|
||||
printf '"Abbreviation Expansion"=dword:00000001\n'
|
||||
printf '"Address Class"=dword:00000001\n'
|
||||
printf '"Age"=dword:0000001e\n'
|
||||
printf '"Alphabetic Hyphen"=dword:00000000\n'
|
||||
printf '"Case Significance"=dword:00000001\n'
|
||||
printf '"Date Class"=dword:00000001\n'
|
||||
printf '"Fraction Class"=dword:00000001\n'
|
||||
printf '"Gender"=dword:00000002\n'
|
||||
printf '"Line Mode"=dword:00000001\n'
|
||||
printf '"Math Mode"=dword:00000000\n'
|
||||
printf '"Measurements Class"=dword:00000001\n'
|
||||
printf '"Money Class"=dword:00000001\n'
|
||||
printf '"Numerical Hyphen"=dword:00000000\n'
|
||||
printf '"Ordinal Numbers Class"=dword:00000001\n'
|
||||
printf '"ProofRead Mode"=dword:00000000\n'
|
||||
printf '"Proper Names Class"=dword:00000001\n'
|
||||
printf '"Spell Mode"=dword:00000000\n'
|
||||
printf '"Telephone Numbers Class"=dword:00000001\n'
|
||||
printf '"Time Class"=dword:00000001\n'
|
||||
fi
|
||||
printf '\n'
|
||||
done
|
||||
} > "$TMP/profile.reg"
|
||||
|
||||
# Guard against silent reg-import failures (a malformed key would corrupt
|
||||
@@ -352,7 +409,7 @@ if [ "$WORDS" = "1" ] && [ -n "$SPEAKER_GUID" ] && [ "$VOX" != "1" ]; then
|
||||
INDEX=0
|
||||
for word in $(cat "$TXT"); do
|
||||
INDEX=$((INDEX + 1))
|
||||
try_run_host "$TMP/w$INDEX.wav" "$word"
|
||||
try_run_host "$TMP/w$INDEX.wav" "$TAG_PREFIX$word"
|
||||
echo "file '$TMP/w$INDEX.wav'" >> "$TMP/list.txt"
|
||||
|
||||
if [ "$GAP" -gt 0 ]; then
|
||||
@@ -370,7 +427,7 @@ if [ "$WORDS" = "1" ] && [ -n "$SPEAKER_GUID" ] && [ "$VOX" != "1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
try_run_host "$RAW" "$(cat "$TXT")"
|
||||
try_run_host "$RAW" "$TAG_PREFIX$(cat "$TXT")"
|
||||
fi
|
||||
[ -s "$RAW" ] || { echo "engine produced no audio" >&2; exit 1; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user