3 # Construct all tone patterns and look for the one closest to the given one
\r
6 procedure FreeToneRecognition pinyin$ test_word$ exclude$ upperRegister freqRange durScale
\r
9 pinyin$ = replace_regex$(pinyin$, "^\s*(.+)\s*$", "\1", 1)
\r
10 pinyin$ = replace_regex$(pinyin$, "5", "0", 0)
\r
13 referenceFrequency = 300
\r
14 frequencyFactor = referenceFrequency / upperRegister
\r
16 referenceExt$ = "pitch"
\r
18 # Bias Z-normalized value of the distance difference between smallest and correct
\r
22 keepIntermediates = 0
\r
25 # Generate reference tones
\r
26 execute ToneScript.praat 'pinyin$' 'upperRegister' 'freqRange' 'durScale' Pitch
\r
28 # Convert input to Pitch
\r
29 if test_word$ <> "" and test_word$ <> "REUSEPITCH"
\r
30 Read from file... 'test_word$'
\r
33 if test_word$ <> "REUSEPITCH"
\r
35 noprogress To Pitch (ac)... 0 60 15 yes 0.1 0.45 0.01 0.5 0.3 600
\r
36 # To Pitch... 0.0 60.0 600.0
\r
37 Formula... self*'frequencyFactor'; Normalize Pitch
\r
38 Rename... SourcePitch
\r
40 select Pitch SourcePitch
\r
45 correctDistance = -1
\r
47 smallestDistance=999999
\r
48 choiceReference$ = "empty"
\r
49 select Table ToneList
\r
50 listLength = Get number of rows
\r
51 for i from 1 to listLength
\r
52 select Table ToneList
\r
53 inFile$ = Get value... 'i' Word
\r
55 if (exclude$ = "" or rindex_regex(inFile$, exclude$) <= 0) and rindex_regex(inFile$, "[\d]") > 0
\r
56 referenceName$ = inFile$
\r
57 select Pitch 'inFile$'
\r
58 plus Pitch SourcePitch
\r
59 noprogress To DTW... 24 10 yes yes no restriction
\r
60 Rename... DTW'inFile$'
\r
61 distance = Get distance (weighted)
\r
63 countDistance = countDistance + 1
\r
64 sumDistance = sumDistance + distance
\r
65 sumSqrDistance = sumSqrDistance + distance^2
\r
67 if pinyin$ = inFile$
\r
68 correctDistance = distance
\r
72 # printline 'distance' - 'inFile$'
\r
75 if distance < smallestDistance
\r
76 smallestDistance = distance
\r
77 choiceReference$ = "'inFile$'"
\r
81 select DTW DTW'inFile$'
\r
83 if keepIntermediates = 0
\r
89 if countDistance > 1
\r
90 meanDistance = sumDistance / countDistance
\r
91 varDistance = (sumSqrDistance - sumDistance^2/countDistance)/(countDistance - 1)
\r
92 stdDistance = sqrt(varDistance)
\r
93 diffDistance = correctDistance - smallestDistance
\r
94 zDistance = diffDistance/stdDistance
\r
97 printline Match: 'pinyin$' <== 'choiceReference$' small='smallestDistance' Z='zDistance'
\r
100 if zDistance < biasDistance
\r
101 choiceReference$ = pinyin$
\r
102 smallestDistance = correctDistance
\r
108 for i from 1 to listLength
\r
109 select Table ToneList
\r
110 inFile$ = Get value... 'i' Word
\r
112 if (exclude$ = "" or rindex_regex(inFile$, exclude$) <= 0) and rindex_regex(inFile$, "[\d]") > 0
\r
115 select Pitch 'inFile$'
\r
116 if keepIntermediates = 0
\r
122 select Table ToneList
\r
123 if test_word$ <> "" and test_word$ <> "REUSEPITCH"
\r
126 if test_word$ <> "" and test_word$ <> "REUSEPITCH"
\r
127 plus Pitch SourcePitch
\r
129 if keepIntermediates = 0
\r