[med-svn] [Git][med-team/praat][master] 6 commits: New upstream version 6.1.05

Rafael Laboissiere gitlab at salsa.debian.org
Sat Oct 19 20:27:57 BST 2019



Rafael Laboissiere pushed to branch master at Debian Med / praat


Commits:
35380a8f by Rafael Laboissiere at 2019-10-19T10:01:17Z
New upstream version 6.1.05
- - - - -
80cd1ff3 by Rafael Laboissiere at 2019-10-19T10:04:00Z
Merge tag 'upstream/6.1.05'

Upstream version 6.1.05

- - - - -
1221c354 by Rafael Laboissiere at 2019-10-19T10:09:43Z
d/What_s_new_.html: Update upstream changelog

Gbp-Dch: Ignore

- - - - -
76b3a49d by Rafael Laboissiere at 2019-10-19T13:51:45Z
Changelog entry for version 6.1.05-1

Gbp-Dch: Ignore

- - - - -
792e0f24 by Rafael Laboissiere at 2019-10-19T18:24:25Z
Merge branch 'master' of salsa.debian.org:med-team/praat

- - - - -
b5c0eb99 by Rafael Laboissiere at 2019-10-19T19:27:04Z
Changelog entry for version 6.1.05-2

Gbp-Dch: Ignore

- - - - -


26 changed files:

- LPC/LPC_to_Spectrogram.cpp
- LPC/manual_LPC.cpp
- LPC/praat_LPC_init.cpp
- debian/What_s_new_.html
- debian/changelog
- − dwtest/KlattGrid_test.praat
- dwtools/KlattGrid.cpp
- dwtools/KlattGrid.h
- dwtools/manual_KlattGrid.cpp
- dwtools/manual_dwtools.cpp
- dwtools/praat_KlattGrid_init.cpp
- fon/FunctionEditor.cpp
- fon/FunctionEditor.h
- fon/Sound_and_Spectrum.cpp
- fon/TextGridEditor.h
- fon/manual_Script.cpp
- fon/manual_tutorials.cpp
- sys/Graphics_colour.cpp
- sys/Gui.h
- sys/GuiMenu.cpp
- sys/motifEmulator.cpp
- sys/praat.cpp
- sys/praat_objectMenus.cpp
- sys/praat_version.h
- test/fon ExperimentMFC/simplest.ExperimentMFC
- + test/fon/examples/sounds/a.wav


Changes:

=====================================
LPC/LPC_to_Spectrogram.cpp
=====================================
@@ -25,7 +25,7 @@
 
 autoSpectrogram LPC_to_Spectrogram (LPC me, double dfMin, double bandwidthReduction, double deEmphasisFrequency) {
 	try {
-		double samplingFrequency = 1.0 / my samplingPeriod;
+		const double samplingFrequency = 1.0 / my samplingPeriod;
 		integer nfft = 2;
 		if (dfMin <= 0.0) {
 			nfft = 512; 
@@ -33,16 +33,16 @@ autoSpectrogram LPC_to_Spectrogram (LPC me, double dfMin, double bandwidthReduct
 		}
 		while (samplingFrequency / nfft > dfMin || nfft <= my maxnCoefficients)
 			nfft *= 2;
-		double freqStep = samplingFrequency / nfft;
+		const double freqStep = samplingFrequency / nfft;
 
 		autoSpectrogram thee = Spectrogram_create (my xmin, my xmax, my nx, my dx, my x1, 0.0, samplingFrequency / 2.0, nfft / 2 + 1, freqStep, 0.0);
 
 		for (integer i = 1; i <= my nx; i ++) {
-			double t = Sampled_indexToX (me, i);
+			const double t = Sampled_indexToX (me, i);
 			autoSpectrum spec = LPC_to_Spectrum (me, t, dfMin, bandwidthReduction, deEmphasisFrequency);
 			for (integer j = 1; j <= spec -> nx; j ++) {
-				double re = spec -> z [1] [j], im = spec -> z [2] [j];
-				thy z [j] [i] =  re * re + im * im;
+				const double re = spec -> z [1] [j], im = spec -> z [2] [j];
+				thy z [j] [i] = re * re + im * im;
 			}
 		}
 		return thee;


=====================================
LPC/manual_LPC.cpp
=====================================
@@ -96,7 +96,9 @@ MAN_END
 #define PowerCepstrum_manual_trendRange \
 	U"the quefrency range for which the amplitudes (in dB) will be modelled by a straight line. " \
 	"The lower value for this range in the @@Hillenbrand et al. (1994)@ article was chosen as 0.001 s " \
-	"in order to reduce the effect of very low quefrency data on the straight line fit. In our analysis this value is not so critical as we use a more robust fitting procedure."
+	"in order to reduce the effect of very low quefrency data on the straight line fit. In our analysis this value " \
+	"is not so critical if we use the robust fitting procedure. If you choose the \"Least squares\" fit method " \
+	"then it matters more."
 
 #define PowerCepstrum_manual_trendType \
 	U"defines how to model the cepstrum background. We can model it with a straight line as was " \
@@ -152,17 +154,17 @@ TAG (U"##Fit method#")
 DEFINITION (PowerCepstrum_manual_fitMethod)
 MAN_END
 
-MAN_BEGIN (U"PowerCepstrogram: To Table (peak prominence)...", U"djmw", 20190910)
+MAN_BEGIN (U"PowerCepstrogram: To Table (peak prominence)...", U"djmw", 20191008)
 INTRO (U"A command to create a table with @@PowerCepstrum: Get peak prominence...|cepstral peak prominence@ values.")
 ENTRY (U"Settings")
 SCRIPT (5, Manual_SETTINGS_WINDOW_HEIGHT (7), U""
 	Manual_DRAW_SETTINGS_WINDOW ("PowerCepstrogram: To Table (peak prominence)", 7)
 	Manual_DRAW_SETTINGS_WINDOW_RANGE("Peak search pitch range (Hz)", U"60.0", U"300.0")
 	Manual_DRAW_SETTINGS_WINDOW_RADIO (U"Interpolation", U"None", 0)
-	Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Parabolic", 0)
-	Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Cubic", 1)
+	Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Parabolic", 1)
+	Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Cubic", 0)
 	Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Sinc70", 0)
-	Manual_DRAW_SETTINGS_WINDOW_RANGE("Trend line quefrency range (s)", U"0.001", U"0.0 (= end)")
+	Manual_DRAW_SETTINGS_WINDOW_RANGE("Trend line quefrency range (s)", U"0.001", U"0.05")
 	Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU(U"Trend type", U"Exponential decay")
 	Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU(U"Fit method", U"Robust")
 )
@@ -260,8 +262,50 @@ TAG (U"##Trend type#")
 DEFINITION (PowerCepstrum_manual_trendType)
 TAG (U"##Fit method")
 DEFINITION (PowerCepstrum_manual_fitMethod)
-ENTRY (U"Note")
-NORMAL (U"The CPP value does not depend on the reference value used in the dB calculation of the power cepstrum.")
+ENTRY (U"Examples")
+NORMAL (U"Next picture of a PowerCepstrum with its straight blue trend line and its corresponding "
+	"peak prominence value was generated with the following script. Note that the first four lines in the "
+	"script are only necessary to generate a PowerCepstrum of a part of a vowel. ")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000")
+CODE (U"To Sound")
+CODE (U"To PowerCepstrogram: 60, 0.002, 5000, 50")
+CODE (U"To PowerCepstrum (slice): 0.1")
+CODE (U"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Straight\", \"Robust slow\"")
+CODE (U"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"")
+CODE (U"Draw: 0, 0, 0, 110, \"yes\"")
+CODE (U"Colour: \"Blue\"")
+CODE (U"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Straight\", \"Robust slow\"")
+CODE (U"Colour: \"Black\"")
+CODE (U"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"")
+SCRIPT (5, 3, U""
+	"kg = Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000\n"
+	"vowel = To Sound\n"
+	"cepstrogram = To PowerCepstrogram: 60, 0.002, 5000, 50\n"
+	"cepstrum = To PowerCepstrum (slice): 0.1\n"
+	"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Straight\", \"Robust slow\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"Draw: 0, 0, 0, 110, \"yes\"\n"
+	"Colour: \"Blue\"\n"
+	"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Straight\", \"Robust slow\"\n"
+	"Colour: \"Black\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"removeObject: kg, vowel, cepstrogram, cepstrum\n")
+NORMAL (U"In the next picture the trend line is of exponential decay type and consequently the "
+	"peak prominence value has changed a little bit.")
+SCRIPT (5, 3, U""
+	"kg = Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000\n"
+	"vowel = To Sound\n"
+	"cepstrogram = To PowerCepstrogram: 60, 0.002, 5000, 50\n"
+	"cepstrum = To PowerCepstrum (slice): 0.1\n"
+	"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Exponential decay\", \"Robust slow\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"Draw: 0, 0, 0, 110, \"yes\"\n"
+	"Colour: \"Blue\"\n"
+	"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Exponential decay\", \"Robust slow\"\n"
+	"Colour: \"Black\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"removeObject: kg, vowel, cepstrogram, cepstrum\n")
+
 MAN_END
 
 MAN_BEGIN (U"PowerCepstrum: Draw...", U"djmw", 20190914)
@@ -276,7 +320,7 @@ NORMAL (U"Cepstrum values are drawn as 20\\.clog10 (value +\\ep), "
 	"where \\ep is a small number that avoids taking the logarithm of zero if the cepstrum value happens to be zero.")
 MAN_END
 
-MAN_BEGIN (U"PowerCepstrum: Draw trend line...", U"djmw", 20190909)
+MAN_BEGIN (U"PowerCepstrum: Draw trend line...", U"djmw", 20191008)
 INTRO (U"Draws the line that models the background of the selected @@PowerCepstrum at .")
 ENTRY (U"Settings")
 TAG (U"##Quefrency range (s)#")
@@ -289,6 +333,32 @@ TAG (U"##Trend type#")
 DEFINITION (PowerCepstrum_manual_trendType)
 TAG (U"##Fit method")
 DEFINITION (PowerCepstrum_manual_fitMethod)
+ENTRY (U"Examples")
+NORMAL (U"The next picture shows a PowerCepstrum with %%two% drawn trend lines, a straight line in blue "
+	"and an exponential decay line in green.  The picture was generated by the following script. "
+	"Note that the first four lines in the script are only necessary to generate a PowerCepstrum of a part of a vowel.")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000")
+CODE (U"To Sound")
+CODE (U"To PowerCepstrogram: 60, 0.002, 5000, 50")
+CODE (U"To PowerCepstrum (slice): 0.1")
+CODE (U"Draw: 0, 0, 0, 110, \"yes\"")
+CODE (U"Colour: \"Blue\"")
+CODE (U"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Straight\", \"Robust slow\"")
+CODE (U"Colour: \"Green\"")
+CODE (U"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Exponential decay\", \"Robust slow\"")
+CODE (U"Colour: \"Black\"")
+SCRIPT (5, 3, U""
+	"kg = Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000\n"
+	"vowel = To Sound\n"
+	"cepstrogram = To PowerCepstrogram: 60, 0.002, 5000, 50\n"
+	"cepstrum = To PowerCepstrum (slice): 0.1\n"
+	"Draw: 0, 0, 0, 110, \"yes\"\n"
+	"Colour: \"Blue\"\n"
+	"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Straight\", \"Robust slow\"\n"
+	"Colour: \"Green\"\n"
+	"Draw trend line: 0, 0, 0, 110, 0.001, 0.05, \"Exponential decay\", \"Robust slow\"\n"
+	"Colour: \"Black\"\n"
+	"removeObject: kg, vowel, cepstrogram, cepstrum\n")
 MAN_END
 
 MAN_BEGIN (U"PowerCepstrum: Get peak...", U"djmw", 20190910)
@@ -331,7 +401,7 @@ TAG (U"##Fit method")
 DEFINITION (PowerCepstrum_manual_fitMethod)
 MAN_END
 
-MAN_BEGIN (U"PowerCepstrum: Smooth...", U"djmw", 20190914)
+MAN_BEGIN (U"PowerCepstrum: Smooth...", U"djmw", 20191005)
 INTRO (U"A command to smooth the selected @@PowerCepstrum@ by averaging values at successive quefrencies.")
 ENTRY (U"Settings")
 TAG (U"##Quefrency averaging window (s)#")
@@ -339,7 +409,46 @@ DEFINITION (PowerCepstrum_manual_quefrencyAveragingWindow)
 TAG (U"##Number of iterations#")
 DEFINITION (U"determines how often the averaging will take place. If chosen 2, for example, the output PowerCepstrum "
 	"after the first averaging will be averaged once again.")
-
+ENTRY (U"Examples")
+NORMAL (U"The figure below is the PowerCepstrum taken from an artificial /a/ vowel synthesized as follows:")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000")
+CODE (U"To Sound")
+CODE (U"To PowerCepstrogram: 60, 0.002, 5000, 50")
+CODE (U"To PowerCepstrum (slice): 0.1")
+CODE (U"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Straight\", \"Robust slow\"")
+CODE (U"Draw: 0, 0, 0, 110, \"yes\"")
+CODE (U"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"")
+SCRIPT (5, 3, U""
+	"kg = Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000\n"
+	"vowel = To Sound\n"
+	"cepstrogram = To PowerCepstrogram: 60, 0.002, 5000, 50\n"
+	"cepstrum = To PowerCepstrum (slice): 0.3\n"
+	"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Straight\", \"Robust slow\"\n"
+	"Draw: 0, 0, 0, 110, \"yes\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"removeObject: kg, vowel, cepstrogram, cepstrum\n")
+NORMAL (U"After 1 iteration with an averaging window of 0.0005 s the PowerCepstrum is:")
+SCRIPT (5, 3, U""
+	"kg = Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000\n"
+	"vowel = To Sound\n"
+	"cepstrogram = To PowerCepstrogram: 60, 0.002, 5000, 50\n"
+	"cepstrum = To PowerCepstrum (slice): 0.3\n"
+	"smooth = Smooth: 0.0005, 1\n"
+	"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Straight\", \"Robust slow\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"Draw: 0, 0, 0, 110, \"yes\"\n"
+	"removeObject: kg, vowel, cepstrogram, cepstrum, smooth\n")
+NORMAL (U"After 2 iterations with an averaging window of 0.0005 s the PowerCepstrum is:")
+SCRIPT (5, 3, U""
+	"kg = Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.1, 1000\n"
+	"vowel = To Sound\n"
+	"cepstrogram = To PowerCepstrogram: 60, 0.002, 5000, 50\n"
+	"cepstrum = To PowerCepstrum (slice): 0.3\n"
+	"smooth = Smooth: 0.0005, 2\n"
+	"prominence = Get peak prominence: 60, 333.3, \"Parabolic\", 0.001, 0.05, \"Straight\", \"Robust slow\"\n"
+	"Draw: 0, 0, 0, 110, \"yes\"\n"
+	"Text top: \"no\", \"Peak prominence = \" + fixed$ (prominence, 2) + \" dB\"\n"
+	"removeObject: kg, vowel, cepstrogram, cepstrum, smooth\n")
 MAN_END
 
 MAN_BEGIN (U"PowerCepstrum: Subtract trend...", U"djmw", 20190914)
@@ -799,6 +908,15 @@ NORMAL (U"N. Anderson (1978): \"On the calculation of filter coefficients for "
 	"IEEE Press: 252\\--255.")
 MAN_END
 
+MAN_BEGIN (U"Fleisher et al. (2015)", U"djmw", 20191008)
+NORMAL (U"M. Fleisher, S. Pinkert, W. Mattheus, A. Mainka & D. Mürbe (2015): \"Formant frequencies and bandwidths of the vocal transfer function are affected by the mechanical impedance of the vocal tract wall.\", %%Biomech Model Mechanobiol% #14: 719\\--733.")
+MAN_END
+
+MAN_BEGIN (U"Hawks & Miller (1995)", U"djmw", 20191008)
+NORMAL (U"J. Hawks &  J. Miller (1995): \"A formant bandwidth estimation procedure for vowel synthesis.\", "
+	"%%Journal of the Acoustical Society of America% #97: 1343\\--1344.")
+MAN_END
+
 MAN_BEGIN (U"Hillenbrand et al. (1994)", U"djmw", 20121017)
 NORMAL (U"J. Hillenbrand, R.A. Cleveland & R.L. Erickson (1994): \"Acoustic correlates of breathy vocal quality\", %%Journal of speech and hearing research% #37: 769\\--778.")
 MAN_END


=====================================
LPC/praat_LPC_init.cpp
=====================================
@@ -156,8 +156,8 @@ FORM (REAL_PowerCepstrum_getQuefrencyOfPeak, U"PowerCepstrum: Get quefrency of p
 DO
 	NUMBER_ONE (PowerCepstrum)
 		double result, quefrency;
-		PowerCepstrum_getMaximumAndQuefrency (me, fromPitch, toPitch, interpolationMethod - 1, & quefrency, & result);
-		double f = 1.0 / quefrency;
+		PowerCepstrum_getMaximumAndQuefrency (me, fromPitch, toPitch, interpolationMethod - 1, nullptr, & result);
+		double f = 1.0 / result;
 	NUMBER_ONE_END (U" s (f =", f, U" Hz)")
 }
 
@@ -406,7 +406,7 @@ FORM (REAL_PowerCepstrogram_getCPPS, U"PowerCepstrogram: Get CPPS", U"PowerCepst
 		RADIOBUTTON (U"Sinc70")
 	LABEL (U"Trend line:")
 	REAL (fromQuefrency_trendLine, U"left Trend line quefrency range (s)", U"0.001")
-	REAL (toQuefrency_trendLine, U"right Trend line quefrency range (s)", U"0.05)")
+	REAL (toQuefrency_trendLine, U"right Trend line quefrency range (s)", U"0.05")
 	OPTIONMENU_ENUM (kCepstrumTrendType, lineType, U"Trend type", kCepstrumTrendType::DEFAULT)
 	OPTIONMENU_ENUM (kCepstrumTrendFit, fitMethod, U"Fit method", kCepstrumTrendFit::DEFAULT)
 	OK


=====================================
debian/What_s_new_.html
=====================================
@@ -7,6 +7,52 @@ What's new?
 <p>
 Latest changes in Praat.</p>
 <p>
+<b>6.1.05</b> (16 October 2019)</p>
+<ul>
+<li>
+ Repaired a bug introduced in 6.0.44 that could cause rubbish LPC smoothing.
+<li>
+ Repaired a rare crash when dragging a selection on the Mac.
+</ul>
+<p>
+<b>6.1.04</b> (28 September 2019)</p>
+<ul>
+<li>
+ <a href="Electroglottography.html">Electroglottography</a>.
+<li>
+ Sound and other windows: <b>Widen or shrink selection...</b>.
+<li>
+ <b>KlattGrid: Create from vowel...</b>.
+<li>
+ Fix rectangle playing bug when selection viewer is on.
+<li>
+ Selection viewer separately visible for Sound window and TextGrid window.
+<li>
+ Scripting: allow comments after parameter list.
+<li>
+ Scripting: fix CR/LF pasting from Microsoft Word.
+</ul>
+<p>
+<b>6.1.03</b> (1 September 2019)</p>
+<ul>
+<li>
+ Sound window: <b>Widen or shrink selection...</b>.
+</ul>
+<p>
+<b>6.1.02</b> (25 August 2019)</p>
+<ul>
+<li>
+ Repaired <b>Sound: Concatenate with overlap...</b>.
+<li>
+ Mac: Info and script windows: prevent line breaks caused by tab stops.
+</ul>
+<p>
+<b>6.1.01</b> (14 August 2019)</p>
+<ul>
+<li>
+ Repaired <b>TextGrid: Replace interval texts...</b>.
+</ul>
+<p>
 <b>6.1</b> (13 July 2019)</p>
 <p>
 <b>6.0.57</b> (1 July 2019)</p>
@@ -528,7 +574,7 @@ What used to be new?</h3>
 </ul>
 <hr>
 <address>
-	<p>© ppgb, July 13, 2019</p>
+	<p>© ppgb, October 16, 2019</p>
 </address>
 </body>
 </html>


=====================================
debian/changelog
=====================================
@@ -1,3 +1,16 @@
+praat (6.1.05-2) unstable; urgency=medium
+
+  [ Steffen Moeller ]
+  * d/u/metadata: yamllint
+
+ -- Rafael Laboissiere <rafael at debian.org>  Sat, 19 Oct 2019 15:25:49 -0300
+
+praat (6.1.05-1) unstable; urgency=medium
+
+  * New upstream version 6.1.05
+
+ -- Rafael Laboissiere <rafael at debian.org>  Sat, 19 Oct 2019 07:10:39 -0300
+
 praat (6.1.04-1) unstable; urgency=medium
 
   * New upstream version 6.1.04


=====================================
dwtest/KlattGrid_test.praat deleted
=====================================
@@ -1,314 +0,0 @@
-# KlattGrid_test.praat
-# djmw 20081208, 20090420, 20140113
-
-
-printline ===========		KlattGrid test start
-
-call test_get_add_remove_extract_replace_old_interface
-
-call test_get_add_remove_replace
-
-printline ===========		KlattGrid test end
-
-procedure test_get_add_remove_replace
-	numberOfOralFormants = 6
-	numberOfNasalFormants = 1
-	numberOfTrachealFormants = 1
-	numberOfFricationFormants = 5
-	numberOfNasalAntiFormants = 1
-	numberOfTrachealAntiFormants = 1
-	numberOfDeltaFormants = 1
-	tmin = 0
-	tmax = 1
-
-	kg = Create KlattGrid... kg tmin tmax numberOfOralFormants numberOfNasalFormants numberOfNasalAntiFormants 
-		... numberOfFricationFormants numberOfTrachealFormants numberOfTrachealAntiFormants numberOfDeltaFormants
-
-	printline ===========		KlattGrid test_get_add_remove_extract_replace start
-	for .itime to 20
-		call setget_1 "pitch" 130
-		call setget_1 "voicing amplitude" 90
-		call setget_1 "flutter" 0.5
-		call setget_1 "power1" 2
-		call setget_1 "power2" 3
-		call setget_1 "open phase" 0.5
-		call setget_1 "collision phase" 0.035
-		call setget_1 "double pulsing" 0.4
-		call setget_1 "spectral tilt" 20
-		call setget_1 "aspiration amplitude" 90
-		call setget_1 "breathiness amplitude" 90
-
-		call setget_1 "frication bypass" 20
-		call setget_1 "frication amplitude" 50
-	
-		call setget_formants Oral
-		call setget_formants Nasal
-		call setget_formants Tracheal
-		call setget_formants Delta
-		call setget_formants Frication
-		call setget_antiformants Nasal
-		call setget_antiformants Tracheal
-
-	endfor
-
-	call test_deltaFormants
-
-	removeObject (kg)
-
-	printline ===========		KlattGrid test_get_add_remove_extract_replace succesful
-
-endproc
-
-procedure test_get_add_remove_extract_replace_old_interface
-	numberOfOralFormants = 6
-	numberOfNormalFormants = numberOfOralFormants
-	numberOfNasalFormants = 1
-	numberOfTrachealFormants = 1
-	numberOfFricationFormants = 5
-	numberOfNasalAntiFormants = 1
-	numberOfTrachealAntiFormants = 1
-	numberOfDeltaFormants = 1
-	tmin = 0
-	tmax = 1
-
-	printline ===========		KlattGrid test_get_add_remove_extract_replace_old_interface start
-
-	kg = Create KlattGrid... kg tmin tmax numberOfOralFormants numberOfNasalFormants numberOfNasalAntiFormants 
-		... numberOfFricationFormants numberOfTrachealFormants numberOfTrachealAntiFormants numberOfDeltaFormants
-
-	for .itime to 20
-		call setget_1 "pitch" 130
-		call setget_1 "voicing amplitude" 90
-		call setget_1 "flutter" 0.5
-		call setget_1 "power1" 2
-		call setget_1 "power2" 3
-		call setget_1 "open phase" 0.5
-		call setget_1 "collision phase" 0.035
-		call setget_1 "double pulsing" 0.4
-		call setget_1 "spectral tilt" 20
-		call setget_1 "aspiration amplitude" 90
-		call setget_1 "breathiness amplitude" 90
-
-		call setget_1 "frication bypass" 20
-		call setget_1 "frication amplitude" 50
-	
-		call setget_formants_old Normal
-		call setget_formants_old Nasal
-		call setget_formants_old Tracheal
-		call setget_formants_old Frication
-		call setget_antiformants_old Nasal
-		call setget_antiformants_old Tracheal
-
-		call setget_deltaformants
-
-	endfor
-
-	call test_deltaFormants_old
-
-	removeObject (kg)
-	printline ===========		KlattGrid test_get_add_remove_extract_replace_old_interface succesful
-endproc
-
-procedure setget_1 .var$ .value
-	selectObject (kg)
-	.time = randomUniform (tmin,tmax)
-	Add '.var$' point... .time .value
-	.val = Get '.var$' at time... .time
-	.vt = Extract '.var$' tier
-	selectObject (kg)
-	Remove '.var$' points between... tmin tmax
-	.val1 = Get '.var$' at time... .time
-	assert .val1 = undefined; Add '.var$' at time... '.time' '.value'
-	
-	plusObject (.vt)
-	Replace '.var$' tier
-	selectObject (kg)
-	.val1 = Get '.var$' at time... .time
-	assert .val1 =.val; Add '.var$' at time... '.time' '.value'
-	removeObject (.vt)
-endproc
-
-procedure setget_2p .var$ .ifor .time .value
-	selectObject (kg)
-	Add delta '.var$' point... .ifor .time .value
-	.val = Get delta '.var$' at time... .ifor .time
-	assert .val = .value; Add delta '.var$' point... .ifor .time .value
-	.fg = Extract delta formant grid
-	selectObject (kg)
-	Remove delta '.var$' points between... .ifor tmin tmax
-	.val1 = Get delta '.var$' at time... .ifor .time
-	assert .val1 = undefined; Get delta '.var$' at time... .ifor .time
-	plusObject (.fg)
-	Replace delta formant grid
-	selectObject (kg)
-	.val1 = Get delta '.var$' at time... .ifor .time
-	assert .val1 =.val; Get delta '.var$' at time... .ifor .time
-	removeObject (.fg)
-endproc
-
-procedure setget_3_old .var$ .choice$ .ifor .time .value
-	selectObject (kg)
-	Add '.var$' point... "'.choice$'" .ifor .time .value
-	.val = Get '.var$' at time... "'.choice$'" .ifor .time
-	assert .val = .value; Add '.var$' point... "'.choice$'" .ifor .time .value
-	.fg = Extract formant grid... '.choice$'
-	selectObject (kg)
-	Remove '.var$' points between... "'.choice$'" .ifor tmin tmax
-	.val1 = Get '.var$' at time... "'.choice$'" .ifor .time
-	assert .val1 = undefined; Get '.var$' at time... "'.choice$'" .ifor .time
-	plusObject (.fg)
-	Replace formant grid... '.choice$'
-	selectObject (kg)
-	.val1 = Get '.var$' at time... "'.choice$'" .ifor .time
-	assert .val1 =.val; Get '.var$' at time... "'.choice$'" .ifor .time
-	removeObject (.fg)
-
-endproc
-
-procedure setget_3a_old .var$ .choice$ .ifor .time .value
-	selectObject (kg)
-	Add '.var$' point... "'.choice$'" .ifor .time .value
-	.val = Get '.var$' at time... "'.choice$'" .ifor .time
-	assert .val = .value; Add '.var$' point... "'.choice$'" .ifor .time .value
-	.tier = Extract amplitude tier... "'.choice$'" .ifor
-	selectObject (kg)
-	Remove '.var$' points between... "'.choice$'" .ifor tmin tmax
-	.val1 = Get '.var$' at time... "'.choice$'" .ifor .time
-	assert .val1 = undefined; Get '.var$' at time... "'.choice$'" .ifor .time
-	plusObject (.tier)
-	Replace amplitude tier... "'.choice$'" .ifor
-	selectObject (kg)
-	.val1 = Get '.var$' at time... "'.choice$'" .ifor .time
-	assert .val1 =.val; Get '.var$' at time... "'.choice$'" .ifor .time
-	removeObject (.tier)
-endproc
-
-procedure setget_formants_old .type$
-	for .i to numberOf'.type$'Formants
-		.time = randomUniform (tmin, tmax)
-		.f = (2*.i-1) * randomUniform (450, 550)
-		.b = .f /10
-		.a = randomUniform (70, 90)
-		call setget_3_old "formant" "'.type$' formant" .i .time .f
-		call setget_3_old "bandwidth" "'.type$' formant" .i .time .b
-		call setget_3a_old "amplitude" "'.type$' formant" .i .time .a
-	endfor
-	selectObject (kg)
-	Formula (frequencies)... "'.type$' formant" self + 100
-	Formula (bandwidths)... "'.type$' formant" self * 2
-endproc
-
-
-procedure setget_3 .type$ .formant$ .var$ .ifor .time .value
-	selectObject (kg)
-	what$ = "'.type$' '.formant$' '.var$'"
-	Remove 'what$' points... .ifor tmin tmax
-	Add 'what$' point... .ifor .time .value
-	.val = Get 'what$' at time... .ifor .time
-	assert .val = .value;	'.val' '.value' (Get 'what$' at time... '.ifor' '.time')
-	.fg = Extract '.type$' '.formant$' grid
-	selectObject (kg)
-	Remove 'what$' points... .ifor tmin tmax
-	.val1 = Get 'what$' at time... .ifor .time
-	assert .val1 = undefined;	'.val1' (Get 'what$' at time... '.ifor' '.time')
-	plusObject (.fg)
-	Replace '.type$' '.formant$' grid
-	selectObject (kg)
-	.val1 = Get 'what$' at time... .ifor .time
-	if .var$ = "amplitude"
-		.val = undefined
-	endif
-	assert .val1 =.val; '.val1' '.val' (Get 'what$' at time... '.ifor' '.time')
-	removeObject (.fg)
-endproc
-
-procedure setget_formants .tYPE$
-	.type$ = replace_regex$ (.tYPE$, "(^.)","\L\1", 1)
-	for .i to numberOf'.tYPE$'Formants
-		.time = randomUniform (tmin, tmax)
-		.f = (2*.i-1) * randomUniform (450, 550)
-		.b = .f /10
-		.a = randomUniform (70, 90)
-		call setget_3 '.type$' "formant" "frequency" .i .time .f
-		call setget_3 '.type$' "formant" "bandwidth" .i .time .b
-		if .tYPE$ <> "Delta"
-			call setget_3 '.type$' "formant" "amplitude" .i .time .a
-		endif
-	endfor
-	selectObject (kg)
-	Formula ('.type$' formant frequencies)... self + 100
-	Formula ('.type$' formant bandwidths)... self * 2
-endproc
-
-procedure setget_antiformants .tYPE$
-	.type$ = replace_regex$ (.tYPE$, "(^.)","\L\1", 1)
-	for .i to numberOf'.tYPE$'AntiFormants
-		.time = randomUniform (tmin, tmax)
-		.f = (2*.i-1) * randomUniform (450, 550)
-		.b = .f /10
-		call setget_3 '.type$' "antiformant" "frequency" .i .time .f
-		call setget_3 '.type$' "antiformant" "bandwidth" .i .time .b
-	endfor
-	selectObject (kg)
-	Formula ('.type$' antiformant frequencies)... self + 100
-	Formula ('.type$' antiformant bandwidths)... self * 2
-endproc
-
-
-procedure setget_deltaformants
-	for .i to numberOfDeltaFormants
-		.time = randomUniform (tmin, tmax)
-		.f = randomUniform (50, 60)
-		.b = .f /10
-		call setget_2p "formant" .i .time .f
-		call setget_2p "bandwidth" .i .time .b
-	endfor
-endproc
-
-procedure setget_antiformants_old .type$
-	for .i to numberOf'.type$'AntiFormants
-		.time = randomUniform (tmin, tmax)
-		.f = (2*.i-1) * randomUniform (450, 550)
-		.b = .f /10
-		call setget_3_old "formant" "'.type$' antiformant" .i .time .f
-		call setget_3_old "bandwidth" "'.type$' antiformant" .i .time .b
-	endfor
-endproc
-
-procedure test_deltaFormants_old
-	.kg = Create KlattGrid... kg 0 1 6 1 1 6 1 1 1
-	Add pitch point... 0.5 100
-	Add voicing amplitude point... 0.5 90
-	Add bandwidth point... "Normal formant" 1 0.5 50
-	Add delta formant point... 1 0.5 500
-	Remove formant points between... "Normal formant" 1 0 2
-	Add formant point... "Normal formant" 1 0 400
-	Add formant point... "Normal formant" 1 1 600
-	Add formant point... "Normal formant" 1 0.003553 400
-	Add formant point... "Normal formant" 1 0.002 300
-	Add formant point... "Normal formant" 1 0.0112 430
-	.sound = To Sound
-	selectObject (.kg)
-	.fg = Extract formant grid (open phases)... 0.1
-	removeObject (.sound, .kg, .fg)
-endproc
-
-procedure test_deltaFormants
-	.kg = Create KlattGrid... kg 0 1 6 1 1 6 1 1 1
-	Add pitch point... 0.5 100
-	Add voicing amplitude point... 0.5 90
-	Add oral formant bandwidth point... 1 0.5 50
-	Add delta formant frequency point... 1 0.5 500
-	Remove oral formant frequency points... 1 0 2
-	Add oral formant frequency point... 1 0 400
-	Add oral formant frequency point... 1 1 600
-	Add oral formant frequency point... 1 0.003553 400
-	Add oral formant frequency point... 1 0.002 300
-	Add oral formant frequency point... 1 0.0112 430
-	.sound = To Sound
-	selectObject (.kg)
-	.fg = Extract oral formant grid (open phases)... 0.1
-	removeObject (.sound, .fg, .kg)
-endproc
-
-


=====================================
dwtools/KlattGrid.cpp
=====================================
@@ -2034,7 +2034,7 @@ void structKlattGrid :: v_info () {
 	vocalTract -> v_info ();
 	MelderInfo_writeLine (U"\n--- CouplingGrid ---\n");
 	coupling -> v_info ();
-	MelderInfo_writeLine (U"\n--- FricationgGrid ---\n");
+	MelderInfo_writeLine (U"\n--- FricationGrid ---\n");
 	frication -> v_info ();
 }
 
@@ -2444,6 +2444,8 @@ void KlattGrid_replaceAmplitudeTier (KlattGrid me, kKlattGridFormantType formant
 autoFormantGrid KlattGrid_extractFormantGrid (KlattGrid me, kKlattGridFormantType formantType) {
 	try {
 		autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType);
+		Melder_require ((*fg) -> formants . size > 0,
+			KlattGrid_getFormantName (formantType), U"s are not defined.");
 		autoFormantGrid thee = Data_copy (fg->get());
 		return thee;
 	} catch (MelderError) {
@@ -2949,29 +2951,34 @@ autoKlattGrid Sound_to_KlattGrid_simple (Sound me, double timeStep, integer maxi
 	}
 }
 
-autoKlattGrid KlattGrid_createFromVowel (double duration, double f0start, double f1, double b1, double f2, double b2, double f3, double b3, double f4, double formantFrequencyInterval, double bandWidthFraction) {
+autoKlattGrid KlattGrid_createFromVowel (double duration, double f0start, double f1, double b1, double f2, double b2, double f3, double b3, double f4, double bandWidthFraction, double formantFrequencyInterval) {
 	integer numberOfOralFormants = 15;
-	double tmid = duration / 2.0;
+	double tstart = 0.0;
 	autoKlattGrid me = KlattGrid_create (0.0, duration, numberOfOralFormants, 0, 0, 0, 0, 0, 0);
-	KlattGrid_addPitchPoint (me.get(), 0.0, f0start);
-	KlattGrid_addVoicingAmplitudePoint (me.get(), tmid, 90.0);
+	KlattGrid_addPitchPoint (me.get(), tstart, f0start);
+	KlattGrid_addVoicingAmplitudePoint (me.get(), tstart, 90.0);
 	if (f1 > 0.0) {
-		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 1, tmid, f1);
-		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 1, tmid, b1);
+		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 1, tstart, f1);
+		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 1, tstart, b1);
 	}
 	if (f2 > 0.0) {
-		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 2, tmid, f2);
-		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 2, tmid, b2);
+		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 2, tstart, f2);
+		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 2, tstart, b2);
 	}
 	if (f3 > 0) {
-		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 3, tmid, f3);
-		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 3, tmid, b3);
+		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 3, tstart, f3);
+		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 3, tstart, b3);
 	}
 	if (f4 > 0) {
-		for (integer iformant = 4; iformant <= numberOfOralFormants; iformant ++) {
-			double frequency =  f4 + (iformant - 4) * formantFrequencyInterval;
-			KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, iformant, tmid, frequency);
-			KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, iformant, tmid, frequency * bandWidthFraction);
+		KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, 4, tstart, f4);
+		KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, 4, tstart, f4 * bandWidthFraction);
+	}
+	if (formantFrequencyInterval > 0) {
+		double startFrequency = std::max (std::max (f1, f2), std::max (f3, f4));
+		for (integer iformant = 5; iformant <= numberOfOralFormants; iformant ++) {
+			double frequency =  startFrequency + (iformant - 4) * formantFrequencyInterval;
+			KlattGrid_addFormantPoint (me.get(), kKlattGridFormantType::Oral, iformant, tstart, frequency);
+			KlattGrid_addBandwidthPoint (me.get(), kKlattGridFormantType::Oral, iformant, tstart, frequency * bandWidthFraction);
 		}
 	}
 	return me;


=====================================
dwtools/KlattGrid.h
=====================================
@@ -102,7 +102,7 @@ autoKlattGrid KlattGrid_create (double tmin, double tmax, integer numberOfForman
 	integer numberOfTrachealFormants, integer numberOfTrachealAntiFormants,
 	integer numberOfFricationFormants, integer numberOfDeltaFormants);
 
-autoKlattGrid KlattGrid_createFromVowel (double duration, double f0start, double f1, double b1, double f2, double b2, double f3, double b3, double f4, double formantFrequencyInterval, double bandWidthFraction);
+autoKlattGrid KlattGrid_createFromVowel (double duration, double f0start, double f1, double b1, double f2, double b2, double f3, double b3, double f4, double bandWidthFraction, double formantFrequencyInterval);
 
 autoKlattGrid KlattGrid_createExample ();
 autoKlattGridPlayOptions KlattGridPlayOptions_create ();


=====================================
dwtools/manual_KlattGrid.cpp
=====================================
@@ -119,6 +119,65 @@ MAN_BEGIN (U"Create KlattGrid...", U"djmw", 20081224)
 INTRO (U"A command to create a multitier @@KlattGrid@ speech synthesizer.")
 MAN_END
 
+MAN_BEGIN (U"Create KlattGrid from vowel...", U"djmw", 20191007)
+INTRO (U"Create a new @@KlattGrid@ from the specifications for a vowel.")
+ENTRY (U"Settings")
+TAG (U"##Name#")
+DEFINITION (U"defines the name that the newly created KlattGrid will get in the list of objects.")
+TAG (U"##Duration (s)#")
+DEFINITION (U"defines the duration of the KlattGrid. The created KlattGrid will have a start time of 0 seconds "
+	"and an end time of %%duration% seconds. ")
+TAG (U"##Pitch (Hz)#")
+DEFINITION (U"defines the value of the pitch point that will be added at the start of the Klattgrid.")
+TAG (U"##F1 (Hz)#, ##F2 (Hz)#, ##F3 (Hz), F4 (Hz)##")
+DEFINITION (U"define the frequencies in hertz of the first four formants. If a frequency is not positive the formant is not used.")
+TAG (U"##B1 (Hz)#, ##B2 (Hz)#, ##B3 (Hz)#")
+DEFINITION (U"define the bandwidths in hertz of the first three formants")
+TAG (U"##Bandwidth fraction#")
+DEFINITION (U"defines the bandwidths of the fourth and higher formants as a fraction of the formant's frequency (i.e. it is the inverse of the formant's %%quality factor%). "
+	"For example if F4 equals 2800 Hz and the \"Bandwidth fraction\" was chosen as 0.05 then its "
+	"bandwidth will be 0.05*2800 = 140 Hz. The quality factor of this fourth formant is 20.")
+TAG (U"##Formant frequency interval (Hz)#")
+DEFINITION (U"defines the distances between the following formants in hertz. For example, if this values is chosen "
+	"as 1100 Hz and if F4 happens to be 3000 Hz then F5 will be 4100 Hz, F6 will be 5200 Hz, F7 will be 6300 Hz, etc."
+	"If the value is not positive these formants will not be created at all. You would typically choose this value "
+	"as 1000 / 1100 Hz for a male / female voice." )
+ENTRY (U"Examples")
+NORMAL (U"The following script creates a vowel sound with many formants wich will sound like the vowel /a/. "
+	"The formant frequencies will be: F1 = 800 Hz, F2 = 1200 Hz, F3 = 2300 Hz, F4 = 2800 Hz. The frequencies of the higher "
+	"formants will be at intervals of 1000 Hz, starting from F4. Therefore, F5 = 3800 Hz, F6 = 4800 Hz, F7 = 5800 Hz, "
+	"and so on. The bandwidths will be B1 = 80 Hz, B2 = 80 Hz, B3 = 100 Hz. "
+	"The bandwidths of the fourth and higher formants will be 0.05 times their frequency. Therefore, B4 = 140 Hz, "
+	"B5 = 190 Hz, B6 = 240 Hz, B7 = 290 Hz, and so on. ")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.05, 1000")
+CODE (U"To Sound")
+NORMAL (U"The following script will create a two formant sound which also sounds like an /a/."
+	"The formant frequencies will be 800 Hz and 1200 Hz.")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 0, 100, 0, 0.1, 0")
+CODE (U"To Sound")
+NORMAL (U"The following script will create a formant sound which also sounds like an /a/."
+	" The formant frequencies will be 800 Hz, 1200 Hz, 2200 Hz, 3200 Hz, 4200, and so on, with 1000 Hz separation).")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 0, 100, 0, 0.05, 1000")
+CODE (U"To Sound")
+NORMAL (U"Because all the frequency points of the corresponding tiers in this KlattGrid are defined at "
+	"the start time of the grid, i.e. at time 0.0 seconds, it is easy "
+	"to change the characteristics of the vowel sound by adding new points. For example, given one of the /a/ sounds above "
+	"which were all synthesized with constant pitch we can have a falling pitch with:")
+CODE (U"Create KlattGrid from vowel: \"a\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.05, 1000")
+CODE (U"Add pitch point: 0.3, 100.0")
+CODE (U"To Sound")
+NORMAL (U"An /au/ diphthong is also easily made by a simple extension with two oral formant frequency points:")
+CODE (U"Create KlattGrid from vowel: \"au\", 0.3, 125, 800, 80, 1200, 80, 2300, 100, 2800, 0.05, 1000")
+CODE (U"Add pitch point: 0.3, 100.0")
+CODE (U"Add oral formant frequncy point: 1, 0.3, 300")
+CODE (U"Add oral formant frequncy point: 2, 0.3, 600")
+CODE (U"To Sound")
+NORMAL (U"Formant frequencies and bandwidths for 16 Swedish vowels are presented by "
+	"@@Hawks & Miller (1995)@ in their table 1. They further give equations for bandwidths as a function "
+	"of formant frequency.\n"
+	"@@Fleisher et al. (2015)@ present in their table 1 values for the first 5 formant frequencies and bandwidths of the German vowels /a/, /i/ and /\\hs/ for speech mode and for singing mode. In general their bandwidths are lower than as predicted by the Hawks and Miller equations.")
+MAN_END
+
 #define PhonationGrid_to_Sound_COMMON_PARAMETERS_HELP \
 TAG (U"##Sampling frequency (Hz)") \
 DEFINITION (U"the @@sampling frequency@ of the resulting sound.") \


=====================================
dwtools/manual_dwtools.cpp
=====================================
@@ -2411,7 +2411,7 @@ NORMAL (U"Getting exact timing of the %%glottal closure instants%% (GCI) and %%g
 	"respectively, occur. ")
 MAN_END
 
-MAN_BEGIN (U"Electroglottogram: Derivative...", U"djmw", 20190903)
+MAN_BEGIN (U"Electroglottogram: Derivative...", U"djmw", 20190930)
 INTRO (U"Calculates the derivative of the @@Electroglottogram at .")
 ENTRY (U"Settings")
 TAG (U"##Low-pass frequency (Hz)")
@@ -2423,11 +2423,14 @@ DEFINITION (U"defines the width of the transition area between fully passed and
 TAG (U"##Scale absolute peak at 0.99")
 DEFINITION (U"defines whether the derivative should be scaled or not.")
 ENTRY (U"Algorithm")
-NORMAL (U"The derivative of a wave form is most easitly calculated in the spectral domain. "
-	"If %%x%(%%t%) = \\in%%X%(%%f%)exp(2\\pi%%ift%) %%dt%, then"
-	" d%%x%(%%t%)/d%%t% = \\in%%X(%%f%)2\\pi%%if% exp(2\\pi%%ift%)d%%t%.")
-NORMAL (U"Therefore, by taking the spectrum of the signal and from this spectrum calculate new real and imaginary components and then transform back to the time doain we get the derivative.")
-NORMAL (U"The multiplication of the spectral components with the factor 2\\pi%%if% will result in a new %%X%\\'p(%%f%) whose components will be: Re(%%X\\'p%(%%f%)) = -2\\pi%%f% Im (%%X%(%%f%))  and Im(%%X\\'p%(%%f%)) =2\\pi%%f% Re(%%X%(%%f%)).")
+NORMAL (U"The derivative of a wave form %%x%(%%t%) is most easily calculated in the spectral domain. According to "
+	"Fourier theory, if %%x%(%%t%) = \\in%%X%(%%f%)exp(2\\pi%%ift%) %%dt%, then"
+	" d%%x%(%%t%)/d%%t% = \\in%%X(%%f%)2\\pi%%if% exp(2\\pi%%ift%)d%%t%, where %%X%(%%f%) is the spectrum "
+	"of the %%x%(%%t).")
+NORMAL (U"Therefore, by taking the spectrum of the signal and from this spectrum calculate new real and "
+	"imaginary components and then transform back to the time doain we get the derivative.")
+NORMAL (U"The multiplication of the spectral components with the factor 2\\pi%%if% will result in a new "
+	"%%X%\\'p(%%f%) whose components will be: Re(%%X\\'p%(%%f%)) = -2\\pi%%f% Im (%%X%(%%f%)) and Im(%%X\\'p%(%%f%)) =2\\pi%%f% Re(%%X%(%%f%)).")
 ENTRY (U"About dEGG")
 NORMAL (U"The derivative of the Electroglottogram is often indicated as dEGG or DEGG. @@Henrich et al. (2004)@ used the peaks in the derivative to find the %%glottal closure instants% and sometimes also the %%glottal opening instants%. "
 	"However, in their paper and also in other papers like, for example,  @@Herbst et al. (2014)@, the derivative they use is not the exact derivative as calculated in the way explained above. "
@@ -2447,13 +2450,13 @@ TAG (U"##Closing threshold (0-1)#")
 DEFINITION (U"defines the relative amplitude in each glottal cycle where the moment of glottal closure will be chosen. ")
 MAN_END
 
-MAN_BEGIN (U"electroglottography", U"djmw", 20190903)
+MAN_BEGIN (U"electroglottography", U"djmw", 20190929)
 INTRO (U"Electroglottography (EGG) is a low-cost, noninvasive technology for measuring changes of relative vocal fold contact area during laryngeal voice production @@Herbst (2019)|(Herbst, 2019)@.")
 NORMAL (U"In electroglottography (EGG) a high-frequency, low-amperage current is passed between two "
 	"electrodes placed on each side of the thyroid cartilage. Changes in vocal fold contact area "
 	"(VFCA) during vocal fold vibration result in admittance variation, and the resulting "
 	"(demodulated) EGG signal is proportional to the relative VFCA.")
-NORMAL (U"In Praat the EEG signal is represented by the @@Electroglottogram at .")
+NORMAL (U"In Praat the EGG signal is represented by the @@Electroglottogram at .")
 NORMAL (U"From standard electroglottography measurements generally a multi-channel sound file results. One channel of this file contains the recorded electroglottogram, the other the recorded sound. You can extract the electroglottogram with the @@Sound: Extract Electroglottogram...|Extract Electroglottogram...@ command that you will find under the ##Sound: Convert -# menu.")
 MAN_END
 
@@ -4231,17 +4234,17 @@ TAG (U"##Trim label#")
 DEFINITION (U"determines the label that the trimmed intervals in the TextGrid will get.")
 MAN_END
 
-MAN_BEGIN (U"Sound & Pitch: To Spectrogram...", U"djmw", 20141024)
+MAN_BEGIN (U"Sound & Pitch: To Spectrogram...", U"djmw", 20191008)
 INTRO (U"A command that creates a @Spectrogram object from the selected "
 	"@Sound and @Pitch objects by @@band filtering in the frequency domain@ with a "
 	"bank of filters whose bandwidths depend on the local pitch.")
 NORMAL (U"The filter functions used are:")
-FORMULA (U"%#H(%f, %F__0_) = 1 / (((%f__%c_^^2^ - %f^2) /%f\\.c%B(%F__0_)))^2 + 1),")
+FORMULA (U"%#H(%f, %f__0_) = 1 / (((%f__%c_^^2^ - %f^2) /%f\\.c%B(%f__0_)))^2 + 1),")
 NORMAL (U"where %f__%c_ is the central (resonance) frequency of the filter. "
-	"%B(%F__0_) is the bandwidth in Hz and determined as")
-FORMULA (U"%B(%F__0_) = %relativeBandwidth\\.c%F__0_, ")
-NORMAL (U"where %F__0_ is the fundamental frequency as determined from the Pitch "
-	"object. Whenever the value of %F__0_ is undefined, a value of 100 Hz is taken.")
+	"%B(%f__0_) is the bandwidth in Hz and determined as")
+FORMULA (U"%B(%f__0_) = %relativeBandwidth\\.c%f__0_, ")
+NORMAL (U"where %f__0_ is the fundamental frequency as determined from the Pitch "
+	"object. Whenever the value of %f__0_ is undefined, a value of 100 Hz is taken.")
 MAN_END
 
 MAN_BEGIN (U"Sound: To MelFilter...", U"djmw", 20141022)
@@ -4409,14 +4412,14 @@ TAG (U"%numberOfObservations")
 TAG (U"%centroid")
 MAN_END
 
-MAN_BEGIN (U"Sound: Extract Electroglottogram...", U"djmw", 20190827)
+MAN_BEGIN (U"Sound: Extract Electroglottogram...", U"djmw", 20190929)
 INTRO (U"Extract one of the channels of a @@Sound@ as an @@Electroglottogram at .")
 ENTRY (U"Settings")
 TAG (U"##Channel number#")
 DEFINITION (U"defines the Electroglottogram channel in the sound.")
 TAG (U"##Invert#")
 DEFINITION (U"defines whether the wave in the Elecletroglottogram channel has to be inverted or not. "
-	"The convention is that a positive direction in the Elecletroglottogram wave corresponds to "
+	"The convention is that a positive direction in the Electroglottogram wave corresponds to "
 	"an increase in contact area between the vocal folds which occurs if the vocal folds are closing. "
 	"Since closing the vocal folds, in general, happens much faster than opening them, the steepest "
 	"slope in each cycle of the wave should be the %%upward% slope. If this is not the case you "


=====================================
dwtools/praat_KlattGrid_init.cpp
=====================================
@@ -130,19 +130,19 @@ FORM (NEW1_KlattGrid_createFromVowel, U"Create KlattGrid from vowel", U"Create K
 	WORD (name, U"Name", U"a")
 	POSITIVE (duration, U"Duration (s)", U"0.4")
 	POSITIVE (f0start, U"Pitch (Hz)", U"125.0")
-	POSITIVE (f1, U"F1 (Hz)", U"800.0")
-	POSITIVE (b1, U"B1 (Hz)", U"80.0")
-	POSITIVE (f2, U"F2 (Hz)", U"1200.0")
-	POSITIVE (b2, U"B2 (Hz)", U"80.0")
-	POSITIVE (f3, U"F3 (Hz)", U"2300.0")
+	REAL (f1, U"F1 (Hz)", U"800.0")
+	POSITIVE (b1, U"B1 (Hz)", U"50.0")
+	REAL (f2, U"F2 (Hz)", U"1200.0")
+	POSITIVE (b2, U"B2 (Hz)", U"50.0")
+	REAL (f3, U"F3 (Hz)", U"2300.0")
 	POSITIVE (b3, U"B3 (Hz)", U"100.0")
-	POSITIVE (f4, U"F4 (Hz)", U"2800.0")
-	POSITIVE (bandWidthFraction, U"Bandwidth fraction", U"0.1")
-	POSITIVE (formantFrequencyInterval, U"Formant frequency interval (Hz) (Hz)", U"1000.0")
+	REAL (f4, U"F4 (Hz)", U"2800.0")
+	POSITIVE (bandWidthFraction, U"Bandwidth fraction", U"0.05")
+	REAL (formantFrequencyInterval, U"Formant frequency interval (Hz)", U"1000.0")
 	OK
 DO
 	CREATE_ONE
-		autoKlattGrid result = KlattGrid_createFromVowel (duration, f0start, f1, b1, f2, b2, f3, b3, f4, formantFrequencyInterval, bandWidthFraction);
+		autoKlattGrid result = KlattGrid_createFromVowel (duration, f0start, f1, b1, f2, b2, f3, b3, f4, bandWidthFraction, formantFrequencyInterval);
 	CREATE_ONE_END (name)
 }
 


=====================================
fon/FunctionEditor.cpp
=====================================
@@ -425,12 +425,12 @@ static void gui_drawingarea_cb_resize (FunctionEditor me, GuiDrawingArea_ResizeE
 static void menu_cb_preferences (FunctionEditor me, EDITOR_ARGS_FORM) {
 	EDITOR_FORM (U"Preferences", nullptr)
 		BOOLEAN (synchronizeZoomAndScroll, U"Synchronize zoom and scroll", my default_synchronizedZoomAndScroll ())
-		BOOLEAN (showSelectionViewer, U"Show selection viewer", my default_showSelectionViewer ())
+		BOOLEAN (showSelectionViewer, Melder_cat (U"Show ", my v_selectionViewerName ()), my default_showSelectionViewer ())
 		POSITIVE (arrowScrollStep, Melder_cat (U"Arrow scroll step (", my v_format_units_short (), U")"), my default_arrowScrollStep ())
 		my v_prefs_addFields (cmd);
 	EDITOR_OK
 		SET_BOOLEAN (synchronizeZoomAndScroll, my pref_synchronizedZoomAndScroll ())
-		SET_BOOLEAN (showSelectionViewer, my pref_showSelectionViewer())
+		SET_BOOLEAN (showSelectionViewer, my pref_showSelectionViewer ())
 		SET_REAL (arrowScrollStep, my p_arrowScrollStep)
 		my v_prefs_setValues (cmd);
 	EDITOR_DO


=====================================
fon/FunctionEditor.h
=====================================
@@ -83,6 +83,7 @@ Thing_define (FunctionEditor, Editor) {
 	virtual void v_drawRealTimeSelectionViewer (int /* phase */, double /* time */) { }
 	virtual void v_prepareDraw () { }   // for less flashing
 	virtual conststring32 v_domainName () { return U"time"; }
+	virtual conststring32 v_selectionViewerName () { return U"selection viewer"; }
 	virtual conststring32 v_format_domain () { return U"Time domain:"; }
 	virtual const char *v_format_short () { return u8"%.3f"; }
 	virtual const char *v_format_long () { return u8"%f"; }


=====================================
fon/Sound_and_Spectrum.cpp
=====================================
@@ -140,7 +140,7 @@ autoSpectrum Spectrum_lpcSmoothing (Spectrum me, int numberOfPeaks, double preem
 		integer nfft = 2 * (thy nx - 1);
 		integer ndata = numberOfCoefficients < nfft ? numberOfCoefficients : nfft - 1;
 		double scale = 10.0 * (gain > 0.0 ? sqrt (gain) : 1.0) / numberOfCoefficients;
-		autoVEC data = newVECraw (nfft);
+		autoVEC data = newVECzero (nfft);
 		data [1] = 1.0;
 		for (integer i = 1; i <= ndata; i ++)
 			data [i + 1] = a [i];


=====================================
fon/TextGridEditor.h
=====================================
@@ -2,7 +2,7 @@
 #define _TextGridEditor_h_
 /* TextGridEditor.h
  *
- * Copyright (C) 1992-2011,2012,2014,2015,2017 Paul Boersma
+ * Copyright (C) 1992-2005,2007-2019 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -74,6 +74,8 @@ Thing_define (TextGridEditor, TimeSoundAnalysisEditor) {
 		override;
 	void v_prefs_getValues (EditorCommand cmd)
 		override;
+	conststring32 v_selectionViewerName ()
+		override { return U"IPA chart"; }
 	void v_createMenuItems_view_timeDomain (EditorMenu menu)
 		override;
 	void v_highlightSelection (double left, double right, double bottom, double top)


=====================================
fon/manual_Script.cpp
=====================================
@@ -1582,7 +1582,7 @@ CODE (U"Play")
 CODE (U"Erase all")
 NORMAL (U"When you run this script, you'll see a rectangle appear in the ##Praat Picture# window "
 	"(that's what the command ##Draw inner box# in the #Margins menu does), "
-	"then you'll hear the Sound play tiwce, then you'll see the rectangle disappear from the Picture window "
+	"then you'll hear the Sound play twice, then you'll see the rectangle disappear from the Picture window "
 	"(that's what the command ##Erase all# from the #Edit menu does).")
 NORMAL (U"Here we see that the Praat scripting language is an example of a %%procedural programming language%, "
 	"which means that the five %statements are executed in the order in which they appear in the script, "


=====================================
fon/manual_tutorials.cpp
=====================================
@@ -22,8 +22,11 @@
 void manual_tutorials_init (ManPages me);
 void manual_tutorials_init (ManPages me) {
 
-MAN_BEGIN (U"What's new?", U"ppgb", 20190928)
+MAN_BEGIN (U"What's new?", U"ppgb", 20191016)
 INTRO (U"Latest changes in Praat.")
+NORMAL (U"##6.1.05# (16 October 2019)")
+LIST_ITEM (U"• Repaired a bug introduced in 6.0.44 that could cause rubbish LPC smoothing.")
+LIST_ITEM (U"• Repaired a rare crash when dragging a selection on the Mac.")
 NORMAL (U"##6.1.04# (28 September 2019)")
 LIST_ITEM (U"• @Electroglottography.")
 LIST_ITEM (U"• Sound and other windows: ##Widen or shrink selection...#.")


=====================================
sys/Graphics_colour.cpp
=====================================
@@ -231,17 +231,18 @@ static void highlight (Graphics graphics, integer x1DC, integer x2DC, integer y1
 						if (SUPPORT_DIRECT_DRAWING) {
 							[drawingArea lockFocus];
 							CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
-							Melder_assert (context);
-							CGContextSaveGState (context);
-							//CGContextSetBlendMode (context, kCGBlendModeDifference);
-							CGContextSetBlendMode (context, kCGBlendModeDarken);
-							CGContextSetShouldAntialias (context, false);
-							NSColor *colour = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName: NSDeviceRGBColorSpace];
-							double red = 0.5 + 0.5 * colour.redComponent, green = 0.5 + 0.5 * colour.greenComponent, blue = 0.5 + 0.5 * colour.blueComponent;
-							//CGContextSetRGBFillColor (context, 1.0 - red, 1.0 - green, 1.0 - blue, 1.0);
-							CGContextSetRGBFillColor (context, red, green, blue, 1.0);
-							CGContextFillRect (context, rect);
-							CGContextRestoreGState (context);
+							if (context) {
+								CGContextSaveGState (context);
+								//CGContextSetBlendMode (context, kCGBlendModeDifference);
+								CGContextSetBlendMode (context, kCGBlendModeDarken);
+								CGContextSetShouldAntialias (context, false);
+								NSColor *colour = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName: NSDeviceRGBColorSpace];
+								double red = 0.5 + 0.5 * colour.redComponent, green = 0.5 + 0.5 * colour.greenComponent, blue = 0.5 + 0.5 * colour.blueComponent;
+								//CGContextSetRGBFillColor (context, 1.0 - red, 1.0 - green, 1.0 - blue, 1.0);
+								CGContextSetRGBFillColor (context, red, green, blue, 1.0);
+								CGContextFillRect (context, rect);
+								CGContextRestoreGState (context);
+							}
 							[drawingArea unlockFocus];
 							//GuiShell_drain (nullptr);
 						} else {


=====================================
sys/Gui.h
=====================================
@@ -2,7 +2,7 @@
 #define _Gui_h_
 /* Gui.h
  *
- * Copyright (C) 1993-2018 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2019 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -963,7 +963,7 @@ void GuiObject_destroy (GuiObject me);
 
 /********** EVENTS **********/
 
-void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file));
+void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file), void (*finishedOpeningDocumentsCallback) ());
 void Gui_setQuitApplicationCallback (int (*quitApplicationCallback) (void));
 
 extern uinteger theGuiTopLowAccelerators [8];


=====================================
sys/GuiMenu.cpp
=====================================
@@ -1,6 +1,6 @@
 /* GuiMenu.cpp
  *
- * Copyright (C) 1992-2012,2013,2015,2016,2017 Paul Boersma,
+ * Copyright (C) 1992-2005,2007-2019 Paul Boersma,
  *               2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
@@ -31,16 +31,20 @@ void structGuiMenu :: v_destroy () noexcept {
 		(void) void_me;
 		GuiMenu me = (GuiMenu) _GuiObject_getUserData (widget);
 		trace (U"destroying GuiMenu ", Melder_pointer (me));
-		if (! me) return;   // we could be destroying me
+		if (! me)
+			return;   // we could be destroying me
 		my d_widget = nullptr;   // undangle
-		if (my d_cascadeButton) my d_cascadeButton -> d_widget = nullptr;   // undangle
-		if (my d_menuItem) my d_menuItem -> d_widget = nullptr;   // undangle
+		if (my d_cascadeButton)
+			my d_cascadeButton -> d_widget = nullptr;   // undangle
+		if (my d_menuItem)
+			my d_menuItem -> d_widget = nullptr;   // undangle
 		forget (me);
 	}
 	static void _guiGtkMenuCascadeButton_destroyCallback (GuiObject widget, gpointer void_me) {
 		(void) void_me;
 		GuiMenu me = (GuiMenu) _GuiObject_getUserData (widget);
-		if (! me) return;
+		if (! me)
+			return;
 		trace (U"destroying GuiButton ", Melder_pointer (my d_cascadeButton.get()));
 		gtk_widget_destroy (GTK_WIDGET (my d_widget));
 	}
@@ -50,16 +54,24 @@ void structGuiMenu :: v_destroy () noexcept {
 		(void) call;
 		GuiMenu me = (GuiMenu) _GuiObject_getUserData (widget);
 		trace (U"destroying GuiMenu ", Melder_pointer (me));
-		if (! me) return;   // we could be destroying me
+		if (! me)
+			return;   // we could be destroying me
 		my d_widget = nullptr;   // undangle
-		if (my d_cascadeButton) my d_cascadeButton -> d_widget = nullptr;   // undangle
-		if (my d_menuItem) my d_menuItem -> d_widget = nullptr;   // undangle
+		if (my d_cascadeButton)
+			my d_cascadeButton -> d_widget = nullptr;   // undangle
+		if (my d_menuItem)
+			my d_menuItem -> d_widget = nullptr;   // undangle
 		forget (me);
 	}
 #elif cocoa
 	static void (*theOpenDocumentCallback) (MelderFile file);
-	void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file)) {
+	static void (*theFinishedOpeningDocumentsCallback) ();
+	void Gui_setOpenDocumentCallback (
+		void (*openDocumentCallback) (MelderFile file),
+		void (*finishedOpeningDocumentsCallback) ()
+	) {
 		theOpenDocumentCallback = openDocumentCallback;
+		theFinishedOpeningDocumentsCallback = finishedOpeningDocumentsCallback;
 	}
 	static NSMenu *theMenuBar;
 	static int theNumberOfMenuBarItems = 0;
@@ -194,6 +206,8 @@ void structGuiMenu :: v_destroy () noexcept {
 			if (theOpenDocumentCallback)
 				theOpenDocumentCallback (& file);
 		}
+		if (theFinishedOpeningDocumentsCallback)
+			theFinishedOpeningDocumentsCallback ();
 	}
 	@end
 #endif


=====================================
sys/motifEmulator.cpp
=====================================
@@ -27,6 +27,7 @@
 #include "machine.h"
 
 static void (*theOpenDocumentCallback) (MelderFile file);
+static void (*theFinishedOpeningDocumentsCallback) ();
 static int (*theQuitApplicationCallback) ();
 
 #if defined (_WIN32)
@@ -1701,6 +1702,8 @@ void GuiAppInitialize (const char *name, unsigned int argc, char **argv)
 					}
 				}
 			}
+			if (theFinishedOpeningDocumentsCallback)
+				theFinishedOpeningDocumentsCallback ();
 			exit (0);   // possible problem
 		}
 
@@ -2671,8 +2674,9 @@ void motif_win_setUserMessageCallback (int (*userMessageCallback) (void)) {
 	theUserMessageCallback = userMessageCallback;
 }
 
-void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file)) {
+void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file), void (*finishedOpeningDocumentsCallback) ()) {
 	theOpenDocumentCallback = openDocumentCallback;
+	theFinishedOpeningDocumentsCallback = finishedOpeningDocumentsCallback;
 }
 #endif
 


=====================================
sys/praat.cpp
=====================================
@@ -896,7 +896,8 @@ void praat_dontUsePictureWindow () { praatP.dontUsePictureWindow = true; }
 					Melder_flushError (praatP.title.get(), U": message not completely handled.");
 				}
 			}
-			if (narg && pid) kill (pid, SIGUSR2);
+			if (narg != 0 && pid != 0)
+				kill (pid, SIGUSR2);
 			return true;
 		}
 	#endif
@@ -918,9 +919,12 @@ void praat_dontUsePictureWindow () { praatP.dontUsePictureWindow = true; }
 			or double-clicked a Praat file,
 			while Praat is already running.
 		*/
-		Melder_sprint (text,500, U"Read from file... ", file -> path);
+		Melder_sprint (text,500, U"Read from file: ~", file -> path);
 		sendpraat (nullptr, Melder_peek32to8 (praatP.title.get()), 0, Melder_peek32to8 (text));
 	}
+	static void cb_finishedOpeningDocuments () {
+		praat_updateSelection ();
+	}
 #elif macintosh
 	static int (*theUserMessageCallback) (char32 *message);
 	static void mac_setUserMessageCallback (int (*userMessageCallback) (char32 *message)) {
@@ -948,28 +952,6 @@ void praat_dontUsePictureWindow () { praatP.dontUsePictureWindow = true; }
 		}
 		return noErr;
 	}
-	static pascal OSErr mac_processSignal16 (const AppleEvent *theAppleEvent, AppleEvent * /* reply */, long /* handlerRefCon */) {
-		static bool duringAppleEvent = false;   // FIXME: may have to be atomic?
-		if (! duringAppleEvent) {
-			char16 *buffer;
-			Size actualSize;
-			duringAppleEvent = true;
-			//AEInteractWithUser (kNoTimeOut, nullptr, nullptr);   // use time out of 0 to execute immediately (without bringing to foreground)
-			ProcessSerialNumber psn;
-			GetCurrentProcess (& psn);
-			SetFrontProcess (& psn);
-			AEGetParamPtr (theAppleEvent, 1, typeUTF16ExternalRepresentation, nullptr, nullptr, 0, & actualSize);
-			buffer = (char16 *) malloc ((size_t) actualSize);
-			AEGetParamPtr (theAppleEvent, 1, typeUTF16ExternalRepresentation, nullptr, & buffer [0], actualSize, nullptr);
-			if (theUserMessageCallback) {
-				autostring32 buffer32 = Melder_16to32 (buffer);
-				theUserMessageCallback (buffer32.get());
-			}
-			free (buffer);
-			duringAppleEvent = false;
-		}
-		return noErr;
-	}
 	static int cb_userMessage (char32 *message) {
 		autoPraatBackground background;
 		try {
@@ -1135,7 +1117,7 @@ void praat_init (conststring32 title, int argc, char **argv)
 			MelderInfo_writeLine (U"  -u, --utf16      use UTF-16LE output encoding, no BOM (the default on Windows)");
 			MelderInfo_writeLine (U"  -8, --utf8       use UTF-8 output encoding (the default on MacOS and Linux)");
 			MelderInfo_writeLine (U"  -a, --ansi       use ISO Latin-1 output encoding (lossy, hence not recommended)");
-			MelderInfo_writeLine (U"                   (on Windows, use -0 or -a when you redirect to a pipe or file)");
+			MelderInfo_writeLine (U"                   (on Windows, use -8 or -a when you redirect to a pipe or file)");
 			MelderInfo_close ();
 			exit (0);
 		} else if (strequ (argv [praatP.argumentNumber], "-8") || strequ (argv [praatP.argumentNumber], "--utf8")) {
@@ -1320,11 +1302,14 @@ void praat_init (conststring32 title, int argc, char **argv)
 	if (Melder_batch) {
 		MelderString_empty (& theCurrentPraatApplication -> batchName);
 		for (int i = praatP.argumentNumber - 1; i < argc; i ++) {
-			if (i >= praatP.argumentNumber) MelderString_append (& theCurrentPraatApplication -> batchName, U" ");
+			if (i >= praatP.argumentNumber)
+				MelderString_append (& theCurrentPraatApplication -> batchName, U" ");
 			bool needsQuoting = !! strchr (argv [i], ' ') && (i == praatP.argumentNumber - 1 || i < argc - 1);
-			if (needsQuoting) MelderString_append (& theCurrentPraatApplication -> batchName, U"\"");
+			if (needsQuoting)
+				MelderString_append (& theCurrentPraatApplication -> batchName, U"\"");
 			MelderString_append (& theCurrentPraatApplication -> batchName, Melder_peek8to32 (argv [i]));
-			if (needsQuoting) MelderString_append (& theCurrentPraatApplication -> batchName, U"\"");
+			if (needsQuoting)
+				MelderString_append (& theCurrentPraatApplication -> batchName, U"\"");
 		}
 	} else {
 		trace (U"starting the application");
@@ -1338,7 +1323,7 @@ void praat_init (conststring32 title, int argc, char **argv)
 			trace (U"locale ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
 		#elif motif
 			argv [0] = Melder_32to8 (praatP. title.get()).transfer();   // argc == 4
-			Gui_setOpenDocumentCallback (cb_openDocument);
+			Gui_setOpenDocumentCallback (cb_openDocument, cb_finishedOpeningDocuments);
 			GuiAppInitialize ("Praatwulg", argc, argv);
 		#elif cocoa
 			//[NSApplication sharedApplication];


=====================================
sys/praat_objectMenus.cpp
=====================================
@@ -1,6 +1,6 @@
 /* praat_objectMenus.cpp
  *
- * Copyright (C) 1992-2018 Paul Boersma
+ * Copyright (C) 1992-2019 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -432,11 +432,11 @@ static void readFromFile (MelderFile file) {
 		return;
 	}
 	praat_newWithFile (object.move(), file, MelderFile_name (file));
-	praat_updateSelection ();
 }
 
 FORM_READ (READMANY_Data_readFromFile, U"Read Object(s) from file", 0, true) {
 	readFromFile (file);
+	praat_updateSelection ();
 END }
 
 /********** Callbacks of the Save menu. **********/
@@ -590,6 +590,13 @@ static void cb_openDocument (MelderFile file) {
 		Melder_flushError ();
 	}
 }
+static void cb_finishedOpeningDocuments () {
+	try {
+		praat_updateSelection ();
+	} catch (MelderError) {
+		Melder_flushError ();
+	}
+}
 
 #if cocoa
 DIRECT (PRAAT_cut) {
@@ -716,7 +723,7 @@ void praat_addMenus2 () {
 	praat_addMenuCommand (U"Objects", U"ApplicationHelp", itemTitle_about.string, nullptr, praat_UNHIDABLE, WINDOW_About);
 
 	#if defined (macintosh) || defined (_WIN32)
-		Gui_setOpenDocumentCallback (cb_openDocument);
+		Gui_setOpenDocumentCallback (cb_openDocument, cb_finishedOpeningDocuments);
 	#endif
 }
 


=====================================
sys/praat_version.h
=====================================
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.1.04
-#define PRAAT_VERSION_NUM 6104
+#define PRAAT_VERSION_STR 6.1.05
+#define PRAAT_VERSION_NUM 6105
 #define PRAAT_YEAR 2019
-#define PRAAT_MONTH September
-#define PRAAT_DAY 28
+#define PRAAT_MONTH October
+#define PRAAT_DAY 16


=====================================
test/fon ExperimentMFC/simplest.ExperimentMFC
=====================================
@@ -1,5 +1,5 @@
 "ooTextFile"
-"ExperimentMFC 6"
+"ExperimentMFC 7"
 
 blankWhilePlaying? <yes>
 stimuliAreSounds? <yes>


=====================================
test/fon/examples/sounds/a.wav
=====================================
Binary files /dev/null and b/test/fon/examples/sounds/a.wav differ



View it on GitLab: https://salsa.debian.org/med-team/praat/compare/ecf26c1823655e5b13c9c203458e505f8f371805...b5c0eb994588f431c792528609a0956205761d70

-- 
View it on GitLab: https://salsa.debian.org/med-team/praat/compare/ecf26c1823655e5b13c9c203458e505f8f371805...b5c0eb994588f431c792528609a0956205761d70
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20191019/ebd074eb/attachment-0001.html>


More information about the debian-med-commit mailing list