Rewriting process start codes to use call process<table><label> .... procedures
[sgc2.git] / ToneProt / ToneRules.praat
blobef05ab9b0063f53fb4ebf493ca24494872cb174c
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
5 # (which they are).
7 # toneScript.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 # toneScript.point: The time of the next pitch value in the contour
18 #        ONLY USE AS: toneScript.point = toneScript.point + <fraction> * voicedDuration
20 # The following values are given by the calling routine
21 # DO NOT ALTER THEM
22
23 # toneScript.toneSyllable: tone number on the current syllable
24 # toneScript.nextTone: tone number of next syllable or -1
25 # toneScript.prevTone: tone number of previous syllable or -1
26 # toneScript.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
31
33 # Procedure to scale the duration of the current syllable
34 procedure toneDuration
35         if toneScript.toneSyllable = 0
36                 zeroToneFactor = 0.5
37         if toneScript.prevTone = 2
38             zeroToneFactor = 0.8 * zeroToneFactor
39         elsif toneScript.prevTone = 3
40             zeroToneFactor = 1.1 * zeroToneFactor
41         elsif toneScript.prevTone = 4
42             zeroToneFactor = 0.8 * zeroToneFactor
43         endif
44         toneFactor = zeroToneFactor * toneFactor
45         elsif toneScript.toneSyllable = 2
46                 toneFactor = 0.8
47         elsif toneScript.toneSyllable = 3
48                 toneFactor = 1.1
49     elsif toneScript.toneSyllable = 4
50                 toneFactor = 0.8
51         endif
52     
53         # Next tone 0, then lengthen first syllable
54         if toneScript.nextTone = 0
55                 toneFactor = toneFactor * 1.2
56         endif
57 endproc
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 'toneScript.point =' defines the time of the next pitch value
67 # start * ?Semit is a fall
68 # start / ?Semit is a rise
70 procedure toneRules
71     #
72     # Tone levels 1-5
73     # Defined relative to the topline and the frequency range
74     levelFive = topLine
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))
80     # First tone
81         if toneScript.toneSyllable = 1
82         # Just a straight line
83         startPoint = levelFive
84         endPoint = levelFive
85         
86         # Two first tones, make them a little different
87         if toneScript.prevTone = 1
88             startPoint = startPoint * 0.999
89             endPoint = endPoint * 0.999
90         endif
91         
92         # Write toneScript.points
93         Add point... 'toneScript.point' 'startPoint'
94         toneScript.point = toneScript.point + voicedDuration
95         Add point... 'toneScript.point' 'endPoint'
96     # Second tone
97         elsif toneScript.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
104         if toneScript.nextTone = 1
105             endPoint = startPoint / fiveSemit
106             endif
107             # Go lower if previous tone is 1
108             if toneScript.prevTone = 1
109                 startPoint = startPoint * oneSemit
110         elsif toneScript.prevTone = 4 or toneScript.prevTone = 3
111             # Special case: 2 following 4 or 3
112             # Go 1 semitone up
113                 startPoint = toneScript.lastFrequency / oneSemit
114             endPoint = levelFive
115             elsif toneScript.prevTone = 2
116         # Two consecutive tone 2, start 1 semitone higher
117                     startPoint = startPoint / oneSemit
118         endif
119         # Define a midtoneScript.point at 1/3 of the duration
120         midPoint = startPoint
121              
122         # Write toneScript.points
123         Add point... 'toneScript.point' 'startPoint'
124         # Next toneScript.point a 1/3th of duration
125         toneScript.point = toneScript.point + (voicedDuration)/3
126         Add point... 'toneScript.point' 'midPoint'
127         # Remaining duration
128         toneScript.point = toneScript.point + (voicedDuration)*2/3
129         Add point... 'toneScript.point' 'endPoint'
130     # Third tone
131         elsif toneScript.toneSyllable = 3
132         # Halfway the range
133         startPoint = levelThree
134         lowestPoint = levelOne * threeSemit
135         # Protect pitch against "underflow"
136         if lowestPoint < toneScript.absoluteMinimum
137             lowestPoint = toneScript.absoluteMinimum
138         endif
139         # First syllable
140         if toneScript.nextTone < 0
141             endPoint = startPoint
142         # Anticipate rise in next tone
143         elsif toneScript.nextTone = 1 or toneScript.nextTone = 4
144             lowestPoint = levelOne / twoSemit
145             endPoint = startPoint
146         # Anticipate rise in next tone and stay low
147         elsif toneScript.nextTone = 2
148             lowestPoint = levelOne / twoSemit
149             endPoint = lowestPoint
150         # Last one was low, don't go so much lower
151         elsif toneScript.prevTone = 4
152             lowestPoint = levelOne * oneSemit
153         # Anticipate rise in next tone and stay low
154         elsif toneScript.nextTone = 0
155             lowestPoint = levelOne
156             endPoint = lowestPoint / sixSemit
157         else
158             endPoint = startPoint
159         endif
160     
161         # Write toneScript.points
162         Add point... 'toneScript.point' 'startPoint'
163         # Go 1/3 of the duration down
164             toneScript.point = toneScript.point + (voicedDuration)*2/6
165         Add point... 'toneScript.point' 'lowestPoint'
166         # Go half the duration low
167             toneScript.point = toneScript.point + (voicedDuration)*3/6
168         Add point... 'toneScript.point' 'lowestPoint'
169         # Return in 1/6th of the duration
170             toneScript.point = toneScript.point + (voicedDuration)*1/6
171         Add point... 'toneScript.point' 'endPoint'
172     # Fourth tone
173         elsif toneScript.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
178         
179         
180         # SPECIAL: Fall in following neutral tone
181             if toneScript.nextTone = 0
182                 endPoint = endPoint / threeSemit
183         endif
184      
185         # Write toneScript.points
186         Add point... 'toneScript.point' 'startPoint'
187         # A plateau for 1/3th
188         toneScript.point = toneScript.point + voicedDuration*1/3
189         Add point... 'toneScript.point' 'startPoint'
190         # Go down the rest
191         toneScript.point = toneScript.point + voicedDuration*2/3
192         Add point... 'toneScript.point' 'endPoint'
193     # Neutral tone
194         elsif toneScript.toneSyllable = 0
195         if toneScript.lastFrequency > 0
196             startPoint = toneScript.lastFrequency
197         else
198             startPoint = levelThree / oneSemit
199         endif
201         if toneScript.prevTone = 1
202             startPoint = toneScript.lastFrequency * twoSemit 
203         elsif toneScript.prevTone = 2
204             startPoint = toneScript.lastFrequency
205         elsif toneScript.prevTone = 3
206             startPoint = toneScript.lastFrequency / oneSemit
207         elsif toneScript.prevTone = 4
208             startPoint = toneScript.lastFrequency * oneSemit
209         elsif toneScript.lastFrequency > 0
210             startPoint = toneScript.lastFrequency * oneSemit
211         endif
213         # Catch all errors\r
214         if startPoint <= 0
215             startPoint = levelThree / oneSemit
216         endif
217             
218        # Add spreading and some small or large de/inclination
219         if toneScript.prevTone = 1
220                 midPoint = startPoint * frequency_Range / oneSemit
221             endPoint = midPoint * oneSemit
222         elsif toneScript.prevTone = 2
223             # 
224                 midPoint = startPoint * fiveSemit
225             endPoint = midPoint * twoSemit
226         elsif toneScript.prevTone = 3
227                 midPoint = startPoint / twoSemit
228             endPoint = midPoint
229         elsif toneScript.prevTone = 4
230                 midPoint = startPoint * threeSemit
231             endPoint = midPoint / oneSemit
232         else
233                 midPoint = startPoint * oneSemit
234             endPoint = midPoint
235         endif
236                 
237         # Add a very short break to force
238         if toneScript.point = undefined
239             toneScript.point = 0
240         endif
241         
242         Add point... 'toneScript.point' 0
243                 toneScript.point = toneScript.point + 1/startPoint
244         Add point... 'toneScript.point' 0
245                 toneScript.point = toneScript.point + toneScript.delta
246         
247         # Write toneScript.points first 2/3 then decaying 1/3
248         Add point... 'toneScript.point' 'startPoint'
249                 toneScript.point = toneScript.point + (voicedDuration - 1/startPoint)*2/3
250             Add point... 'toneScript.point' 'midPoint'
251                 toneScript.point = toneScript.point + (voicedDuration - 1/startPoint)*1/3
252             Add point... 'toneScript.point' 'endPoint'
253     # Dutch intonation
254         else
255         # Start halfway of the range
256         startPoint = levelThree
257         # Or continue from last Dutch "tone"
258         if toneScript.prevTone = 6
259             startPoint = toneScript.lastFrequency
260         endif
261         # Add declination
262         endPoint = startPoint * oneSemit
263         
264         # Write toneScript.points
265         Add point... 'toneScript.point' 'startPoint'
266         toneScript.point = toneScript.point + voicedDuration
267         Add point... 'toneScript.point' 'endPoint'
268         endif
269 endproc