Handle broken wordlists and audio files
[sgc2.git] / ToneProt / ToneRecognition.praat
blob4b4412f73f59f350d1afcbd0bda1a88f980fe989
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     endif\r
13     .referenceFrequency = 300\r
14     .frequencyFactor = .referenceFrequency / .upperRegister\r
16     .referenceExt$ = "pitch"\r
17     \r
18     # Bias Z-normalized value of the distance difference between smallest and correct\r
19     .biasDistance = 0.6\r
20     \r
21     # Debugging\r
22     .keepIntermediates = 0\r
23     .debug = 0\r
25     # Generate reference tones\r
26     call toneScript '.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
31         Rename... Source\r
32     endif\r
33     if .test_word$ <> "REUSEPITCH"\r
34         select Sound Source\r
35                 call convert2Pitch 'sgc_ToneProt.minimumPitch' 'sgc_ToneProt.maximumPitch'\r
36                 .sourcePitch = convert2Pitch.object\r
37         Formula... self*'.frequencyFactor'; Normalize Pitch\r
38         Rename... SourcePitch\r
39     endif\r
40     select Pitch SourcePitch\r
42     .countDistance = 0\r
43     .sumDistance = 0\r
44     .sumSqrDistance = 0\r
45     .correctDistance = -1\r
47     .smallestDistance=999999\r
48     sgc_ToneProt.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             .dtw = noprogress To DTW... 24 10 yes yes no restriction\r
60             Rename... DTW'.inFile$'\r
61             distance = Get distance (weighted)\r
62             \r
63             .countDistance = .countDistance + 1\r
64             .sumDistance = .sumDistance + distance\r
65             .sumSqrDistance = .sumSqrDistance + distance^2\r
66             \r
67             if .pinyin$ = .inFile$\r
68                 .correctDistance = distance\r
69             endif\r
71             if .debug > 0\r
72                 # printline 'distance' - '.inFile$'\r
73             endif\r
75             if distance < .smallestDistance\r
76                 .smallestDistance = distance\r
77                 sgc_ToneProt.choiceReference$ = "'.inFile$'"\r
78             endif\r
80             # Clean up\r
81             select DTW DTW'.inFile$'\r
83             if .keepIntermediates = 0\r
84                 Remove\r
85             endif\r
86         endif\r
87     endfor\r
88     \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
96         if .debug > 0\r
97             printline Match: '.pinyin$' <== 'sgc_ToneProt.choiceReference$' small='.smallestDistance' Z='.zDistance'\r
98         endif\r
100         if .zDistance < .biasDistance\r
101             sgc_ToneProt.choiceReference$ = .pinyin$\r
102             .smallestDistance = .correctDistance\r
103         endif\r
104     endif\r
105     \r
107     # Clean up\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
114             # Clean up\r
115             select Pitch '.inFile$'\r
116             if .keepIntermediates = 0\r
117                 Remove\r
118             endif\r
119         endif\r
120     endfor\r
122     select Table ToneList\r
123     if .test_word$ <> "" and .test_word$ <> "REUSEPITCH"\r
124         plus Sound Source\r
125     endif\r
126     if .test_word$ <> "" and .test_word$ <> "REUSEPITCH"\r
127         plus Pitch SourcePitch\r
128     endif\r
129     if .keepIntermediates = 0\r
130         Remove\r
131     endif\r
133 endproc\r