2 # the next line restarts using wish \
5 #tk_messageBox -message "Start"
7 package require
-exact snack
2.2
9 set currentDirectory
[pwd]
11 # Button and Label texts
12 set ExampleTxt
"Example"
13 set NextTxt
"Next sound"
14 set PinyinTxt
"Pinyin"
21 set FemaleTxt
"Female"
24 set SubmitTxt
"Submit"
27 set CorrectTxt
"Correct"
28 set InvalidTxt
"Invalid"
29 set TooLowTxt
"You speak too low"
30 set TooHighTxt
"You speak too high"
31 set TooWideTxt
"Your range is too wide"
32 set TooNarrowTxt
"Your range is too narrow"
33 set WordListTitleTxt
"Open a pinyin word list (one word per line)"
38 set pinyin
"duo1shao3"
39 set ExamplePinyin
$pinyin
41 set StandardWordList
"SGC_protWordList.txt"
43 # This list gets the files path as the second argument in the WordList file
44 # It will force recognition of these files for debugging
47 set logPerf
$standardlogPerf
49 if {[file readable
$currentDirectory/lastResult.txt
]} {
50 set fileID
[open
$currentDirectory/lastResult.txt
{RDONLY
}]
51 gets
$fileID lastResult
53 set pinyin
[lindex
$lastResult 1]
54 set ExamplePinyin
$pinyin
55 set register
[lindex
$lastResult 6]
56 if {$register < 50 ||
$register > 900} {
62 proc ReadWordList
{filename
} {
65 global currentSoundFileName
66 global currentExampleFileName
72 if {[file readable
$filename]} {
76 set f
[open
$filename]
77 foreach line
[split [read $f] \n] {
78 if {[string length
$line]} {
80 if {[llength
$line] > 3} {
82 if {[regexp
"logFile\.txt" $filename]} {set directory
"log/"}
83 set line
"[lindex $line 1] $directory[lindex $line end]"
85 # Also store any file names
86 if {[llength
$line] > 1} {
87 lappend AutoFileList
[lindex
$line 1]
89 lappend WordList
[lindex
$line 0]
93 if {[llength
$AutoFileList] > 0} {
97 # Pick first random word
98 if {[llength
$WordList] > 0} {
99 set i
[expr {int
(rand
()*[llength
$WordList])}]
100 set pinyin
[lindex
$WordList $i]
101 if {[llength
$AutoFileList] > 0} {
102 set currentSoundFileName
[lindex
$AutoFileList $i]
103 set currentExampleFileName
$currentSoundFileName
104 set ExamplePinyin
$pinyin
105 s configure
-file $currentSoundFileName
106 SetTime
[s length
-unit sec
]
107 .fa.b1 configure
-text "$NextTxt"
113 ReadWordList
"$currentDirectory/$StandardWordList"
115 # Where to find the files
116 set standardSoundFileName
"currentSound.wav"
117 set currentSoundFileName
$standardSoundFileName
118 set standardExampleFileName
"lastExample.wav"
119 set currentExampleFileName
$standardExampleFileName
121 set Platform
$tcl_platform(os
)
123 # Platform dependend commands
126 set PraatCommand
"./praatLinux"
127 set SendPraatCommand
"./sendpraatLinux"
129 set PraatName
"praatLinux"
132 set PraatCommand
"./praatMac"
133 set SendPraatCommand
"./sendpraatMac"
135 set PraatName
"praatMac"
141 set PraatCommand
"$currentDirectory/praatWin.exe"
142 set SendPraatCommand
"$currentDirectory/sendpraatWin.exe"
143 set PraatName
"Praat"
149 # (watch out for trailing spaces)
150 set QuitCommand
[list
exec $SendPraatCommand "$PraatName" "Quit" "&"]
151 if {$TimeOut > 0} {set QuitCommand
[linsert
$QuitCommand 2 $TimeOut]}
152 set PlayExampleCommand
[list
exec $SendPraatCommand "$PraatName" "Read from file... \$currentDirectory/\$currentExampleFileName" "Play" "Remove" "&"]
153 if {$TimeOut > 0} {set PlayExampleCommand
[linsert
$PlayExampleCommand 2 $TimeOut]}
154 set HumToneCommand
[list
exec $SendPraatCommand "$PraatName" {execute
"$currentDirectory/HumToneContour.praat" $pinyin $register} "&"]
155 if {$TimeOut > 0} {set HumToneCommand
[linsert
$HumToneCommand 2 $TimeOut]}
156 set ShowToneCommand
[list
exec $SendPraatCommand "$PraatName" {execute
"$currentDirectory/DrawToneContour.praat" $pinyin $register} "&"]
157 if {$TimeOut > 0} {set ShowToneCommand
[linsert
$ShowToneCommand 2 $TimeOut]}
158 set RecognizeCommand
[list
exec $SendPraatCommand "$PraatName" {execute
"$currentDirectory/SGC_ToneProt.praat" "$currentDirectory/$currentSoundFileName" $pinyin $register $precision Hum
$logPerf} ]
159 if {$TimeOut > 0} {set RecognizeCommand
[linsert
$RecognizeCommand 2 $TimeOut]}
161 exec "$PraatCommand" "&"
163 # Start of Audio SNACK stuff
164 file delete _tmprec.wav
165 snack
::sound t
-debug 0
167 snack
::sound s
-file _tmprec.wav
-debug 0
171 $m add cascade
-label File
-menu $m.
file -underline 0
172 menu
$m.
file -tearoff 0
173 $m.
file add
command -label "Open..." -command [list OpenSound
]
174 $m.
file add
command -label "Save As..." -command [list SaveSound
]
175 $m.
file add
command -label "$QuitTxt" -command Destroy
177 $m add cascade
-label Audio
-menu $m.audio
-underline 0
178 menu
$m.audio
-tearoff 0
179 $m.audio add
command -label "Settings..." -command Settings
180 $m.audio add
command -label "Mixer..." -command snack
::mixerDialog
182 $m add cascade
-label Tools
-menu $m.tools
-underline 0
183 menu
$m.tools
-tearoff 0
184 $m.tools add
command -label "Replay" -command ReplayLogFile
185 $m.tools add
command -label "Open word list..." -command GetWordList
186 $m.tools add
command -label "Close word list" -command CloseWordList
191 pack
[frame .fa
] -pady 5
192 button .fa.b1
-text "$ExampleTxt" -command PlayExample
193 button .fa.b2
-text "$ShowTxt" -command ShowTone
194 label .fa.l1
-text "$PinyinTxt:"
195 entry .fa.e1
-width 12 -relief sunken
-bd 2 -textvariable pinyin
196 button .fa.b3
-text "$ClearTxt" -command {set pinyin
""}
197 button .fa.b4
-text "$QuitTxt" -command Destroy
198 pack .fa.b1 .fa.b2 .fa.l1 .fa.e1 .fa.b3 .fa.b4
-side left
200 pack
[frame .fb
] -pady 5
201 label .fb.l1
-text "$T1Txt:"
202 entry .fb.e1
-width 4 -relief sunken
-bd 2 -textvariable register
203 label .fb.l2
-text "$HzTxt"
204 radiobutton .fb.r1
-text "$FemaleTxt" -variable register
-value 300
205 radiobutton .fb.r2
-text "$MaleTxt" -variable register
-value 200
206 radiobutton .fb.r3
-text "$ChildTxt" -variable register
-value 450
207 pack .fb.l1 .fb.e1 .fb.l2 .fb.r1 .fb.r2 .fb.r3
-side left
212 pack
[frame .f1
] -pady 5
213 button .f1.bp
-bitmap snackPlay
-command Play
214 button .f1.bu
-bitmap snackPause
-command Pause
215 button .f1.bs
-bitmap snackStop
-command Stop
216 button .f1.br
-bitmap snackRecord
-command Record
-fg red
217 button .f1.b1
-text "$SubmitTxt" -command Recognize
218 pack .f1.bp .f1.bu .f1.bs .f1.br .f1.b1
-side left
220 pack
[frame .f2
] -pady 5
221 label .f2.
time -text "00:00.0" -width 10
222 snack
::levelMeter .f2.lm
223 pack .f2.
time .f2.lm
-side left
225 pack
[frame .f5
] -pady 5
226 label .f5.l1
-text "-------"
227 pack .f5.l1
-side left
229 pack
[frame .f6
] -pady 5
230 label .f6.l1
-text ""
231 pack .f6.l1
-side left
234 wm protocol . WM_DELETE_WINDOW Destroy
236 # Procedure definitions
239 set filename
[snack
::getOpenFile
]
240 s configure
-file $filename
241 SetTime
[s length
-unit sec
]
245 set filename
[snack
::getSaveFile
]
250 set ::s
(rate
) [s cget
-rate]
251 set ::s
(enc
) [s cget
-encoding]
252 set ::s
(chan
) [s cget
-channels]
260 pack
$w.q
-expand 1 -fill both
-side top
261 pack
[frame
$w.q.f1
] -side left
-anchor nw
-padx 3m
-pady 2m
262 pack
[frame
$w.q.f2
] -side left
-anchor nw
-padx 3m
-pady 2m
263 pack
[frame
$w.q.f3
] -side left
-anchor nw
-padx 3m
-pady 2m
264 pack
[frame
$w.q.f4
] -side left
-anchor nw
-padx 3m
-pady 2m
265 pack
[label
$w.q.f1.l
-text "Sample Rate"]
266 foreach e
[snack
::audio rates
] {
267 pack
[radiobutton
$w.q.f1.r
$e -text $e -value $e -variable ::s
(rate
)] \
270 pack
[entry
$w.q.f1.e
-textvariable ::s
(rate
) -width 6] -anchor w
271 pack
[label
$w.q.f2.l
-text "Sample Encoding"]
272 foreach e
[snack
::audio encodings
] {
273 pack
[radiobutton
$w.q.f2.r
$e -text $e -value $e -variable ::s
(enc
)] \
276 pack
[label
$w.q.f3.l
-text Channels
]
277 pack
[radiobutton
$w.q.f3.1
-text Mono
-value 1 -variable ::s
(chan
)] -anchor w
278 pack
[radiobutton
$w.q.f3.2
-text Stereo
-value 2 -variable ::s
(chan
)] \
280 pack
[entry
$w.q.f3.e
-textvariable ::s
(chan
) -width 3] -anchor w
283 pack
[ button
$w.f3.b1
-text OK
-width 6 \
284 -command "ApplySettings;destroy $w"] -side left
285 pack
[ button
$w.f3.b2
-text Cancel
-command "destroy $w"] -side left
288 proc ApplySettings
{} {
290 s configure
-rate $
::s
(rate
) -channels $
::s
(chan
) -encoding $
::s
(enc
)
291 t configure
-rate $
::s
(rate
) -channels $
::s
(chan
) -encoding $
::s
(enc
)
293 s configure
-file _tmprec.wav
297 set mmss
[clock format
[expr int
($t)] -format "%M:%S"]
298 .f2.
time config
-text $mmss.
[format
"%d" [expr int
(10*($t-int($t)))]]
303 set t
[audio elapsed
]
304 set end
[expr int
([s cget
-rate] * $t)]
305 set start
[expr $end - [s cget
-rate] / 10]
306 if {$start < 0} { set start
0}
307 if {$end >= [s length
]} { set end
-1 }
308 set l
[s max
-start $start -end $end]
312 set t
[s length
-unit sec
]
315 .f2.lm configure
-level $l
322 s configure
-file _tmprec.wav
326 .f1.bp configure
-relief raised
327 .f1.br configure
-relief groove
333 proc GetWordList
{} {
334 global WordListTitleTxt
336 set filename
[tk_getOpenFile
-title "$WordListTitleTxt"]
337 ReadWordList
"$filename"
340 proc ReplayLogFile
{} {
341 ReadWordList
"logFile.txt"
344 proc CloseWordList
{} {
347 global currentSoundFileName
348 global standardSoundFileName
349 global currentExampleFileName
350 global standardExampleFileName
352 global standardlogPerf
357 set currentSoundFileName
$standardSoundFileName
358 set currentExampleFileName
$standardExampleFileName
359 set logPerf
$standardlogPerf
361 .fa.b1 configure
-text "$ExampleTxt"
365 global currentSoundFileName
366 global currentExampleFileName
372 global RecognizeCommand
373 global currentDirectory
383 # Stop any recording etc
387 set Evaluation
"---------"
389 set currentDirectory
[pwd]
390 eval [subst
$RecognizeCommand]
392 set ExamplePinyin
$pinyin
393 set fileID
[open
$currentDirectory/lastResult.txt
{RDONLY
}]
394 gets
$fileID lastResult
396 set Recognition
[regsub
-all {6} [lindex
$lastResult 2] {?
}]
398 set feedbackID
[open
$currentDirectory/feedback.txt
{RDONLY
}]
399 gets
$feedbackID lastFeedback
402 if {[lindex
$lastResult 0] == "Correct:"} {
403 set Evaluation
$CorrectTxt
404 set textColor
{dark green
}
405 set lastFeedback
"----"
407 set Evaluation
$WrongTxt
408 set textColor
{dark red
}
411 switch
[lindex
$lastResult 7] {
412 "High" {set height
$TooHighTxt}
413 "Low" {set height
$TooLowTxt}
414 default
{set height
""}
416 switch
[lindex
$lastResult 8] {
417 "Wide" {set range
$TooWideTxt}
418 "Narrow" {set range
$TooNarrowTxt}
419 default
{set range
""}
422 # Skip result if spoken at wrong pitch and incorrect
423 if {([lindex
$lastResult 7] != "Low" && [lindex
$lastResult 7] != "Narrow") ||
[lindex
$lastResult 0] != "Wrong:"} {
424 .f5.l1 configure
-fg "$textColor" -text "$pinyin => $Evaluation: $Recognition"
426 .f5.l1 configure
-fg "$textColor" -text "$pinyin"
428 .f6.l1 configure
-fg "$textColor" -text "$lastFeedback"
430 if {[llength
$WordList] > 0} {
431 set i
[expr {int
(rand
()*[llength
$WordList])}]
432 set pinyin
[lindex
$WordList $i]
433 if {[llength
$AutoFileList] > 0} {
434 set currentSoundFileName
[lindex
$AutoFileList $i]
435 set currentExampleFileName
$currentSoundFileName
436 set ExamplePinyin
$pinyin
437 s configure
-file $currentSoundFileName
438 SetTime
[s length
-unit sec
]
446 eval [subst
$QuitCommand]
450 proc PlayExample
{} {
451 global currentExampleFileName
452 global currentSoundFileName
453 global PlayExampleCommand
454 global HumToneCommand
458 global currentDirectory
459 # Stop any recording etc
462 set currentDirectory
[pwd]
464 if {$ExamplePinyin == $pinyin} {
465 eval [subst
$PlayExampleCommand]
467 eval [subst
$HumToneCommand]
473 global ShowToneCommand
476 global currentDirectory
477 # Stop any recording etc
480 set currentDirectory
[pwd]
481 eval [subst
$ShowToneCommand]
492 .f1.bp configure
-relief groove
493 .f1.br configure
-relief raised
494 .f1.bu configure
-relief raised
501 .f1.bp configure
-relief raised
502 .f1.br configure
-relief raised
503 .f1.bu configure
-relief raised
506 if {$RecordedSound == 1} {
507 global standardSoundFileName
508 s
write $standardSoundFileName
517 if {[.f1.bu cget
-relief] == "raised"} {
518 .f1.bu configure
-relief groove
520 .f1.bu configure
-relief raised