Handling recording time
[sgc2.git] / ToneProt / ToneRecognition.praat
blob3464de797c527a1a97a24da2a8c1990801c9acab
1 #! praat\r
2 #\r
3 # Construct all tone patterns and look for the one closest to the given one\r
4 #\r
5 \r
6 procedure FreeToneRecognition .pinyin$ .test_word$ .exclude$ .upperRegister .freqRange .durScale\r
7     # Clean up input\r
8     if .pinyin$ <> ""\r
9         .pinyin$ = replace_regex$(.pinyin$, "^\s*(.+)\s*$", "\1", 1)\r
10         .pinyin$ = replace_regex$(.pinyin$, "5", "0", 0)\r
11                 # Missing neutral tones\r
12                 call add_missing_neutral_tones '.pinyin$'\r
13                 .pinyin$ = add_missing_neutral_tones.pinyin$\r
14     endif\r
16     .referenceFrequency = 300\r
17     .frequencyFactor = .referenceFrequency / .upperRegister\r
19     .referenceExt$ = "pitch"\r
20     \r
21     # Bias Z-normalized value of the distance difference between smallest and correct\r
22     .biasDistance = 0.6\r
23     \r
24     # Debugging\r
25     .keepIntermediates = 0\r
26     .debug = 0\r
28     # Generate reference tones\r
29     call toneScript '.pinyin$' '.upperRegister' '.freqRange' '.durScale' Pitch\r
31     # Convert input to Pitch\r
32     if .test_word$ <> "" and .test_word$ <> "REUSEPITCH"\r
33         Read from file... '.test_word$'\r
34         Rename... Source\r
35     endif\r
36     if .test_word$ <> "REUSEPITCH"\r
37         select Sound Source\r
38                 call convert2Pitch 'sgc_ToneProt.minimumPitch' 'sgc_ToneProt.maximumPitch'\r
39                 .sourcePitch = convert2Pitch.object\r
40         Formula... self*'.frequencyFactor'; Normalize Pitch\r
41         Rename... SourcePitch\r
42     endif\r
43     select Pitch SourcePitch\r
45     .countDistance = 0\r
46     .sumDistance = 0\r
47     .sumSqrDistance = 0\r
48     .correctDistance = -1\r
50     .smallestDistance=999999\r
51     sgc_ToneProt.choiceReference$ = "empty"\r
52     select Table ToneList\r
53     .listLength = Get number of rows\r
54     for .i from 1 to .listLength\r
55         select Table ToneList\r
56         .inFile$ = Get value... '.i' Word\r
58         if (.exclude$ = "" or rindex_regex(.inFile$, .exclude$) <= 0) and rindex_regex(.inFile$, "[\d]") > 0 \r
59             referenceName$ = .inFile$\r
60             select Pitch '.inFile$'\r
61             plus Pitch SourcePitch\r
62             .dtw = noprogress To DTW... 24 10 yes yes no restriction\r
63             Rename... DTW'.inFile$'\r
64             distance = Get distance (weighted)\r
65             \r
66             .countDistance = .countDistance + 1\r
67             .sumDistance = .sumDistance + distance\r
68             .sumSqrDistance = .sumSqrDistance + distance^2\r
69             \r
70             if .pinyin$ = .inFile$\r
71                 .correctDistance = distance\r
72             endif\r
74             if .debug > 0\r
75                 # printline 'distance' - '.inFile$'\r
76             endif\r
78             if distance < .smallestDistance\r
79                 .smallestDistance = distance\r
80                 sgc_ToneProt.choiceReference$ = "'.inFile$'"\r
81             endif\r
83             # Clean up\r
84             select DTW DTW'.inFile$'\r
86             if .keepIntermediates = 0\r
87                 Remove\r
88             endif\r
89         endif\r
90     endfor\r
91     \r
92     if .countDistance > 1\r
93         .meanDistance = .sumDistance / .countDistance\r
94         .varDistance = (.sumSqrDistance - .sumDistance^2/.countDistance)/(.countDistance - 1)\r
95         .stdDistance = sqrt(.varDistance)\r
96         .diffDistance = .correctDistance - .smallestDistance\r
97         .zDistance = .diffDistance/.stdDistance\r
99         if .debug > 0\r
100             printline Match: '.pinyin$' <== 'sgc_ToneProt.choiceReference$' small='.smallestDistance' Z='.zDistance'\r
101         endif\r
103         if .zDistance < .biasDistance\r
104             sgc_ToneProt.choiceReference$ = .pinyin$\r
105             .smallestDistance = .correctDistance\r
106         endif\r
107     endif\r
108     \r
110     # Clean up\r
111     for .i from 1 to .listLength\r
112         select Table ToneList\r
113         .inFile$ = Get value... '.i' Word\r
115         if (.exclude$ = "" or rindex_regex(.inFile$, .exclude$) <= 0) and rindex_regex(.inFile$, "[\d]") > 0 \r
117             # Clean up\r
118             select Pitch '.inFile$'\r
119             if .keepIntermediates = 0\r
120                 Remove\r
121             endif\r
122         endif\r
123     endfor\r
125     select Table ToneList\r
126     if .test_word$ <> "" and .test_word$ <> "REUSEPITCH"\r
127         plus Sound Source\r
128     endif\r
129     if .test_word$ <> "" and .test_word$ <> "REUSEPITCH"\r
130         plus Pitch SourcePitch\r
131     endif\r
132     if .keepIntermediates = 0\r
133         Remove\r
134     endif\r
136 endproc\r