libpraat.dll is not required anymore
[sgc.git] / SGC_ToneProt / InitialRecognition.praat
blobbbe2e2b00015913f7e7fb43a0c2c7b013b9a261c
1 #! praat
3 # Load all CoG reference files and compare the recorded test sound to them
4 # Chose the reference file with the lowest distance
5 # 'exclude$' contains a regexp pattern that deselects unwanted reference files
6 # The number of coefficients should match those in the reference files
7 # (which should be readable from a Praat script, but aren't)
9 #   word pinyin duo1
10 #       word test_word wav/duo1shao3/duo1shao3_duo1shao3_F20DUTB1BS01_2006-12-11T2-00.wav
11 #       word reference_dir ../wordlists/CoGMandarinSounds
12 #   
14 form Give input
15         word pinyin cha2
16         word test_word ../../test/cha2_cha2_252_Sat-Mar-17-22-08-22-2007.wav
17         word reference_dir ../wordlists/CoGMandarinSounds
18 endform
20 referenceCOGExt$ = "cog"
22 # Read the procedure to calculate the CoG
23 # Note that we preserve the initial but silence any "noise" at the end ot the final
24 include CoGcalculation.praat
26 # Bias Z-normalized value of the distance difference between smallest and correct
27 biasDistance = 0.9
29 # Debugging
30 #keepIntermediates = 0
31 debug = 0
33 final$ = replace_regex$(pinyin$, "^([^uoaeiv]*)([uoaeiv]+[ngmr]*[0-9])([a-zA-Z0-9]*)$", "\2", 0)
34 initial$ = replace_regex$(pinyin$, "^([^uoaeiv]*)([uoaeiv]+[ngmr]*[0-9])([a-zA-Z0-9]*)$", "\1", 0)
35 secondSyll$ = " "
36 if rindex_regex(pinyin$, "^'initial$''final$'([a-zA-Z]+[0-9])") > 0
37     secondSyll$ = replace_regex$(pinyin$, "^'initial$''final$'([a-zA-Z]+[0-9])", "\1", 0)
38 endif
40 # printline 'initial$'+'final$'+'secondSyll$'
42 # Read input
43 if test_word$ <> "" and test_word$ <> "REUSEMFCC"
44     Read from file... 'test_word$'
45     Rename... Original
46     Resample... 16000 50
47     Rename... Source
48     select Sound Original
49     Remove
50     select Sound Source
51 endif
53 # CoG
54 nasals$ = "(m|n|ng)"
55 plosives$ = "([ptkbdg])"
56 fricatives$ = "([fsxh]|sh)"
57 affricates$ = "([zcqj]|zh|ch)"
58 semivowels$ = "([ywlr])"
60 isNasal = 0
61 isPlosive = 0
62 isFricative = 0
63 isAffricate = 0
64 isSemivowel = 0
65 isEmpty = 0
67 # Determine manner of articulation and adapt bias
68 if rindex_regex(pinyin$, "^'nasals$'") > 0
69     isNasal = 1
70     biasDistance = 0.9
71 elsif rindex_regex(pinyin$, "^'plosives$'") > 0
72     isPlosive=1
73     biasDistance = 0.9
74 elsif rindex_regex(pinyin$, "^'fricatives$'") > 0
75     isFricative=1
76     biasDistance = 0.9
77 elsif rindex_regex(pinyin$, "^'affricates$'") > 0
78     isAffricate=1
79     biasDistance = 0.9
80 elsif rindex_regex(pinyin$, "^'semivowels$'") > 0
81     isSemivowel=1
82     biasDistance = 0.5
83 else
84     isEmpty = 1
85 endif
87 Create Strings as file list... ReferenceList 'reference_dir$'/*'final$'.'referenceCOGExt$'
88 numberOfReferences = Get number of strings
90 # Convert input to CoG
91 if test_word$ <> "REUSEMFCC"
92     select Sound Source
93     call CoGcalculation
94     Rename... Source
95 endif
97 inputMediaCoG = Get quantile... 0 0 0.5 Hertz
99 # Get final syllable
100 totalDuration = 0
102 smallestDistance=999999
103 countDistance = 0
104 sumDistance = 0
105 sumSqrDistance = 0
106 correctDistance = -1
107 choiceReference$ = pinyin$
108 for i from 1 to numberOfReferences
109     select Strings ReferenceList
110     inFile$ = Get string... 'i'
111     referenceName$ = replace_regex$(inFile$, "([^.]+)."+referenceCOGExt$+"$", "\1", 0)
112         
113     useReference = 0
114     # Special cases first!
115     if initial$ = "g" and rindex_regex(inFile$, "^h'final$'") > 0
116         useReference = 1
117     elsif initial$ = "x" and rindex_regex(inFile$, "^k'final$'") > 0
118         useReference = 1
119     elsif (isNasal and rindex_regex(inFile$, "^'nasals$''final$'") > 0)
120         useReference = 1
121     elsif (isFricative and rindex_regex(inFile$, "^'fricatives$''final$'") > 0)
122         useReference = 1
123     elsif (isPlosive and rindex_regex(inFile$, "^'plosives$''final$'") > 0)
124         useReference = 1
125     elsif (isAffricate and rindex_regex(inFile$, "^'affricates$''final$'") > 0)
126         useReference = 1
127     elsif (isSemivowel and rindex_regex(inFile$, "^'semivowels$''final$'") > 0)
128         useReference = 1
129     elsif (isEmpty) and rindex_regex(inFile$, "^'final$'") > 0
130         useReference = 1
131     endif
132     
133     if useReference > 0
134             Read from file... 'reference_dir$'/'inFile$'
136        currentMediaCoG = Get quantile... 0 0 0.5 Hertz
137         factorMedian = inputMediaCoG/currentMediaCoG
138         Formula... self*factorMedian
140         select Pitch 'referenceName$'
141         plus Pitch Source
142         noprogress To DTW... 24.0 10.0 yes yes no restriction
143         Rename... DTW'i'
144         distance = Get distance (weighted)
146         countDistance = countDistance + 1
147         sumDistance = sumDistance + distance
148         sumSqrDistance = sumSqrDistance + distance^2
150         if distance < smallestDistance
151             smallestDistance = distance
152             choiceReference$ = referenceName$
153         endif
155         if referenceName$ = pinyin$
156             correctDistance = distance
157         endif
158 if debug > 0
159     logline$ = "'pinyin$' 'inFile$' 'referenceName$' 'distance' 'smallestDistance' 'choiceReference$'"
160     printline 'logline$'
161     logline$ = logline$+newline$
162     logline$ >> initialrecognitionlog.txt
163 endif
165         # Clean up
166         select DTW DTW'i'
167             plus Pitch 'referenceName$'
168         Remove
169     endif
170 endfor
172 zDistance = -1
173 if countDistance > 2
174     meanDistance = sumDistance / countDistance
175     varDistance = (sumSqrDistance - sumDistance^2/countDistance)/(countDistance - 1)
176     stdDistance = sqrt(varDistance)
177     diffDistance = correctDistance - smallestDistance
178     zDistance = diffDistance/stdDistance
180     if zDistance < biasDistance
181         choiceReference$ = pinyin$
182         smallestDistance = correctDistance
183     endif
184         
185 endif
187 # Special cases
188 if initial$ = "d"  and rindex_regex(choiceReference$, "^g'final$'") > 0
189     choiceReference$ = "g'final$'"
190 endif
192 if debug > 0
193     logline$ = "CoG Match: 'pinyin$' <== 'choiceReference$' corr='correctDistance' Z='zDistance'"
194     logline$ = logline$+newline$
195     logline$ >> initialrecognitionlog.txt
196 endif
197 choiceReference$ > lastInitialRecognitionResult.txt
199 # Clean up
201 select Strings ReferenceList
202 if test_word$ <> "" and test_word$ <> "REUSEMFCC"
203     plus Sound Source
204 endif
205 plus Pitch Source
206 Remove