pelican-nlp 0.3.7__py3-none-any.whl → 0.3.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1546 @@
1
+ # prosoplot.praat ---
2
+ # Praat include file containing procedures for plotting parameters related to prosody
3
+ # This file is included (indirectly) by prosogram.praat. It isn't a stand-alone script. Use prosogram.praat instead.
4
+ # Author: Piet Mertens
5
+ # Last modification: 2020-03-14
6
+
7
+ # Procedure hierarchy
8
+ # gr_init initialize some global variables for graphics modes
9
+ # gr_start_demowin initialize for Praat Demo window
10
+ # gr_start_picturewin initialize for Praat Picture window
11
+ # gr_run_demowin start running interactive window
12
+ # gr_redraw redraw demo window contents: buttons, prosogram, textgrid, time bar
13
+ # gr_display_prosogram
14
+ # gr_plot_textgrid
15
+ # gr_draw_tiernames
16
+ # gr_garnish draw border, time marks, pitch scales...
17
+ # gr_draw_portee
18
+ # gr_draw_calib draw horizontal calibration line
19
+ # gr_draw_octavejump
20
+ # gr_plot_param_ST plot f0 on ST scale
21
+ # gr_plot_param_scaled plot intensity on dB scale
22
+ # gr_plot_vuv plot voicing decision
23
+ # gr_plot_nuclei plot syllabic nuclei
24
+ # gr_plot_pitchrange plot pitch range
25
+ # gr_plot_feature plot feature (a categorical or a numerical variable) of a syllabic nucleus, as a symbol or a number
26
+ # gr_plot_prop_as_shape plot property (a numerical variable) of a syllabic nucleus, as a shape
27
+ # gr_plot_prop_curve plot property (a numerical variable) of a syllabic nucleus, as a curve
28
+ # gr_plot_PitchTier_clip_nuclei plot stylization for syllabic nuclei with or without clipping
29
+ # gr_plot_stylisation plot stylization for syllabic nuclei
30
+ # gr_display_textgrid_pure plot textgrid in demo window mode
31
+ # gr_draw_buttons
32
+ # gr_draw_button
33
+ # gr_write_all_prosograms plot and save all prosogram in a file or set of files
34
+ # gr_first_viewport_of_page initialize viewport for Picture window and Postscript bounding box
35
+ # gr_viewport_size set outer and inner viewport
36
+ # gr_write_prosogram save Praat picture window with prosogram(s) to disk file
37
+ # gr_next_viewport
38
+
39
+
40
+ demowin = 0 ; start in Picture window mode
41
+
42
+
43
+ procedure gr_init
44
+ ; Initialize some global variables for graphics modes
45
+ show_octavejump = 1 ; show symbol at times of F0 discontinuity (typical of octave jump)
46
+ plot_f0_on_top = 0 ; plot f0 on top of stylization, rather than stylization on top of F0
47
+ ; Start counters for files and pages
48
+ file_stamp = 1 ; Show input speech filename on prosogram
49
+ plot_version = 1 ; Show version number
50
+ file_numbering = 1 ; automatic numbering of graphics files
51
+ file_ctr = 1 ; counter for graphics files
52
+ nrof_pages = 0
53
+ ; Font size affects drawing of TextGrid!
54
+ default_fontsize = 10
55
+ button_fontsize = 10 ; used for button text in demo window
56
+ msg_fontsize = 10 ; used for messages
57
+
58
+ ; Greyscales
59
+ grey$ = "Grey"
60
+ red$ = "Red"
61
+ green$ = "Green"
62
+ blue$ = "Blue"
63
+ cyan$ = "Cyan"
64
+ purple$ = "Purple"
65
+ magenta$ = "Magenta"
66
+ pink$ = "Pink"
67
+ purple$ = "Purple"
68
+ if (greyscale)
69
+ red$ = "Black"
70
+ green$ = "Black"
71
+ blue$ = "Black"
72
+ cyan$ = "Grey"
73
+ purple$ = "Grey"
74
+ magenta$ = "Grey"
75
+ pink$ = "Grey"
76
+ purple$ = "Grey"
77
+ endif
78
+ endproc
79
+
80
+
81
+ procedure gr_start_picturewin
82
+ @gr_init
83
+ demowin = 0
84
+ win$ = ""
85
+ small_fontsize = 6 ; used for file stamp
86
+ tiny_fontsize = 4 ; used for version stamp
87
+ 'font_family$'
88
+ stylization_linewidth = 7
89
+ pitchrange_linewidth = 2
90
+ Font size: fontsize
91
+ endproc
92
+
93
+
94
+ procedure gr_start_demowin: .filename$
95
+ @gr_init
96
+ demowin = 1
97
+ win$ = "demo "
98
+ .s$ = "Interactive 'version$' - Corpus file: '.filename$'"
99
+ demoWindowTitle (.s$)
100
+ grid_in_prosogram = 0
101
+ small_fontsize = 8
102
+ tiny_fontsize = 6
103
+ 'win$''font_family$'
104
+ 'win$'Font size: fontsize
105
+ stylization_linewidth = 3
106
+ pitchrange_linewidth = 2
107
+ 'win$'Black
108
+ # The size of the Demo window is (0..100, 0..100), with (0,0) the lower left corner.
109
+ 'win$'Select outer viewport: 0, 100, 0, 100
110
+ 'win$'Select inner viewport: 0, 100, 0, 100
111
+ 'win$'Axes: 0, 100, 0, 100
112
+ gr_text_maxlines = 40
113
+ @gr_clearscreen
114
+ endproc
115
+
116
+
117
+ procedure gr_printline: .text$
118
+ if (demowin)
119
+ .yd = 100/gr_text_maxlines
120
+ .xt = 1
121
+ if (gr_text_linenr >= gr_text_maxlines) ; max number of lines already used
122
+ for j from 1 to gr_text_maxlines-1 ; shift lines in msg text buffer and print again
123
+ gr_textbuf'j'$ = gr_textbuf'j+1'$
124
+ .s$ = gr_textbuf'j'$
125
+ .s$ = replace$ (.s$, "_", "\_ ", 0)
126
+ .xt2 = Text width (wc): .s$
127
+ 'win$'Paint rectangle: "White", .xt, .xt2, .yt, .yt+.yd
128
+ .yt = 100 - (j * .yd)
129
+ 'win$'Text special: .xt, "Left", .yt, "Bottom", "Helvetica", msg_fontsize, "0", .s$
130
+ endfor
131
+ gr_text_linenr = gr_text_maxlines
132
+ endif
133
+ .yt = 100 - (gr_text_linenr * .yd)
134
+ .s$ = replace$ (.text$, "_", "\_ ", 0)
135
+ 'win$'Text special: .xt, "Left", .yt, "Bottom", "Helvetica", msg_fontsize, "0", .s$
136
+ gr_textbuf'gr_text_linenr'$ = .text$
137
+ gr_text_linenr += 1
138
+ else
139
+ @msg: .text$
140
+ endif
141
+ endproc
142
+
143
+
144
+ procedure gr_clearscreen
145
+ # Only used in demowin
146
+ if (demowin)
147
+ 'win$'Erase all
148
+ for .j from 1 to gr_text_maxlines
149
+ gr_textbuf'.j'$ = ""
150
+ endfor
151
+ gr_text_linenr = 1
152
+ endif
153
+ endproc
154
+
155
+
156
+ procedure gr_clear_rectangle: .x1, .x2, .y1, .y2
157
+ if (demowin)
158
+ 'win$'Select inner viewport: 0, 100, 0, 100
159
+ 'win$'Axes: 0, 100, 0, 100
160
+ 'win$'Paint rectangle: "White", .x1, .x2, .y1, .y2
161
+ endif
162
+ endproc
163
+
164
+
165
+ procedure gr_run_demowin: anal_t1, anal_t2, .timeincr, ySTmin, ySTmax
166
+ # <anal_t1>..<anal_t2> analysed interval of signal, may be part of full signal duration.
167
+ # The size of the Demo window is (0..100, 0..100), with (0,0) the lower left corner.
168
+ # Define viewport for prosogram (below buttons, without TextGrid)
169
+ dw_ovx1 = 0 ; outer viewport = area for prosogram (without textgrid) including margins
170
+ dw_ovx2 = 100
171
+ dw_ovy1 = 60 ; lower side
172
+ dw_ovy2 = 91 ; upper side
173
+ dw_margin = 5 ; margin size is relative to dimension of demo window
174
+ dw_vx1 = dw_ovx1 + dw_margin ; inner viewport = area for prosogram (without textgrid) without margin
175
+ dw_vx2 = dw_ovx2 - dw_margin ; right margin
176
+ dw_vy1 = dw_ovy1 ; no lower margin
177
+ dw_vy2 = dw_ovy2 - dw_margin ; upper margin
178
+ # Define viewport for buttons
179
+ dw_bx1 = dw_vx1 ; X size for buttons = same as inner viewport
180
+ dw_bx2 = dw_vx2
181
+ dw_by1 = 93
182
+ dw_by2 = 98
183
+ # Define viewport for separate textgrid
184
+ dw_Tx1 = dw_vx1 ; X size for textgrid = same as inner viewport
185
+ dw_Tx2 = dw_vx2
186
+ dw_Ty1 = dw_vy1 ; lower side, default when no textgrid
187
+ dw_Ty2 = dw_vy2 ; upper side, default when no textgrid
188
+ if (nrofplottedtiers > 0)
189
+ selectObject: newgridID
190
+ n_ = Get number of tiers
191
+ dw_Ty2 = dw_vy1 - 1 ; upper side
192
+ dw_Ty1 = dw_Ty2 - (5 * n_) ; lower side
193
+ ; printline TextGrid viewport: x1=<'dw_Tx1:1'> x2=<'dw_Tx2:1'> y1=<'dw_Ty1:1'> y2=<'dw_Ty2:1'>
194
+ endif
195
+ # Define viewport for excerpt position
196
+ dw_Ex1 = dw_vx1 ; X range same as inner viewport
197
+ dw_Ex2 = dw_vx2
198
+ dw_Ey2 = dw_Ty1 - 1 ; upper side
199
+ dw_Ey1 = dw_Ey2 - 2 ; lower side
200
+ # Display all viewports and wait for input (mouse, keyboard)
201
+ 'win$'Erase all
202
+ @gr_redraw: anal_t1, anal_t1+.timeincr
203
+ @gr_on_input: nucleiID
204
+ endproc
205
+
206
+
207
+ procedure gr_redraw: .x1, .x2
208
+ # This procedure is used only for demo window
209
+ if (auto_pitchrange)
210
+ @speaker_autorange: .x1, .x2
211
+ ySTmax = ymax
212
+ ySTmin = ymin
213
+ endif
214
+ @gr_clear_rectangle: dw_ovx1, dw_ovx2, dw_by2, 100 ; clear top margin above buttons
215
+ @gr_display_prosogram: .x1, .x2, ySTmin, ySTmax, grid_in_prosogram, 1
216
+ if (nrofplottedtiers > 0)
217
+ @gr_clear_rectangle: dw_ovx1, dw_Tx1, dw_Ty1, dw_Ty2 ; clear border to left of textgrid
218
+ @gr_clear_rectangle: dw_Tx2, dw_ovx2, dw_Ty1, dw_Ty2 ; clear border to right of textgrid
219
+ @gr_display_textgrid_pure: newgridID, .x1, .x2, dw_Tx1, dw_Tx2, dw_Ty1, dw_Ty2
220
+ endif
221
+ @gr_draw_buttons
222
+ @gr_draw_excerpt_position: .x1, .x2, anal_t1, anal_t2
223
+ endproc
224
+
225
+
226
+ procedure gr_draw_excerpt_position: .t1, .t2, .at1, .at2
227
+ # Draw position (<.t1>..<.t2>) of excerpt inside full time range of speech signal (<.at1>..<.at2>)
228
+ if (demowin)
229
+ @gr_clear_rectangle: dw_ovx1, dw_ovx2, dw_Ey1, dw_Ey2 ; clear part of demo window, including borders
230
+ 'win$'Select inner viewport: dw_vx1, dw_vx2, dw_Ey1, dw_Ey2
231
+ ; when zooming beyond signal end (= .at2) :
232
+ .tr = max(.at2, .t2)
233
+ 'win$'Axes: .at1, .tr, 0, 1
234
+ 'win$'Colour: "Black"
235
+ 'win$'Draw rectangle: .at1, .at2, 0, 1
236
+ 'win$'Paint rectangle: "Grey", .t1, min(.t2, .at2), 0, 1
237
+ ; Draw analysis endtime
238
+ 'win$'Select inner viewport: 0, 100, 0, 100
239
+ 'win$'Axes: 0, 100, 0, 100
240
+ 'win$'Text special: dw_vx2+(dw_vx2-dw_vx1)*0.005, "left", dw_Ey1+(dw_Ey2-dw_Ey1)/2, "half", "Helvetica", default_fontsize, "0", fixed$(.at2, 2)
241
+ endif
242
+ endproc
243
+
244
+
245
+ procedure gr_display_prosogram: x1, x2, y1, y2, with_grid, .nfiles
246
+ # This procedure is used both in Picture window and in Demo window
247
+ @debug_msg: "gr_display_prosogram: entry, 'x1:3' - 'x2:3'"
248
+ if (demowin) ; clear demo window
249
+ @gr_clear_rectangle: dw_ovx1, dw_ovx2, dw_ovy1, dw_ovy2 ; area for prosogram
250
+ 'win$'Select inner viewport: dw_vx1, dw_vx2, dw_vy1, dw_vy2
251
+ endif
252
+ ySTmax = y2
253
+ ySTmin = y1
254
+ if (with_grid)
255
+ ySTbottom = ySTmin - nrofplottedtiers*(ySTmax-ySTmin)/4
256
+ else
257
+ ySTbottom = y1
258
+ endif
259
+ @debug_msg: "gr_display_prosogram: ySTmin='ySTmin:3' ySTmax='ySTmax:3' ySTbottom='ySTbottom:3' nrofplottedtiers='nrofplottedtiers'"
260
+ 'win$'Axes: x1, x2, ySTbottom, ySTmax
261
+
262
+ ; start drawing
263
+ if (with_grid and newgrid_available and nrofplottedtiers > 0) ; textgrid available, use Praat's Draw cmd to draw TG
264
+ @gr_plot_textgrid: newgridID, x1, x2
265
+ if (show_tiernames)
266
+ @gr_draw_tiernames: newgridID, x1, x2
267
+ endif
268
+ endif
269
+ @gr_garnish: x1, x2, ySTbottom, ySTmin, ySTmax, 10, basename$, font_family$, .nfiles
270
+
271
+ if (task != task_annotation)
272
+ # Adjust plotted intensity range such that distance between horizontal lines = 3 dB
273
+ selectObject: intensityID
274
+ dBmin = Get minimum: signal_start, anal_t2, "Parabolic"
275
+ dBmax = Get maximum: signal_start, anal_t2, "Parabolic"
276
+ # divide range by 2, since distance between lines = 2ST
277
+ dBmin = dBmax - ((ySTmax - ySTmin)/2) * 3
278
+ if (show_portee)
279
+ @gr_draw_portee: x1, x2, ySTmin, ySTmax, 2, ySTbottom
280
+ endif
281
+ if (needs_stylization and show_octavejump)
282
+ @gr_draw_octavejump: nucleiID, discontinuity_tier, x1, x2, red$
283
+ endif
284
+ if (show_f0 and not plot_f0_on_top)
285
+ @gr_plot_param_ST: pitchID, x1, x2, ySTbottom, ySTmax, blue$
286
+ endif
287
+ if (rich)
288
+ if (show_intensity)
289
+ if (greyscale)
290
+ 'win$'Dashed line
291
+ endif
292
+ @gr_plot_param_scaled: intensityID, x1, x2, 1, green$
293
+ 'win$'Solid line
294
+ endif
295
+ if (intbp_available and show_intbp)
296
+ @gr_plot_param_scaled: intbpID, x1, x2, 1, magenta$
297
+ endif
298
+ if (loudness_available)
299
+ selectObject: loudnessID
300
+ min = Get minimum: signal_start, anal_t2, "Parabolic"
301
+ max = Get maximum: signal_start, anal_t2, "Parabolic"
302
+ tmp = min - nrofplottedtiers*(max-min)/4
303
+ @gr_plot_param: loudnessID, x1, x2, tmp, max, cyan$
304
+ endif
305
+ if (show_harmonicity)
306
+ @gr_plot_param_scaled: harmonicityID, x1, x2, 0, purple$
307
+ endif
308
+ if (show_vuv)
309
+ @gr_plot_vuv: nucleiID, vuv_tier, x1, x2, "Black"
310
+ endif
311
+ if (needs_stylization)
312
+ @gr_plot_nuclei: nucleiID, x1, x2, red$
313
+ endif
314
+ if (show_length)
315
+ @gr_plot_prop_curve: nucleiID, nucldatID, j_nucldur, x1, x2, 0, 0.3, grey$, "Dashed"
316
+ @gr_plot_prop_curve: nucleiID, nucldatID, j_syllabledur, x1, x2, 0, 0.3, red$, "Dashed"
317
+ ; @gr_plot_prop_curve: nucleiID, nucldatID, j_onsetdur, x1, x2, 0, 0.3, cyan$, "Dashed"
318
+ endif
319
+ if (show_localrate)
320
+ @gr_plot_prop_curve: nucleiID, nucldatID, j_localrate_nucl, x1, x2, 0, 7, green$, "Solid"
321
+ endif
322
+ if (show_elasticity)
323
+ ; @table_stats: nucldatID, "syll_dur", "mean", "sd", "min", "max"
324
+ @gr_plot_prop_curve: nucleiID, nucldatID, j_syllabledur, x1, x2, -1, 1, grey$, "Dashed"
325
+ ; @table_stats: nucldatID, "en_sylldur", "mean", "sd", "min", "max"
326
+ @gr_plot_prop_curve: nucleiID, nucldatID, j_en_sylldur, x1, x2, -5, 5, green$, "Dashed"
327
+ ; @table_stats: nucldatID, "en_rhymedur", "mean", "sd", "min", "max"
328
+ @gr_plot_prop_curve: nucleiID, nucldatID, j_en_rhymedur, x1, x2, -5, 5, red$, "Dashed"
329
+ endif
330
+ endif
331
+
332
+ if (show_trajectories)
333
+ @gr_plot_prop_as_shape: "box_nucl", nucleiID, nucldatID, j_intrasyldown, x1, x2, -10, 10, "Cyan", "Solid"
334
+ @gr_plot_prop_as_shape: "box_nucl", nucleiID, nucldatID, j_intrasylup, x1, x2, -10, 10, "Blue", "Solid"
335
+ @gr_plot_prop_as_shape: "box_left", nucleiID, nucldatID, j_intersyl, x1, x2, -10, 10, "Green", "Solid"
336
+ endif
337
+
338
+ if (show_pitchrange)
339
+ @gr_plot_pitchrange: nucleiID, x1, x2, magenta$
340
+ endif
341
+
342
+ if (show_pauses)
343
+ if (rich)
344
+ @gr_plot_feature: nucleiID, nucldatID, j_pause_dur, x1, x2, "Right", 75, "#pause", "Blue"
345
+ else
346
+ @gr_plot_feature: nucleiID, nucldatID, j_before_pause, x1, x2, "Right", 75, "feature:P", "Blue"
347
+ endif
348
+ endif
349
+ if (show_hesitations)
350
+ @gr_plot_feature: nucleiID, nucldatID, j_hesitation, x1, x2, "Centre", 60, "feature:Hes", "Blue"
351
+ endif
352
+
353
+ if (show_prominence)
354
+ ; @plot_prominence_measures: x1, x2
355
+ ; @plot_prominence: nucleiID, nucldatID, "promL2D_nucldur", x1, x2, "Grey"
356
+ endif
357
+
358
+ if (show_rhythm)
359
+ ; @gr_plot_prop_curve: nucleiID, nucldatID, j_isodur, x1, x2, 0.0, 0.5, green$, "Solid"
360
+ ; @gr_plot_prop_curve: nucleiID, nucldatID, j_pcgapleft, x1, x2, 0.0, 1.0, cyan$, "Solid"
361
+ endif
362
+
363
+ if (needs_stylization)
364
+ @gr_plot_PitchTier_clip_nuclei: stylSTID, nucleiID, x1, x2, ySTbottom, ySTmax, draw_pitch_target_values, "Black"
365
+ endif
366
+ if (show_f0 and plot_f0_on_top)
367
+ @gr_plot_param_ST: pitchID, x1, x2, ySTbottom, ySTmax, blue$
368
+ endif
369
+ endif ; task <> task_annotation
370
+ endproc
371
+
372
+
373
+ procedure gr_on_input: .gridID
374
+ ; Read mouse and keyboard input and perform corresponding actions
375
+ ; Variables <x1> and <x2> give world X-coordinates (starttime and endtime of displayed window)
376
+ 'win$'Select inner viewport: 0, 100, 0, 100
377
+ 'win$'Axes: 0, 100, 0, 100
378
+ loop = 1
379
+ while (loop and demoWaitForInput ( ))
380
+ if demoClicked ( )
381
+ x0 = demoX ( )
382
+ y0 = demoY ( )
383
+ if demoClickedIn (dw_vx1, dw_vx2, dw_vy1, dw_vy2) ; clicked on prosogram
384
+ .t = x1 + ((x0-dw_vx1) / (dw_vx2-dw_vx1)) * (x2-x1) ; .t = position on time axis ; x1 = starttime ; x2 = endtime
385
+ if (.t < signal_finish)
386
+ @interval_from_time: .gridID, nucleus_tier, .t, "interval"
387
+ .t1 = Get starting point: nucleus_tier, interval
388
+ .t2 = Get end point: nucleus_tier, interval
389
+ @play_part: soundID, .t1, .t2
390
+ endif
391
+ elsif demoClickedIn (dw_Tx1, dw_Tx2, dw_Ty1, dw_Ty2) ; clicked textgrid
392
+ .t = x1 + ((x0-dw_Tx1) / (dw_Tx2-dw_Tx1)) * (x2-x1) ; .t = position on time axis
393
+ if (nrofplottedtiers > 0 and .t < signal_finish)
394
+ selectObject: newgridID
395
+ .n = Get number of tiers
396
+ .tier = ceiling ((y0-dw_Ty1)/((dw_Ty2-dw_Ty1)/.n))
397
+ .tier = min( max (1, .tier), .n)
398
+ .tier = .n - .tier + 1 ; tiers drawn from top to bottom
399
+ @interval_from_time: newgridID, .tier, .t, "interval"
400
+ .t1 = Get starting point: .tier, interval
401
+ .t2 = Get end point: .tier, interval
402
+ @play_part: soundID, max(.t1,x1), min(.t2,x2) ; play visible part of interval
403
+ endif
404
+ elsif demoClickedIn (dw_vx1, dw_vx2, dw_Ey1, dw_Ey2) ; clicked time bar (excerpt position)
405
+ .t = ((x0-dw_vx1) / (dw_vx2-dw_vx1)) * anal_t2 ; .t = position on time axis
406
+ if (.t < x1)
407
+ @gr_scroll: -timeincr
408
+ elsif (.t > x2)
409
+ @gr_scroll: timeincr
410
+ else
411
+ @play_part: soundID, x1, x2
412
+ endif
413
+ elsif demoClickedIn (dw_bx1, dw_bx2, dw_by1, dw_by2) ; clicked buttons
414
+ @gr_button_get
415
+ if (button == 1) ; |<< scroll to start of signal
416
+ @gr_scroll (0)
417
+ elsif (button == 2) ; << scroll left by timeincr
418
+ @gr_scroll (-timeincr)
419
+ elsif (button == 3) ; < scroll left by 0.25 s
420
+ @gr_scroll: -0.25
421
+ elsif (button == 4) ; play visible window
422
+ @gr_draw_button: 4, "Lime", "Play"
423
+ @play_part: soundID, x1, x2
424
+ @gr_draw_button: 4, "Yellow", "Play"
425
+ elsif (button == 5) ; > scroll right by 0.25 s
426
+ @gr_scroll: 0.25
427
+ elsif (button == 6) ; >> scroll right by timeincr
428
+ @gr_scroll: timeincr
429
+ elsif (button == 7) ; >>| scroll to end of signal
430
+ @gr_scroll: anal_t2
431
+ elsif (button == 8) ; zoom out (2 x)
432
+ @gr_zoom: 2
433
+ elsif (button == 9) ; zoom in (0.5 x)
434
+ @gr_zoom: 0.5
435
+ elsif (button == 11) ; resynthesize
436
+ @gr_draw_button: 11, "Lime", "Resynth"
437
+ @resynthesis: soundID, stylID, time_step, x1, x2
438
+ @gr_display_prosogram: x1, x2, ySTmin, ySTmax, grid_in_prosogram, 1
439
+ @gr_draw_button: 11, "Yellow", "Resynth"
440
+ ;elsif (button == 12) ; auto play and scroll
441
+ ; call gr_draw_button 12 Lime Stop
442
+ ; call play_part soundID x1 x2
443
+ ; while (x2 < anal_t2)
444
+ ; call gr_scroll timeincr
445
+ ; call gr_draw_button 12 Lime Stop
446
+ ; call play_part soundID x1 x2
447
+ ; endwhile
448
+ ; call gr_draw_button 12 Yellow Play &~Scroll
449
+ elsif (button == 12) ; Rich / Light view
450
+ @toggle: "rich"
451
+ @gr_redraw: x1, x2
452
+ elsif (button == 13) ; Show Pitch range
453
+ @toggle: "show_pitchrange"
454
+ @gr_redraw: x1, x2
455
+ elsif (button == 14) ; Show Pitch values
456
+ @steps_012: "draw_pitch_target_values"
457
+ @gr_redraw: x1, x2
458
+ elsif (button == 15) ; Refresh (needed after resize window)
459
+ @gr_clearscreen
460
+ @gr_redraw: x1, x2
461
+ elsif (button == 16) ; Exit
462
+ @gr_clearscreen
463
+ @gr_printline: "Now kill window..."
464
+ loop = 0
465
+ endif
466
+ endif
467
+ elsif demoKeyPressed ( )
468
+ key$ = demoKey$ ( )
469
+ if (key$ = "R")
470
+ @gr_scroll: timeincr
471
+ elsif (key$ = "L")
472
+ @gr_scroll: -timeincr
473
+ ;else
474
+ ; shift = demoShiftKeyPressed ()
475
+ ; @msg: "KeyPressed='key$' shift='shift'"
476
+ endif
477
+ endif
478
+ 'win$'Select inner viewport: 0, 100, 0, 100
479
+ 'win$'Axes: 0, 100, 0, 100
480
+ endwhile
481
+ endproc
482
+
483
+
484
+ procedure resynthesis: soundinID, pitchtierinID, time_step, x1, x2
485
+ ; Make a copy of part of the pitch tier
486
+ selectObject: pitchtierinID ; values in Hz
487
+ .j1 = Get high index from time: x1
488
+ .j2 = Get low index from time: x2
489
+ tmppitchtierID = Create PitchTier: "tmp", x1, x2
490
+ for .j from .j1 to .j2
491
+ selectObject: pitchtierinID
492
+ .v = Get value at index: .j
493
+ .t = Get time from index: .j
494
+ selectObject: tmppitchtierID
495
+ Add point: .t, .v
496
+ endfor
497
+ ; Make a copy of part of the speech signal and get resynthesis
498
+ selectObject: soundinID
499
+ tmpsoundID = Extract part: x1, x2, "rectangular", 1.0, "yes"
500
+ manipID = To Manipulation: time_step, 60, 600
501
+ selectObject: tmppitchtierID
502
+ plus manipID
503
+ Replace pitch tier
504
+ selectObject: manipID
505
+ synthID = Get resynthesis (overlap-add)
506
+ ; Plot PitchTier
507
+ @gr_plot_PitchTier: stylSTID, x1, x2, "Lime"
508
+ selectObject: synthID
509
+ Play
510
+ ; Write to WAV file: "tmp_resynth.wav"
511
+ removeObject: manipID, tmppitchtierID, tmpsoundID, synthID
512
+ ; @gr_display_prosogram: x1, x2, ySTmin, ySTmax, grid_in_prosogram, 1
513
+ endproc
514
+
515
+
516
+ procedure gr_draw_buttons
517
+ nrof_buttons = 16 ; room for 16 buttons of equal size (1 row horizontally)
518
+ 'win$'Select inner viewport: dw_bx1, dw_bx2, dw_by1, dw_by2
519
+ 'win$'Axes: dw_bx1, dw_bx2, dw_by1, dw_by2
520
+ @gr_clear_rectangle (dw_ovx1, dw_ovx2, dw_by1, dw_by2) ; clear buttons area, including left and right margins
521
+ # Define button positions
522
+ .size = (dw_bx2-dw_bx1)/nrof_buttons
523
+ for j to nrof_buttons
524
+ button'j'_x1 = dw_bx1 + (j-1)*.size + .size*0.1
525
+ button'j'_x2 = button'j'_x1 + .size*0.9
526
+ endfor
527
+ @gr_draw_button: 1, "Yellow", "|<<"
528
+ @gr_draw_button: 2, "Yellow", "<<"
529
+ @gr_draw_button: 3, "Yellow", "<"
530
+ @gr_draw_button: 4, "Yellow", "Play"
531
+ @gr_draw_button: 5, "Yellow", ">"
532
+ @gr_draw_button: 6, "Yellow", ">>"
533
+ @gr_draw_button: 7, "Yellow", ">>|"
534
+ @gr_draw_button: 8, "Yellow", "Zoom~Out"
535
+ @gr_draw_button: 9, "Yellow", "Zoom~In"
536
+ @gr_draw_button: 11, "Yellow", "Resynth"
537
+ @gr_draw_button: 12, "Cyan", "Rich~View"
538
+ @gr_draw_button: 13, "Cyan", "Pitch~Range"
539
+ @gr_draw_button: 14, "Cyan", "Show~Values"
540
+ @gr_draw_button: 15, "Yellow", "Refresh"
541
+ @gr_draw_button: 16, "Magenta", "Exit"
542
+ endproc
543
+
544
+
545
+ procedure gr_draw_button: nr, .color$, .text$
546
+ .x1 = button'nr'_x1
547
+ .x2 = button'nr'_x2
548
+ .x = .x1 + (.x2 - .x1)/2
549
+ .y = dw_by1 + (dw_by2 - dw_by1)/2
550
+ 'win$'Select inner viewport: dw_bx1, dw_bx2, dw_by1, dw_by2
551
+ 'win$'Axes: dw_bx1, dw_bx2, dw_by1, dw_by2
552
+ 'win$'Paint rectangle: .color$, .x1, .x2, dw_by1, dw_by2
553
+ 'win$'Black
554
+ 'win$'Draw rectangle: .x1, .x2, dw_by1, dw_by2
555
+ .pos = index (.text$, "~")
556
+ if (.pos > 0)
557
+ .s$ = left$ (.text$, .pos - 1)
558
+ 'win$'Text special: .x, "centre", .y, "bottom", "Helvetica", button_fontsize, "0", .s$
559
+ .s$ = right$ (.text$, length(.text$) - .pos)
560
+ 'win$'Text special: .x, "centre", .y, "top", "Helvetica", button_fontsize, "0", .s$
561
+ else
562
+ 'win$'Text special: .x, "centre", .y, "half", "Helvetica", button_fontsize, "0", .text$
563
+ endif
564
+ endproc
565
+
566
+
567
+ procedure gr_button_get
568
+ # Set <button> to number of button clicked or zero if no button clicked
569
+ button = 0
570
+ for j from 1 to nrof_buttons
571
+ if demoClickedIn (button'j'_x1, button'j'_x2, dw_by1, dw_by2)
572
+ button = j
573
+ j = nrof_buttons + 1
574
+ endif
575
+ endfor
576
+ endproc
577
+
578
+
579
+ procedure gr_zoom: factor
580
+ ;@msg: "gr_zoom: factor='factor' x1='x1:3' x2='x2:3' anal_t1='anal_t1:3' anal_t2='anal_t2:3' timeincr='timeincr:3'"
581
+ .x = x1 + (x2-x1)/2
582
+ timeincr = max (1, factor * timeincr) ; the time interval should be at least 1 s
583
+ x1 = max (.x - timeincr/2, anal_t1) ; no zooming out beyond signal boundaries
584
+ x2 = min (.x + timeincr/2, anal_t2) ; no zooming out beyond signal boundaries
585
+ ;@msg: "gr_zoom: exit x1='x1:3' x2='x2:3' timeincr='timeincr:3'"
586
+ @gr_redraw: x1, x2
587
+ endproc
588
+
589
+
590
+ procedure gr_scroll: amount
591
+ ;@msg: "gr_scroll: amount='amount' x1='x1:3' x2='x2:3' anal_t1='anal_t1:3' anal_t2='anal_t2:3' timeincr='timeincr:3'"
592
+ if (amount = 0)
593
+ x1 = anal_t1
594
+ endif
595
+ x1 = min (x1 + amount, anal_t2 - timeincr) ; no scrolling beyond endtime of analysis
596
+ x1 = max (x1, anal_t1) ; no scrolling beyond starttime of analysis
597
+ x2 = min (x1 + timeincr, anal_t2) ; no scrolling beyond endtime of analysis
598
+ ;@msg: "gr_scroll: exit x1='x1:3' x2='x2:3'"
599
+ @gr_redraw: x1, x2
600
+ endproc
601
+
602
+
603
+ procedure gr_draw_calib: .x1, .y1, .x2
604
+ # Draw horizontal dotted line from <.x1, .y1> to <.x2, .y1> (Some graphics viewers display Praat's Dotted lines as solid ones.)
605
+ if (.x2 > .x1)
606
+ 'win$'Solid line
607
+ .dx1 = (.x2-.x1)/200 ; 200 dots per line
608
+ .dx2 = .dx1*0.3 ; dot shorter than whitespace
609
+ .x = .x1 + .dx2
610
+ while (.x1 <= .x2)
611
+ 'win$'Draw line: .x1, .y1, min(.x,.x2), .y1
612
+ .x1 += .dx1
613
+ .x = .x1 + .dx2
614
+ endwhile
615
+ endif
616
+ endproc
617
+
618
+
619
+ procedure gr_draw_portee: .x1, .x2, .ymin, .ymax, .ystep, .ybottom
620
+ # Draw horizontal calibration lines which are <.ystep> apart from <.ybottom> to <.ymax>
621
+ 'win$'Axes: .x1, .x2, .ybottom, .ymax
622
+ # Draw calibration lines
623
+ 'win$'Grey
624
+ 'win$'Line width: 1
625
+ .y = ceiling (.ymin/2) * 2
626
+ while (.y < .ymax)
627
+ @gr_draw_calib: .x1, .y, .x2
628
+ .y += .ystep
629
+ endwhile
630
+ endproc
631
+
632
+
633
+ procedure gr_plot_textgrid: .gridID, .x1, .x2
634
+ if (demowin)
635
+ 'win$'Select inner viewport: dw_vx1, dw_vx2, dw_vy1, dw_vy2
636
+ endif
637
+ 'win$'Black
638
+ 'win$'Line width: 1
639
+ 'win$'Solid line
640
+ selectObject: .gridID
641
+ @debug_msg: "gr_plot_textgrid: show_tg_bound='show_tg_bound'"
642
+ # Draw: From, To, ShowBoundaries, UseTextstyles, Garnish
643
+ if (task == task_annotation or not show_tg_bound)
644
+ 'win$'Draw: .x1, .x2, "no", "no", "no"
645
+ else
646
+ 'win$'Draw: .x1, .x2, "yes", "no", "no"
647
+ endif
648
+ endproc
649
+
650
+
651
+ procedure gr_draw_tiernames: .gridID, .x1, .x2
652
+ ;if (not demowin)
653
+ .y1 = ySTbottom
654
+ .y2 = ySTmax
655
+ 'win$'Line width: 1
656
+ 'win$'Solid line
657
+ 'win$'Black
658
+ if (demowin)
659
+ 'win$'Red
660
+ endif
661
+ 'win$'Axes: .x1, .x2, .y1, .y2
662
+ selectObject: .gridID
663
+ .n = Get number of tiers
664
+ .dyN = (ySTmin - ySTbottom)/.n ; height of a tier
665
+ for .tier from 1 to .n
666
+ .ylo = .y1 + (.n - .tier) * .dyN
667
+ .yt = .ylo + (.dyN)/2
668
+ .tiername$ = Get tier name: .tier
669
+ 'win$'Text special: .x2+(.x2-.x1)*0.005, "left", .yt, "half", "Helvetica", small_fontsize, "33", .tiername$
670
+ endfor
671
+ 'win$'Black
672
+ ;endif
673
+ endproc
674
+
675
+
676
+ procedure gr_display_textgrid_pure: .gridID, .x1, .x2, .vpx1, .vpx2, .vpy1, .vpy2
677
+ ; Draw textgrid rather than using Praat's built-in Draw command
678
+ 'win$'Select inner viewport: .vpx1, .vpx2, .vpy1, .vpy2
679
+ 'win$'Axes: .vpx1, .vpx2, .vpy1, .vpy2
680
+ ; Clear the area
681
+ 'win$'Paint rectangle: "White", .vpx1, .vpx2, .vpy1, .vpy2
682
+ 'win$'Black
683
+ 'win$'Line width: 1
684
+ 'win$'Solid line
685
+ selectObject: .gridID
686
+ .n = Get number of tiers
687
+ .y1 = 0
688
+ .y2 = 1
689
+ .dyN = (.y2 - .y1)/.n
690
+ 'win$'Axes: .x1, .x2, .y1, .y2
691
+ 'win$'Draw inner box
692
+ for .tier from 1 to .n
693
+ .ylo = (.n - .tier) * .dyN
694
+ .yhi = .ylo + .dyN
695
+ 'win$'Draw line: .x1, .yhi, .x2, .yhi
696
+ @interval_from_time: .gridID, .tier, .x1, "first_interval"
697
+ @interval_from_time: .gridID, .tier, .x2, "last_interval"
698
+ for .interval from first_interval to last_interval
699
+ .ix1 = Get starting point: .tier, .interval
700
+ .ix2 = Get end point: .tier, .interval
701
+ .ix1 = max (.ix1, .x1)
702
+ .ix2 = min (.ix2, .x2)
703
+ .label$ = Get label of interval: .tier, .interval
704
+ ;.label$ = replace$ (.label$, "_", "\_ ", 0) ; avoid interpretation of underscore as subscript
705
+ ;.label$ = replace$ (.label$, "%", "\% ", 0) ; avoid interpretation of percent as italic text style
706
+ 'win$'Draw line: .ix2, .ylo, .ix2, .yhi
707
+ .xt = .ix1 + (.ix2 - .ix1)/2
708
+ .yt = .ylo + (.yhi - .ylo)/2
709
+ 'win$'Text special: .xt, "centre", .yt, "half", font_family$, fontsize, "0", .label$
710
+ endfor
711
+ if (show_tiernames)
712
+ ; Draw tier name
713
+ .tiername$ = Get tier name: .tier
714
+ 'win$'Red
715
+ 'win$'Text special: .x2+(.x2-.x1)*0.005, "left", .yt, "half", font_family$, default_fontsize, "33", .tiername$
716
+ endif
717
+ 'win$'Black
718
+ endfor
719
+ endproc
720
+
721
+
722
+ procedure gr_garnish: x1, x2, ybot, y1, y2, ystep, .fname$, .font$, .nfiles
723
+ ; Y axis on ST scale : ybot = bottom of textgrid, y1 = bottom (min) of drawing, y2 = top (max) of drawing, ystep = y-distance between calibration marks for values
724
+ ; <.fname$> name of file
725
+ ; <.font$> font family used for garnish
726
+ @debug_msg: "gr_garnish: show_y_scale='show_y_scale' show_tiernames='show_tiernames'"
727
+ ; .font$ = "Helvetica"
728
+ # Draw border of viewport
729
+ 'win$'Black
730
+ 'win$'Line width: 1
731
+ 'win$'Solid line
732
+ 'win$'Axes: x1, x2, ybot, y2
733
+ 'win$'Draw inner box
734
+ # Time calibration marks
735
+ ;'win$'Font size: small_fontsize ; Change of font size will affect viewport definition
736
+ 'win$''.font$'
737
+ if (viewsize$ = "compact")
738
+ show_x_scale = 0
739
+ endif
740
+ if (show_x_scale) ; numbers, ticks, dotted lines
741
+ 'win$'Marks top every: 1, 0.1, "no", "yes", "no"
742
+ 'win$'Marks top every: 1, 1, "yes", "yes", "no"
743
+ else
744
+ 'win$'Marks top every: 1, 0.1, "no", "yes", "no"
745
+ endif
746
+ # Y axis calibration
747
+ ;if (not demowin)
748
+ if (show_y_scale)
749
+ # Show ST scale in left margin
750
+ # 'win$'Marks left every: 1, ystep, "yes", "yes", "no"
751
+ .y = (floor (y2/ystep) * ystep) - ystep/4
752
+ 'win$'Text special: x1, "right", .y, "half", .font$, small_fontsize, "0", "ST "
753
+ .x0 = x1-(x2-x1)/200
754
+ .yST = 10 * floor((y1+10)/10)
755
+ while (.yST <= y2)
756
+ 'win$'Draw line: .x0, .yST, x1, .yST
757
+ 'win$'Text special: .x0, "Right", .yST, "Half", .font$, small_fontsize, "0", fixed$(.yST,0)
758
+ .yST += ystep
759
+ endwhile
760
+ if (show_y_scale_r)
761
+ # Show Hz scale in right margin
762
+ 'win$'Black
763
+ 'win$'Solid line
764
+ .ystepHz = 25
765
+ .yHz = semitonesToHertz(y1 + hertzToSemitones(1)) ; lower frequency value
766
+ .yHz = max(50, .yHz)
767
+ .ystepHz = 25
768
+ if (.yHz < 75)
769
+ .yHz = 75
770
+ else
771
+ .yHz = ceiling(.yHz/50) * 50
772
+ endif
773
+ .y2Hz = semitonesToHertz(y2 + hertzToSemitones(1)) ; upper frequency value
774
+ .x3 = x2+(x2-x1)/200 ; length of mark
775
+ while (.yHz <= .y2Hz)
776
+ .yST = hertzToSemitones(.yHz) - hertzToSemitones(1)
777
+ if (.yHz >= 300)
778
+ .ystepHz = 100
779
+ elsif (.yHz >= 100)
780
+ .ystepHz = 50
781
+ endif
782
+ 'win$'Draw line: x2, .yST, .x3, .yST
783
+ .s$ = fixed$(.yHz,0)
784
+ if (.yHz + .ystepHz >= .y2Hz)
785
+ .s$ = .s$ + " Hz"
786
+ endif
787
+ 'win$'Text special: .x3, "Left", .yST, "Half", .font$, small_fontsize, "0", .s$
788
+ .yHz += .ystepHz
789
+ endwhile
790
+ 'win$'Black
791
+ endif ; show_y_scale_r
792
+ else
793
+ ; 'win$'Marks left every: 1, ystep, "no", "yes", "no"
794
+ endif
795
+ ;endif
796
+ .settings$ = ""
797
+ if (show_settings) ; Show analysis settings : segmentation mode, glissando threshold
798
+ if (adaptive_glissando)
799
+ s$ = "G(adapt)='glissando_low'-'glissando'/T^2"
800
+ else
801
+ s$ = "G='glissando'/T^2"
802
+ endif
803
+ .settings$ = "'segmentation_name$', " + s$ + ", DG='diffgt', dmin='mindur_ts:3'"
804
+ ; 'win$'Text special: x2, "Right", y2, "Top", .font$, small_fontsize, "0.0", .settings$
805
+ endif
806
+ if (not demowin and show_settings)
807
+ # Print version identification
808
+ s$ = .settings$ + " \-- " + version$
809
+ 'win$'Text special: x2, "Right", ybot, "Top", .font$, small_fontsize, "0.0", s$
810
+ # Show end of signal by double vertical line
811
+ if (x2 > signal_finish)
812
+ 'win$'Line width: 3
813
+ 'win$'Draw line: signal_finish, ybot, signal_finish, y2
814
+ 'win$'Line width: 1
815
+ endif
816
+ if (.nfiles > 1 or file_stamp)
817
+ if (file_stamp)
818
+ .s$ = replace$(.fname$, "_", "\_ ", 0)
819
+ if (viewsize$ = "compact")
820
+ .s$ = .s$ + "('x1:2'-'x2:2's)"
821
+ endif
822
+ 'win$'Text special: x1, "Left", ybot, "Top", .font$, small_fontsize, "0.0", .s$
823
+ endif
824
+ endif
825
+ endif
826
+ ; restore default font:
827
+ 'win$''font_family$'
828
+ endproc
829
+
830
+
831
+ procedure gr_plot_param_ST: .paramID, .x1, .x2, .y1, .y2, .color$
832
+ 'win$''.color$'
833
+ selectObject: .paramID
834
+ # diffST = difference in ST between ST-scale relative to 100Hz and that rel to 1Hz
835
+ .diffST = 12 * log2(100/1)
836
+ 'win$'Draw semitones: .x1, .x2, .y1-.diffST, .y2-.diffST, "no"
837
+ endproc
838
+
839
+
840
+ procedure gr_plot_param: .paramID, .x1, .x2, .y1, .y2, .color$
841
+ # Plot parameter paramID in current viewport
842
+ 'win$''.color$'
843
+ 'win$'Line width: 1
844
+ selectObject: .paramID
845
+ 'win$'Draw: .x1, .x2, .y1, .y2, "no"
846
+ endproc
847
+
848
+
849
+ procedure gr_plot_param_scaled: .paramID, .x1, .x2, .garnish, .color$
850
+ 'win$''.color$'
851
+ 'win$'Line width: 1
852
+ selectObject: .paramID
853
+ .y2 = Get maximum: anal_t1, anal_t2, "Parabolic"
854
+ .y1 = .y2 - ((ySTmax - ySTmin)/2) * 3
855
+ if (with_grid)
856
+ .y1 -= nrofplottedtiers*(.y2-.y1)/4
857
+ endif
858
+ if (.garnish) ; objects for which Draw includes "garnish" option
859
+ 'win$'Draw: .x1, .x2, .y1, .y2, "no"
860
+ else
861
+ 'win$'Draw: .x1, .x2, .y1, .y2
862
+ endif
863
+ endproc
864
+
865
+
866
+ procedure gr_draw_zigzag: .lx1, .lxend, .ldx, .lystart, .ldy
867
+ # Draw a horizontal zigzag line from <.lx1> to <.lxend>, with x-steps of <.ldx>
868
+ # starting from <.lystart> moving up by <.ldy> and back to <.lystart>
869
+ .ldir = 1 ; up
870
+ .ly1 = .lystart - .ldy/2
871
+ .ly2 = .lystart + .ldy/2
872
+ while (.lx1 < .lxend)
873
+ .lx = .lx1 + .ldx
874
+ if (.lx > .lxend)
875
+ .lx = .lxend
876
+ .ly2 = .ly1 + .ldir*(.ldy*(.lx-.lx1)/.ldx)
877
+ endif
878
+ 'win$'Draw line: .lx1, .ly1, .lx, .ly2
879
+ .lx1 += .ldx
880
+ .ldir = .ldir * -1 ; change direction
881
+ .tmp = .ly1
882
+ .ly1 = .ly2
883
+ .ly2 = .tmp
884
+ endwhile
885
+ endproc
886
+
887
+
888
+ procedure gr_plot_vuv: .gridID, .tier, .x1, .x2, .color$
889
+ # Draw VUV data contained in tier 1 of <gridID>, from time <x1> to <x2>
890
+ .ldx = (.x2 - .x1) / 200
891
+ .ldy = (ySTmax - ySTbottom) / 50
892
+ .ly = ySTmin + .ldy
893
+ .ly1 = .ly - .ldy/2
894
+ .ly2 = .ly + .ldy/2
895
+ 'win$'Axes: .x1, .x2, ySTbottom, ySTmax
896
+ selectObject: .gridID
897
+ @interval_from_time: .gridID, .tier, .x1, "first_interval"
898
+ @interval_from_time: .gridID, .tier, .x2, "last_interval"
899
+ 'win$''.color$'
900
+ for .i from first_interval to last_interval
901
+ .label$ = Get label of interval: .tier, .i
902
+ if (.label$ = "V")
903
+ .t1 = Get start time of interval: .tier, .i
904
+ .t2 = Get end time of interval: .tier, .i
905
+ if (.t1 >= .x1)
906
+ 'win$'Draw line: .t1, .ly1, .t1, .ly2
907
+ endif
908
+ if (.t2 <= .x2)
909
+ 'win$'Draw line: .t2, .ly1, .t2, .ly2
910
+ endif
911
+ .lx1 = max (.x1, .t1)
912
+ .lx2 = min (.x2, .t2)
913
+ @gr_draw_zigzag: .lx1, .lx2, .ldx, .ly, .ldy
914
+ endif
915
+ endfor
916
+ endproc
917
+
918
+
919
+ procedure gr_plot_nuclei: .gridID, .x1, .x2, .color_$
920
+ # Draw nuclei in nucleus_tier of <gridID>, from time <x1> to <x2> at the bottom of the current viewport
921
+ .ldy = (ySTmax - ySTbottom) / 50 ; divide Y-range in 50 parts
922
+ .ly = ySTmin + .ldy
923
+ .ly1 = .ly - .ldy*0.80
924
+ .ly2 = .ly + .ldy*0.80
925
+ 'win$'Axes: .x1, .x2, ySTbottom, ySTmax
926
+ selectObject: .gridID
927
+ @interval_from_time: .gridID, nucleus_tier, .x1, "first_interval"
928
+ @interval_from_time: .gridID, nucleus_tier, .x2, "last_interval"
929
+ 'win$''.color_$'
930
+ for .i from first_interval to last_interval
931
+ .label$ = Get label of interval: nucleus_tier, .i
932
+ if (.label$ = "a")
933
+ .t1 = Get start time of interval: nucleus_tier, .i
934
+ .t2 = Get end time of interval: nucleus_tier, .i
935
+ if (.t1 >= .x1) ; draw left side
936
+ 'win$'Draw line: .t1, .ly1, .t1, .ly2
937
+ endif
938
+ if (.t2 <= .x2) ; draw right side
939
+ 'win$'Draw line: .t2, .ly1, .t2, .ly2
940
+ endif
941
+ .lx1 = max (.x1, .t1)
942
+ .lx2 = min (.x2, .t2)
943
+ 'win$'Draw line: .lx1, .ly1, .lx2, .ly1
944
+ 'win$'Draw line: .lx1, .ly2, .lx2, .ly2
945
+ endif
946
+ endfor
947
+ endproc
948
+
949
+
950
+ procedure gr_plot_pitchrange: .gridID, .x1, .x2, .color$
951
+ # Draw pitchrange (median, top and bottom) using <gridID>, from time <.x1> to <.x2> in the current viewport.
952
+ 'win$'Axes: .x1, .x2, ySTbottom, ySTmax
953
+ selectObject: .gridID
954
+ @interval_from_time: .gridID, speaker_tier, .x1, "first_interval"
955
+ @interval_from_time: .gridID, speaker_tier, .x2, "last_interval"
956
+ 'win$'Dashed line
957
+ 'win$'Line width: pitchrange_linewidth
958
+ for .i from first_interval to last_interval
959
+ .t1 = Get start time of interval: speaker_tier, .i
960
+ .t2 = Get end time of interval: speaker_tier, .i
961
+ if (speaker_available)
962
+ speaker$ = Get label of interval: speaker_tier, .i
963
+ speaker_j = extractNumber (speakers$, "<'speaker$'>:") ; find speaker number
964
+ else
965
+ speaker_j = 1
966
+ endif
967
+ if (speaker_j == undefined)
968
+ ; This happens when there are no nuclei found for this speaker.
969
+ ; @msg: "gr_plot_pitchrange: undefined speaker=<'speaker$'> i='i' t1='.t1' t2='.t2' speakers='speakers$'"
970
+ else
971
+ 'win$''.color$'
972
+ 'win$'Line width: pitchrange_linewidth
973
+ .ly1 = extractNumber (speaker_range_'speaker_j'$, "BOTTOM_ST=")
974
+ .ly2 = extractNumber (speaker_range_'speaker_j'$, "TOP_ST=")
975
+ if (.t1 >= .x1) ; draw left side
976
+ 'win$'Draw line: .t1, .ly1, .t1, .ly2
977
+ endif
978
+ if (.t2 <= .x2) ; draw right side
979
+ 'win$'Draw line: .t2, .ly1, .t2, .ly2
980
+ endif
981
+ .lx1 = max (.x1, .t1)
982
+ .lx2 = min (.x2, .t2)
983
+ 'win$'Draw line: .lx1, .ly1, .lx2, .ly1
984
+ 'win$'Draw line: .lx1, .ly2, .lx2, .ly2
985
+ .ly1 = extractNumber (speaker_range_'speaker_j'$, "MEDIAN_ST=")
986
+ 'win$'Draw line: .lx1, .ly1, .lx2, .ly1
987
+ if (speaker_available)
988
+ .s$ = speaker_label'speaker_j'$
989
+ 'win$'Text special: .lx1, "Left", .ly2, "Bottom", font_family$, small_fontsize, "0", .s$
990
+ endif
991
+ endif
992
+ endfor
993
+ 'win$'Solid line
994
+ 'win$'Black
995
+ endproc
996
+
997
+
998
+ procedure gr_draw_octavejump: nucleiID, .tier, .time1, .time2, .color$
999
+ # Draw octavejumps in tier 2 of <nucleiID>
1000
+ 'win$''.color$'
1001
+ .y = ySTmin + (ySTmax - ySTmin) / 2 ; y-position to draw
1002
+ selectObject: nucleiID
1003
+ .ni = Get number of points: .tier
1004
+ for .i to .ni
1005
+ .x = Get time of point: .tier, .i
1006
+ if (.x >= .time1 and .x <= .time2)
1007
+ 'win$'Text: .x, "Centre", .y, "Half", "\ox"
1008
+ endif
1009
+ endfor
1010
+ endproc
1011
+
1012
+
1013
+ procedure gr_plot_PitchTier_clip_nuclei: .paramID, .nucleiID, .x1, .x2, .y1, .y2, .draw_pitch_target_values, .color$
1014
+ @debug_msg: "gr_plot_PitchTier_clip_nuclei: entry, '.x1:3' - '.x2:3'"
1015
+ 'win$'Axes: .x1, .x2, .y1, .y2
1016
+ if (clip_to_Y_range)
1017
+ selectObject: .paramID
1018
+ .tmp_pitchTierID = Copy: "tmp_pitchtier"
1019
+ selectObject: .tmp_pitchTierID
1020
+ @clipPitchTier: .tmp_pitchTierID, .y1, .y2, .x1, .x2
1021
+ @gr_plot_stylisation: .tmp_pitchTierID, .nucleiID, .x1, .x2, .color$
1022
+ removeObject: .tmp_pitchTierID
1023
+ else
1024
+ @gr_plot_stylisation: .paramID, .nucleiID, .x1, .x2, .draw_pitch_target_values, .color$
1025
+ endif
1026
+ endproc
1027
+
1028
+
1029
+ procedure gr_plot_stylisation: .paramID, nucleiID, .x1, .x2, .draw_pitch_target_values, .color$
1030
+ # Plot stylization **inside** nuclei
1031
+ # <x1>..<x2> times at borders of graphics window (viewport)
1032
+ @debug_msg: "gr_plot_stylisation: entry '.x1:3' - '.x2:3'"
1033
+ # .diffST = difference in ST between ST-scale relative to 100Hz and that rel to 1Hz
1034
+ .diffST = 12 * log2(100/1)
1035
+ 'win$''.color$'
1036
+ 'win$'Line width: stylization_linewidth
1037
+ @interval_from_time: nucleiID, nucleus_tier, .x1, "first_interval"
1038
+ @interval_from_time: nucleiID, nucleus_tier, .x2, "last_interval"
1039
+ ; @msg: "gr_plot_stylisation: first 'first_interval' - last 'last_interval'"
1040
+ selectObject: .paramID ; stylization (PitchTier)
1041
+ .np = Get number of points
1042
+ for .i from first_interval to last_interval ; indices of nuclei for which to plot stylization
1043
+ selectObject: nucleiID ; segmentation into nuclei, etc
1044
+ @is_nucleus: .i
1045
+ if (result)
1046
+ .nx1 = Get start time of interval: nucleus_tier, .i
1047
+ .nx2 = Get end time of interval: nucleus_tier, .i
1048
+ # Check that the nearest indices of stylization PitchTier are within nucleus
1049
+ selectObject: .paramID ; stylization (PitchTier)
1050
+ .i1 = Get nearest index from time: .nx1
1051
+ repeat
1052
+ .t = Get time from index: .i1
1053
+ if (.t < .nx1)
1054
+ .i1 += 1
1055
+ endif
1056
+ until (.t >= .nx1 or .t >= .nx2 or .i1 >= .np)
1057
+ .i2 = Get nearest index from time: .nx2
1058
+ repeat
1059
+ .t = Get time from index: .i2
1060
+ if (.t > .nx2)
1061
+ .i2 -= 1
1062
+ endif
1063
+ until (.t <= .nx2 or .t <= .nx1 or .i2 <= 1)
1064
+ for .j from .i1 to .i2-1 ; each tonal segment .j within nucleus
1065
+ .ox1 = Get time from index: .j
1066
+ .oy1 = Get value at index: .j
1067
+ .ox2 = Get time from index: .j+1
1068
+ .oy2 = Get value at index: .j+1
1069
+ if (.ox2 > .x1 and .ox1 < .x2)
1070
+ ; find visible part (within graphics window) of stylization for tonal segment .j
1071
+ .lx1 = .ox1
1072
+ .lx2 = .ox2
1073
+ .ly1 = .oy1
1074
+ .ly2 = .oy2
1075
+ if (.ox1 < .x1) ; tonal segment start outside visible area
1076
+ .ly1 = .oy1 + (.oy2-.oy1)*(.x1-.ox1)/(.ox2-.ox1) ; find y at x1
1077
+ .lx1 = .x1
1078
+ endif
1079
+ if (.ox2 > .x2) ; tonal segment ends outside visible area
1080
+ .ly2 = .oy1 + (.oy2-.oy1)*(.x2-.ox1)/(.ox2-.ox1) ; find y at x2
1081
+ .lx2 = .x2
1082
+ endif
1083
+ 'win$'Draw line: .lx1, .ly1, .lx2, .ly2
1084
+ if (.draw_pitch_target_values)
1085
+ .y1 = .ly1
1086
+ .y2 = .ly2
1087
+ .prec = 1 ; precision, when values in ST
1088
+ if (.draw_pitch_target_values = 2) ; show values in Hz, otherwise in ST
1089
+ .y1 = semitonesToHertz(.y1-.diffST)
1090
+ .y2 = semitonesToHertz(.y2-.diffST)
1091
+ .prec = 0 ; precision, when values in Hz
1092
+ endif
1093
+ .offs = 1
1094
+ if (.ly1 <> .ly2)
1095
+ 'win$'Text special: .lx1, "Left", .ly1+.offs, "Half", "Helvetica", small_fontsize, "90", fixed$(.y1,.prec)
1096
+ 'win$'Text special: .lx2, "Left", .ly2+.offs, "Half", "Helvetica", small_fontsize, "90", fixed$(.y2,.prec)
1097
+ else
1098
+ 'win$'Text special: .lx1+(.lx2-.lx1)/2, "Left", .ly1+.offs, "Half", "Helvetica", small_fontsize, "90", fixed$(.y1,.prec)
1099
+ endif
1100
+ endif
1101
+ endif
1102
+ endfor
1103
+ endif
1104
+ endfor
1105
+ 'win$'Line width: 1
1106
+ @debug_msg: "gr_plot_stylisation: exit"
1107
+ endproc
1108
+
1109
+
1110
+ procedure gr_plot_PitchTier: .objectID, .x1, .x2, .color$
1111
+ if (demowin)
1112
+ 'win$'Select inner viewport: dw_vx1, dw_vx2, dw_vy1, dw_vy2
1113
+ endif
1114
+ 'win$'Axes: .x1, .x2, ySTbottom, ySTmax
1115
+ selectObject: .objectID
1116
+ 'win$''.color$'
1117
+ 'win$'Draw: .x1, .x2, ySTmin, ySTmax, "no"
1118
+ endproc
1119
+
1120
+
1121
+ ; procedure gr_plot_values: .col, .gridID, .x1, .x2, .y1, .y2, .color$
1122
+ ; # For nuclei in <gridID> in time range <.x1>..<.x2>, draw value for <.col> as text
1123
+ ; 'win$'Axes: .x1, .x2, .y1, .y2
1124
+ ; selectObject: .gridID
1125
+ ; .ni = Get number of intervals: nucleus_tier
1126
+ ; @interval_from_time: .gridID, nucleus_tier, .x1, "first_interval"
1127
+ ; @interval_from_time: .gridID, nucleus_tier, .x2, "last_interval"
1128
+ ; 'win$''.color$'
1129
+ ; for .i from first_interval to last_interval
1130
+ ; selectObject: .gridID
1131
+ ; .label$ = Get label of interval: nucleus_tier, .i
1132
+ ; if (.label$ = "a")
1133
+ ; .t1 = Get start time of interval: nucleus_tier, .i
1134
+ ; .t2 = Get end time of interval: nucleus_tier, .i
1135
+ ; .t = .t1 + (.t2-.t1)/2
1136
+ ; .s$ = Get label of interval: pointer_tier, .i
1137
+ ; .row = number(.s$)
1138
+ ; if (.row <= nrof_nuclei_analysed)
1139
+ ; selectObject: nucldatID
1140
+ ; .v = Get value: .row, .col
1141
+ ; .yST = hertzToSemitones(.v) - hertzToSemitones(1)
1142
+ ; 'win$'Text special: .t, "Centre", .yST, "Bottom", "Helvetica", small_fontsize, "0", "'.v:2'"
1143
+ ; endif
1144
+ ; endif
1145
+ ; endfor
1146
+ ; endproc
1147
+
1148
+
1149
+ procedure gr_plot_feature: .gridID, .table, .col, .x1, .x2, .just$, .y, .format$, .color$
1150
+ # For each syllable in time range, draw text at Y-position, provided feature is true (i.e. >= 0)
1151
+ # <.col> index of a column in <.table>, i.e. some variable/feature/attribute.
1152
+ # <.y> vertical position : percentage of Y range
1153
+ # <.x1>..<.x2> time range
1154
+ # <.just$> position text relative to nucleus : Centre, Right, Left of nucleus
1155
+ # <.format$> "feature:<string>" OR "number:<precision>" OR "#pause"
1156
+ selectObject: .table
1157
+ bottom = -nrofplottedtiers*100/4
1158
+ 'win$'Axes: .x1, .x2, bottom, 100
1159
+ 'win$''.color$'
1160
+ 'win$'Line width: 1
1161
+ .type$ = "none"
1162
+ .text$ = extractWord$(.format$, "feature:")
1163
+ .prec = extractNumber(.format$, "number:")
1164
+ if (index_regex(.format$, "#pause"))
1165
+ .type$ = "pause"
1166
+ elsif (length(.text$))
1167
+ .type$ = "feature"
1168
+ elsif (.prec != undefined)
1169
+ .type$ = "number"
1170
+ endif
1171
+ @intervals_from_time_range: .gridID, nucleus_tier, .x1, .x2, "first_interval", "last_interval"
1172
+ for .i from first_interval to last_interval
1173
+ selectObject: .gridID
1174
+ @is_nucleus: .i
1175
+ if (result)
1176
+ .nx1 = Get start time of interval: nucleus_tier, .i
1177
+ .nx2 = Get end time of interval: nucleus_tier, .i
1178
+ .s$ = Get label of interval: pointer_tier, .i
1179
+ if (length(.s$))
1180
+ .row = number(.s$)
1181
+ if (.row <= nrof_nuclei_analysed)
1182
+ selectObject: .table
1183
+ .v = Get value: .row, .col
1184
+ if (.type$ == "feature" and .v > 0) or (.type$ == "number") or (.type$ = "pause")
1185
+ if (.type$ == "number")
1186
+ .text$ = fixed$(.v, .prec)
1187
+ elsif (.type$ == "pause")
1188
+ .text$ = ""
1189
+ if (.v >= mindur_pause_gap)
1190
+ .text$ = "P " + fixed$(.v*1000, 0) ; pause duration in ms
1191
+ endif
1192
+ endif
1193
+ if (.just$ = "Left") ; left of nucleus
1194
+ .x = .nx1
1195
+ .halign$ = "Right" ; horizontal alignment is Right (like "Right adjusted")
1196
+ elsif (.just$ = "Right") ; left of nucleus
1197
+ .x = .nx2
1198
+ .halign$ = "Left"
1199
+ else
1200
+ .x = .nx1+(.nx2-.nx1)/2 ; midtime
1201
+ .halign$ = "Centre"
1202
+ endif
1203
+ if (.x >= .x1 and .x <= .x2 and length(.text$))
1204
+ 'win$'Text special: .x, .halign$, .y, "Bottom", "Helvetica", small_fontsize, "0", .text$
1205
+ endif
1206
+ endif
1207
+ endif
1208
+ endif
1209
+ endif
1210
+ endfor
1211
+ 'win$'Font size: fontsize
1212
+ endproc
1213
+
1214
+
1215
+ procedure gr_plot_prop_as_shape: .format$, .gridID, .table, .col, .wx1, .wx2, .wy1, .wy2, .color$, .linestyle$
1216
+ # For nuclei in time range <.wx1>..<.wx2> in <.gridID>, plot a shape representing the magnitude of variable in <.col> in <.table>.
1217
+ # The shape is given by <.format$>.
1218
+ # "box_nucl" plot a box as wide as nucleus duration and as high as magnitude of property
1219
+ # "box_left" plot a box between previous nucleus and current nucleus, and as high as magnitude
1220
+ # Also draws the value at (xmid,y).
1221
+ # <.col> column for property
1222
+ # <.wx1>...<.wx2>, <.wy1>...<.wy2> world coordinates to be used for the active viewport.
1223
+ .dy = nrofplottedtiers*(.wy2-.wy1)/4
1224
+ 'win$'Axes: .wx1, .wx2, .wy1 - .dy, .wy2
1225
+ 'win$'Line width: 1
1226
+ 'win$'Solid line
1227
+ 'win$''.color$'
1228
+ @intervals_from_time_range: .gridID, nucleus_tier, .wx1, .wx2, "ifirst", "ilast"
1229
+ for .i from ifirst to ilast
1230
+ selectObject: .gridID
1231
+ @is_nucleus: .i
1232
+ if (result)
1233
+ .x1 = Get start time of interval: nucleus_tier, .i
1234
+ .x2 = Get end time of interval: nucleus_tier, .i
1235
+ .s$ = Get label of interval: pointer_tier, .i
1236
+ .row = number(.s$)
1237
+ selectObject: .table
1238
+ .y = Get value: .row, .col
1239
+ if (.y >= 0)
1240
+ .pos$ = "Bottom"
1241
+ else
1242
+ .pos$ = "Top"
1243
+ endif
1244
+ if (.format$ = "box_nucl" and .x2 >= .wx1 and .x1 <= .wx2)
1245
+ .x1 = max(.x1, .wx1) ; clip to world coordinates
1246
+ .x2 = min(.x2, .wx2) ; clip to world coordinates
1247
+ 'win$'Draw rectangle: .x1, .x2, 0, .y
1248
+ .xmid = .x1+(.x2-.x1)/2
1249
+ 'win$'Text special: .xmid, "Centre", .y, .pos$, "Helvetica", small_fontsize, "0", fixed$(.y,1)
1250
+ elsif (.format$ = "box_left" and .row > 1)
1251
+ .x2 = .x1
1252
+ .x1 = Get value: .row-1, j_nucl_t2
1253
+ if (.x2 >= .wx1 and .x1 <= .wx2)
1254
+ .x1 = max(.x1, .wx1) ; clip to world coordinates
1255
+ .x2 = min(.x2, .wx2) ; clip to world coordinates
1256
+ 'win$'Draw rectangle: .x1, .x2, 0, .y
1257
+ .xmid = .x1+(.x2-.x1)/2
1258
+ 'win$'Text special: .xmid, "Centre", .y, .pos$, "Helvetica", small_fontsize, "0", fixed$(.y,1)
1259
+ endif
1260
+ endif
1261
+ endif
1262
+ endfor
1263
+ 'win$'Solid line
1264
+ 'win$'Line width: 1
1265
+ endproc
1266
+
1267
+
1268
+ procedure gr_plot_prop_curve: .gridID, .table, .col, .wx1, .wx2, .wy1, .wy2, .color$, .linestyle$
1269
+ # Plots a line connecting the points (x,y),
1270
+ # where x is the midtime of a given nucleus, and y the value of a property of that nucleus.
1271
+ # Also draws the value y (as a number) at (x,y).
1272
+ # The nuclei are those of <.gridID>, the values correspond to the value in <.col> of <.table>.
1273
+ # <.col> column for property
1274
+ # <.wx1>...<.wx2>, <.wy1>...<.wy2> world coordinates to be used for the active viewport.
1275
+ 'win$'Axes: .wx1, .wx2, .wy1, .wy2
1276
+ 'win$''.color$'
1277
+ 'win$'Line width: 2
1278
+ 'win$'Solid line
1279
+ if (.linestyle$ = "Dotted")
1280
+ 'win$'Dotted line
1281
+ elsif (.linestyle$ = "Dashed")
1282
+ 'win$'Dashed line
1283
+ endif
1284
+ @intervals_from_time_range: .gridID, nucleus_tier, .wx1, .wx2, "first_interval", "last_interval"
1285
+ for .i from first_interval to last_interval
1286
+ selectObject: .gridID
1287
+ @is_nucleus: .i
1288
+ if (result)
1289
+ .x1 = Get start time of interval: nucleus_tier, .i
1290
+ .x2 = Get end time of interval: nucleus_tier, .i
1291
+ .s$ = Get label of interval: pointer_tier, .i
1292
+ .row = number(.s$)
1293
+ .lx2 = .x1+(.x2-.x1)/2
1294
+ if (.lx2 >= .wx1 and .lx2 <= .wx2 and .row <= nrof_nuclei_analysed) ; midtime falls inside window
1295
+ selectObject: .table
1296
+ .ly2 = Get value: .row, .col
1297
+ ;.radius = max (0.1 * ((.ly2-.wy1)/(.wy2-.wy1))/(.wx2-.wx1), 0.001) ; radius is relative to X axis, i.e. time
1298
+ 'win$'Draw circle: .lx2, .ly2, 0.005
1299
+ 'win$'Text special: .lx2, "Left", .ly2, "Bottom", "Helvetica", small_fontsize, "0", fixed$(.ly2,1)
1300
+ if (.row > 1) ; get position and property value of previous nucleus
1301
+ .ly1 = Get value: .row-1, .col
1302
+ .x1 = Get value: .row-1, j_nucl_t1
1303
+ .x2 = Get value: .row-1, j_nucl_t2
1304
+ .lx1 = .x1+(.x2-.x1)/2 ; mid time of previous nucleus
1305
+ if (.lx1 < .wx1) ; clip to world coordinates
1306
+ .ly1 = .ly1 + (.ly2-.ly1)*(.wx1-.lx1)/(.lx2-.lx1)
1307
+ .lx1 = .wx1
1308
+ endif
1309
+ 'win$'Draw line: .lx1, .ly1, .lx2, .ly2
1310
+ endif
1311
+ if (.row < nrof_nuclei_analysed) ; get position and property value of next nucleus
1312
+ .x1 = Get value: .row+1, j_nucl_t1
1313
+ .x2 = Get value: .row+1, j_nucl_t2
1314
+ .lx3 = .x1 + (.x2-.x1)/2 ; mid time of next nucleus
1315
+ if (.lx3 > .wx2) ; clip to world coordinates
1316
+ .ly3 = Get value: .row+1, .col
1317
+ .ly3 = .ly2 + (.ly3-.ly2)*(.wx2-.lx2)/(.lx3-.lx2)
1318
+ .lx3 = .wx2
1319
+ 'win$'Draw line: .lx2, .ly2, .lx3, .ly3
1320
+ endif
1321
+ endif
1322
+ endif
1323
+ endif
1324
+ endfor
1325
+ 'win$'Solid line
1326
+ 'win$'Line width: 1
1327
+ endproc
1328
+
1329
+
1330
+ procedure gr_viewport_size
1331
+ # Initialization of viewport. Set outer viewport of Prosogram strip.
1332
+ # Set number of strips per page depending on number of tiers in TextGrid plotted.
1333
+ vx1 = 0.5 ; outer viewport left side
1334
+ vx2 = vx1 + viewport_width ; outer viewport right side
1335
+ vy1 = 0 ; outer viewport top
1336
+ npt = max(0, nrofplottedtiers-1)
1337
+ if (viewsize$ = "compact")
1338
+ vy2 = 1.55 + npt * 0.15
1339
+ vyincr = 1.2 + npt * 0.15 ; was 0.95
1340
+ plotspagetiers$ = "0:10, 1:10, 2:9, 3:7, 4:7, 5:6, 6:5"
1341
+ elsif (viewsize$ = "wide" or task == task_pitch_plot or task == task_annotation)
1342
+ vy2 = 1.8 + npt * 0.2
1343
+ vyincr = 1.45 + npt * 0.2 ; was 1.3
1344
+ plotspagetiers$ = "0:7, 1:7, 2:6, 3:5, 4:4, 5:4, 6:3"
1345
+ else ; viewsize$ = "large"
1346
+ vy2 = 4 + npt * 0.3
1347
+ vyincr = vy2
1348
+ plotspagetiers$ = "0:2, 1:2, 2:2, 3:2, 4:2, 5:2, 6:2"
1349
+ endif
1350
+
1351
+ # In the drawing of a TextGrid, the place held by the tiers = (nrofplottedtiers/(nrofplottedtiers+4)) of the total height (inner viewport).
1352
+ strips_per_page = 1
1353
+ if (nrofplottedtiers <= 6)
1354
+ strips_per_page = extractNumber (plotspagetiers$, "'nrofplottedtiers':")
1355
+ endif
1356
+ 'win$'Select outer viewport: vx1, vx2, vy1, vy2
1357
+ ; Select margin between outer and inner viewport
1358
+ vdx = (vx2-vx1)/13
1359
+ vdy = (vy2-vy1)/5.5
1360
+ 'win$'Select inner viewport: vx1+vdx, vx2-vdx, vy1+vdy, vy2-vdy
1361
+ ; @msg: "gr_viewport_size: viewsize='viewsize$' npt='npt' strips_per_page='strips_per_page'"
1362
+ ; @msg: "gr_viewport_size: vx1='vx1:2' vx2='vx2:2' vy1='vy1:2' vy2='vy2:2' vdx='vdx:2' vdy='vdy:2' vyincr='vyincr:2'"
1363
+ endproc
1364
+
1365
+
1366
+ procedure gr_first_viewport_of_page
1367
+ # Initialization of viewports and Postscript bounding box, at start of page
1368
+ Erase all
1369
+ @gr_viewport_size
1370
+ Line width: 1
1371
+ nrofstrips = 0 ; used to decide when to start a new page
1372
+ # area of page used by drawings; for Postscript bounding box
1373
+ bb_x1 = vx1
1374
+ bb_x2 = vx2
1375
+ bb_y1 = vy1
1376
+ bb_y2 = vy2
1377
+ endproc
1378
+
1379
+
1380
+ procedure gr_next_viewport
1381
+ vy1 += vyincr
1382
+ vy2 += vyincr
1383
+ 'win$'Select outer viewport: vx1, vx2, vy1, vy2
1384
+ 'win$'Select inner viewport: vx1+vdx, vx2-vdx, vy1+vdy, vy2-vdy
1385
+ bb_y2 = vy2 ; update Postscript bounding box
1386
+ endproc
1387
+
1388
+
1389
+ procedure gr_write_prosogram
1390
+ # Write to EPS/EMF/PDF/JPG/PNG file, after adjusting bounding box and after constructing filename, using <output_fname$>
1391
+ # Praat draws figures inside viewport, leaving margins for garnish.
1392
+ # Modify BoundingBox to decrease margins. They will be reset by next call to first_viewport_of_page.
1393
+ if (viewsize$ = "compact")
1394
+ bb_y1 += 0.25 ; top
1395
+ bb_x1 += 0.35
1396
+ bb_y2 -= 0.2 ; bottom
1397
+ bb_x2 -= 0.5
1398
+ else ; wide or large
1399
+ bb_y1 += 0.1 ; top (0.1 for PNG)
1400
+ bb_x1 += 0.35
1401
+ bb_y2 -= 0.2 ; bottom (-0.2 for PNG)
1402
+ bb_x2 -= 0.5
1403
+ endif
1404
+ if (show_tiernames or show_y_scale)
1405
+ 'win$'Select outer viewport: bb_x1, bb_x2+0.3, bb_y1, bb_y2
1406
+ else
1407
+ 'win$'Select outer viewport: bb_x1, bb_x2, bb_y1, bb_y2
1408
+ endif
1409
+
1410
+ # Construct filename for output file
1411
+ if (file_numbering)
1412
+ .padding$ = ""
1413
+ if (file_ctr <= 9)
1414
+ .padding$ = "00"
1415
+ elsif (file_ctr <= 99)
1416
+ .padding$ = "0"
1417
+ endif
1418
+ .output_file$ = output_fname$ + .padding$ + "'file_ctr'"
1419
+ file_ctr += 1
1420
+ else
1421
+ .output_file$ = output_fname$
1422
+ endif
1423
+ @debug_msg: "gr_write_prosogram: file_numbering='file_numbering' output_format='output_format$' output_file=<'.output_file$'>"
1424
+ if (index(output_format$, "EPS") or
1425
+ ... ((index(output_format$, "PDF") or index(output_format$, "JPG")) and windows))
1426
+ epsfile$ = .output_file$ + ".eps"
1427
+ Write to EPS file: epsfile$
1428
+ endif
1429
+ if (index(output_format$, "EMF") > 0 and windows)
1430
+ Write to Windows metafile: "'.output_file$'.emf"
1431
+ endif
1432
+ if (index(output_format$, "PDF"))
1433
+ if (macintosh)
1434
+ Save as PDF file: "'.output_file$'.pdf"
1435
+ elsif (windows)
1436
+ if (fileReadable (path_ghostscript$))
1437
+ res = 300 ; resolution in dpi
1438
+ command$ = path_ghostscript$ + " -dNOPAUSE -dBATCH -dQUIET -sDEVICE=pdfwrite -r'res' -sOutputFile=""'.output_file$'.pdf"" 'epsfile$'"
1439
+ system 'command$'
1440
+ else
1441
+ @debug_msg: "gr_write_prosogram: cannot access <'path_ghostscript$'>"
1442
+ endif
1443
+ endif
1444
+ endif
1445
+ if (index(output_format$,"JPG") and windows)
1446
+ res = 300 ; resolution in dpi
1447
+ if (index(output_format$,"600"))
1448
+ res = 600
1449
+ endif
1450
+ .jpegq = 75 ; default value for JPEGQ quality scale
1451
+ if (variableExists ("jpegq"))
1452
+ .jpegq = max(1,min(floor(jpegq),100))
1453
+ endif
1454
+ @debug_msg: "gr_write_prosogram: jpegq='.jpegq'"
1455
+ command$ = path_ghostscript$ + " -dNOPAUSE -dBATCH -dQUIET -sDEVICE=jpeg -dJPEGQ='.jpegq' -sEPSCrop -r'res' -sOutputFile=""'.output_file$'.jpg"" 'epsfile$'"
1456
+ @debug_msg: "gr_write_prosogram: format='output_format$', fname=<'.output_file$'.jpg>"
1457
+ if (fileReadable (path_ghostscript$))
1458
+ system 'command$'
1459
+ else
1460
+ @debug_msg: "gr_write_prosogram: cannot access <'path_ghostscript$'>"
1461
+ endif
1462
+ endif
1463
+ if (index(output_format$, "PNG"))
1464
+ if (index(output_format$, "PNG 600 dpi"))
1465
+ Save as 600-dpi PNG file: "'.output_file$'.png"
1466
+ elsif (index(output_format$, "PNG 300 dpi"))
1467
+ Save as 300-dpi PNG file: "'.output_file$'.png"
1468
+ endif
1469
+ endif
1470
+ endproc
1471
+
1472
+
1473
+ procedure gr_write_all_prosograms: .at1, .at2, .timeincr, .inputfile, .nrof_inputfiles
1474
+ # Draw and save all prosograms for time interval <.at1>..<.at2>, using a prosogram window duration of <.timeincr>
1475
+ # <.inputfile> number of current input file
1476
+ # <.nrof_inputfiles> total number of input files
1477
+ @debug_msg: "write_all_prosograms: entry"
1478
+ demowin = 0 ; drawing in Picture window
1479
+ win$ = "" ; drawing in Picture window
1480
+ Font size: fontsize
1481
+ grid_in_prosogram = 1
1482
+ if (nrof_pages == 0) ; grid takes part of plotting area, so adjust lower Y-value
1483
+ ySTbottom = ySTmin - nrofplottedtiers*(ySTmax-ySTmin)/4
1484
+ @from_ST_rel_1_to_Hz: ySTmin
1485
+ yHzmin = result
1486
+ @from_ST_rel_1_to_Hz: ySTmax
1487
+ yHzmax = result
1488
+ ; @msg: "Drawing with Y-range 'ySTmin:1'-'ySTmax:1'ST ('yHzmin:0'-'yHzmax:0' Hz)"
1489
+ endif
1490
+ .start_new_page = 1
1491
+ .t1 = .at1
1492
+ repeat ; for each prosogram strip
1493
+ if (.start_new_page) ; at start or when nrofstrips >= strips_per_page
1494
+ nrof_pages += 1
1495
+ @debug_msg: "write_all_prosograms: starting page nr 'nrof_pages', t1='.t1:3'"
1496
+ @gr_first_viewport_of_page
1497
+ endif
1498
+ .t2 = .t1 + .timeincr
1499
+ ; @msg: "gr_write_all_prosograms: Drawing '.t1:3' - '.t2:3'"
1500
+ if (auto_pitchrange) ; automatic pitch range selection, local to each strip
1501
+ @speaker_autorange: .t1, .t2
1502
+ ySTmax = ymax
1503
+ ySTmin = ymin
1504
+ endif
1505
+ @gr_display_prosogram: .t1, .t2, ySTmin, ySTmax, grid_in_prosogram, .nrof_inputfiles
1506
+ nrofstrips += 1
1507
+ # prepare for next window pane
1508
+ if (nrofstrips >= strips_per_page
1509
+ ... or (.nrof_inputfiles == 1 and .t2 >= .at2)
1510
+ ... or (single_fname_graphics_output = 0 and .t2 >= .at2)
1511
+ ... or (outputmode$ = "One") )
1512
+ @gr_write_prosogram
1513
+ .start_new_page = 1
1514
+ nrofstrips = 0
1515
+ elsif (.t2 < .at2 or .inputfile < .nrof_inputfiles)
1516
+ @gr_next_viewport
1517
+ .start_new_page = 0
1518
+ endif
1519
+ .t1 += .timeincr
1520
+ until (.t1 >= .at2)
1521
+ if (.inputfile == .nrof_inputfiles and nrofstrips > 1) ; Write last output file if necessary
1522
+ @gr_write_prosogram
1523
+ endif
1524
+ @debug_msg: "write_all_prosograms: exit"
1525
+ endproc
1526
+
1527
+
1528
+ procedure gr_write_all_annotation: .at1, .at2, .timeincr, .inputfile, .nrof_inputfiles
1529
+ ySTmin = 0
1530
+ ySTmax = 100
1531
+ @gr_write_all_prosograms: .at1, .at2, .timeincr, .inputfile, .nrof_inputfiles
1532
+ endproc
1533
+
1534
+
1535
+ ;procedure multipage_pdf
1536
+ ; ; pdf_in$ = replace_regex$ (input_files$, "\.eps", "\.pdf", 1)
1537
+ ; pdf_in$ = replace_regex$ (input_files$, "\.eps", "\.pdf", 1)
1538
+ ; pdf_out$ = replace_regex$ (input_files$, "[0-9\*]*\.eps", "\.pdf", 1)
1539
+ ; pdf_files$ = ""
1540
+ ; if (index (output_format$, "multipage"))
1541
+ ; ; use wildcard expansion by pdftk in order to avoid command line buffer overflow
1542
+ ; command$ = "pdftk 'pdf_in$' cat output 'pdf_out$'"
1543
+ ; system 'command$'
1544
+ ; endif
1545
+ ;endproc
1546
+