1 # The rules for constructing the tone contours.
3 # This procedure works because in Praat, there is no namespace
4 # separation. All variables behave as if they are global
7 # toneSyllable is the tone number on the current syllable
8 # 1-4, 0=neutral, 6=Dutch (garbage) intonation
10 # These procedures set the following pareameters
11 # and use them to create a Pitch Tier:
13 # toneFactor: Duration scale factor for current tone
14 # startPoint: Start of the tone
15 # endPoint: end of the tone
16 # lowestPoint: bottom of tone 3
17 # point: The time of the next pitch value in the contour
18 # ONLY USE AS: point = point + <fraction> * voicedDuration
20 # The following values are given by the calling routine
23 # toneSyllable: tone number on the current syllable
24 # nextTone: tone number of next syllable or -1
25 # prevTone: tone number of previous syllable or -1
26 # lastFrequency: end-frequency of the previous syllable
28 # topLine: the frequency of the first tone
29 # frequency_Range: Range of tone four (1 octave)
30 # voicedDuration: Duration of voiced part of syllable
33 # Procedure to scale the duration of the current syllable
34 procedure toneDuration
38 zeroToneFactor = 0.8 * zeroToneFactor
40 zeroToneFactor = 1.1 * zeroToneFactor
42 zeroToneFactor = 0.8 * zeroToneFactor
44 toneFactor = zeroToneFactor * toneFactor
45 elsif toneSyllable = 2
47 elsif toneSyllable = 3
49 elsif toneSyllable = 4
53 # Next tone 0, then lengthen first syllable
55 toneFactor = toneFactor * 1.2
59 # DO NOT CHANGE toneFactor BELOW THIS POINT
61 # Rules to create a tone
63 # Do not mess with the 'Add point...' commands
64 # unless you know what you are doing
65 # The 'point =' defines the time of the next pitch value
67 # start * ?Semit is a fall
68 # start / ?Semit is a rise
73 # Defined relative to the topline and the frequency range
75 levelOne = topLine * frequency_Range
76 levelThree = topLine * sqrt(frequency_Range)
77 levelTwo = topLine * sqrt(sqrt(frequency_Range))
78 levelFour = levelOne / sqrt(sqrt(frequency_Range))
82 # Just a straight line
83 startPoint = levelFive
86 # Two first tones, make them a little different
88 startPoint = startPoint * 0.999
89 endPoint = endPoint * 0.999
93 Add point... 'point' 'startPoint'
94 point = point + voicedDuration
95 Add point... 'point' 'endPoint'
97 elsif toneSyllable = 2
98 # Start halfway of the range - 1 semitone
99 startPoint = levelThree * oneSemit
100 # End 1 semitones above the first tone
101 endPoint = levelFive / oneSemit
102 # Special case: 2 followed by 1, stop short of the top-line
103 # ie, 5 semitones above the start
105 endPoint = startPoint / fiveSemit
107 # Go lower if previous tone is 1
109 startPoint = startPoint * oneSemit
110 elsif prevTone = 4 or prevTone = 3
111 # Special case: 2 following 4 or 3
113 startPoint = lastFrequency / oneSemit
116 # Two consecutive tone 2, start 1 semitone higher
117 startPoint = startPoint / oneSemit
119 # Define a midpoint at 1/3 of the duration
120 midPoint = startPoint
123 Add point... 'point' 'startPoint'
124 # Next point a 1/3th of duration
125 point = point + (voicedDuration)/3
126 Add point... 'point' 'midPoint'
128 point = point + (voicedDuration)*2/3
129 Add point... 'point' 'endPoint'
131 elsif toneSyllable = 3
133 startPoint = levelThree
134 lowestPoint = levelOne * threeSemit
135 # Protect pitch against "underflow"
136 if lowestPoint < absoluteMinimum
137 lowestPoint = absoluteMinimum
141 endPoint = startPoint
142 # Anticipate rise in next tone
143 elsif nextTone = 1 or nextTone = 4
144 lowestPoint = levelOne / twoSemit
145 endPoint = startPoint
146 # Anticipate rise in next tone and stay low
148 lowestPoint = levelOne / twoSemit
149 endPoint = lowestPoint
150 # Last one was low, don't go so much lower
152 lowestPoint = levelOne * oneSemit
153 # Anticipate rise in next tone and stay low
155 lowestPoint = levelOne
156 endPoint = lowestPoint / sixSemit
158 endPoint = startPoint
162 Add point... 'point' 'startPoint'
163 # Go 1/3 of the duration down
164 point = point + (voicedDuration)*2/6
165 Add point... 'point' 'lowestPoint'
166 # Go half the duration low
167 point = point + (voicedDuration)*3/6
168 Add point... 'point' 'lowestPoint'
169 # Return in 1/6th of the duration
170 point = point + (voicedDuration)*1/6
171 Add point... 'point' 'endPoint'
173 elsif toneSyllable = 4
174 # Start higher than tone 1 (by 2 semitones)
175 startPoint = levelFive / twoSemit
176 # Go down the full range
177 endPoint = startPoint * frequency_Range
180 # SPECIAL: Fall in following neutral tone
182 endPoint = endPoint / threeSemit
186 Add point... 'point' 'startPoint'
187 # A plateau for 1/3th
188 point = point + voicedDuration*1/3
189 Add point... 'point' 'startPoint'
191 point = point + voicedDuration*2/3
192 Add point... 'point' 'endPoint'
194 elsif toneSyllable = 0
196 startPoint = lastFrequency
198 startPoint = levelThree / oneSemit
202 startPoint = lastFrequency * twoSemit
204 startPoint = lastFrequency
206 startPoint = lastFrequency / oneSemit
208 startPoint = lastFrequency * oneSemit
209 elsif lastFrequency > 0
210 startPoint = lastFrequency * oneSemit
215 startPoint = levelThree / oneSemit
218 # Add spreading and some small or large de/inclination
220 midPoint = startPoint * frequency_Range / oneSemit
221 endPoint = midPoint * oneSemit
224 midPoint = startPoint * fiveSemit
225 endPoint = midPoint * twoSemit
227 midPoint = startPoint / twoSemit
230 midPoint = startPoint * threeSemit
231 endPoint = midPoint / oneSemit
233 midPoint = startPoint * oneSemit
237 # Add a very short break to force
242 Add point... 'point' 0
243 point = point + 1/startPoint
244 Add point... 'point' 0
245 point = point + delta
247 # Write points first 2/3 then decaying 1/3
248 Add point... 'point' 'startPoint'
249 point = point + (voicedDuration - 1/startPoint)*2/3
250 Add point... 'point' 'midPoint'
251 point = point + (voicedDuration - 1/startPoint)*1/3
252 Add point... 'point' 'endPoint'
255 # Start halfway of the range
256 startPoint = levelThree
257 # Or continue from last Dutch "tone"
259 startPoint = lastFrequency
262 endPoint = startPoint * oneSemit
265 Add point... 'point' 'startPoint'
266 point = point + voicedDuration
267 Add point... 'point' 'endPoint'