I use audio/rsynth from pkgsrc with the nasd (network audio system daemon). The defaults are kind of odd for the GUI, so you might want to try the settings in the screenshot. Have fun! package require Tk
proc say {sentence r_var d_var f_var F_var ff_var bf_var} {
#This invokes say from the rsynth package.
#puts $ff_var
if {[string length $ff_var] == 2} {
set k_var ".$ff_var"
} elseif {[string length $ff_var] == 3} {
set k_var [string range $ff_var 0 0].[string range $ff_var 1 end]
} elseif {[string length $ff_var] == 1} {
set k_var ".0$ff_var"
} else {
set k_var 1.0
}
#puts $k_var
set go 1
set rpid ""
#This could use #open | so that it doesn't block the process.
catch {exec say -K $k_var -r $r_var -d $d_var -f $f_var -F $F_var -x $bf_var $sentence}
}
proc main {} {
pack [frame .f -relief groove -bd 4] -fill both
pack [frame .f.t] -fill x
pack [entry .f.t.e -textvariable sentence -width 30] -fill x
pack [button .f.say -text Say \
-command {say $sentence $r_var $d_var $f_var $F_var $ff_var $bf_var}] -fill x
bind . <Return> {.f.say invoke}
pack [frame .f.b -relief groove -bd 4] -fill both
pack [scale .f.b.r -from 2000 -to 8000 -variable r_var -orient horizontal \
-label "Sound Rate:" -tickinterval 1500] -fill x
.f.b.r set 5812
pack [label .f.b.dl -text "Dictionary:"]
foreach dict {a b} {
pack [radiobutton .f.b.d$dict -variable d_var -value $dict \
-text $dict]
}
.f.b.db select
pack [scale .f.b.bf -from 0 -to 6000 -variable bf_var -orient horizontal \
-label "Base Frequency:"] -fill x
.f.b.bf set 2365
pack [scale .f.b.fr -from 0 -to 100 -variable f_var -orient horizontal \
-label "mSec per Frame:" -tickinterval 20] -fill x
.f.b.fr set 12
pack [scale .f.b.f -from 0 -to 400 -variable F_var -orient horizontal \
-label "Flutter Rate:" -tickinterval 100] -fill x
.f.b.f set 0
#Filter Fraction
pack [scale .f.b.ff -from 0 -to 200 -variable ff_var -orient horizontal \
-label "Parameter Filter Fraction:" -tickinterval 40] -fill x
.f.b.ff set 79
}
mainCategory Speech Synthesis

