[med-svn] [Git][med-team/praat][upstream] New upstream version 6.4.01+dfsg
Rafael Laboissière (@rafael)
gitlab at salsa.debian.org
Sun Dec 3 19:46:02 GMT 2023
Rafael Laboissière pushed to branch upstream at Debian Med / praat
Commits:
f4394a63 by Rafael Laboissière at 2023-12-02T09:01:34-03:00
New upstream version 6.4.01+dfsg
- - - - -
11 changed files:
- fon/manual_functions.cpp
- fon/manual_scripting.cpp
- fon/manual_whatsnew.cpp
- fon/praat_Sound.cpp
- foned/SoundAnalysisArea.cpp
- foned/SoundAnalysisArea_enums.h
- sys/EditorM.h
- sys/Ui.cpp
- sys/Ui.h
- sys/praatM.h
- sys/praat_version.h
Changes:
=====================================
fon/manual_functions.cpp
=====================================
@@ -271,10 +271,21 @@ A growing list of functions that you can use in @formulas and @scripting...
, @`runSubprocess$` (%`executableFilePath$`, `...`) – run an external program with the given arguments, and return its output
, @`runSystem` (`...`) – run a system command line with the given arguments concatenated
, @`runSystem$` (`...`) – run a system command line with the given arguments concatenated, and return its output
+, @`selected` ( ) – the ID of the topmost selected object
+, @`selected` (%`i`) – the ID of the %%i%th selected object (as counted from the top, or from the bottom if negative)
+, @`selected` (%`type$`) – the ID of the topmost selected object of type %`type$`
+, @`selected` (%`type$`, %`i`) – the ID of the %%i%th selected object of type %`type$` (as counted from the top,
+ or from the bottom if negative)
+, @`selected$` ( ) – the full name (type + name) of the topmost selected object
+, @`selected$` (%`i`) – the full name (type + name) of the %%i%th selected object (as counted from the top,
+ or from the bottom if negative)
+, @`selected$` (%`type$`) – the name of the topmost selected object of type %`type$`
+, @`selected$` (%`type$`, %`i`) – the name of the %%i%th selected object of type %`type$` (as counted from the top,
+ or from the bottom if negative)
, @`selected#` ( ) – the IDs of all selected objects
-, @`selected#` (%`type`) – the IDs of all selected objects of type %`type`
+, @`selected#` (%`type$`) – the IDs of all selected objects of type %`type$`
, @`selected$#` ( ) – the names of all selected objects
-, @`selected$#` (%`type`) – the names of all selected objects of type %`type`
+, @`selected$#` (%`type$`) – the names of all selected objects of type %`type$`
, @`selectObject` (`...`) – select objects in the list by ID and/or name
, @`semitonesToHertz` (%`x`) – from logarithmic scale %re 100 Hz to acoustic frequency
, @`sigmoid` (%`x`) – 1 / (1 + %e^^-%`x`^)
@@ -3670,6 +3681,56 @@ and return the output of that command line.
For details and examples, see @@Scripting 6.5. Calling system commands at .
+################################################################################
+"`selected`"
+© Paul Boersma 2023
+
+A function that can be used in @Formulas.
+
+Syntax and semantics
+====================
+#`selected` ( )
+: return the ID of the topmost selected object.
+
+#`selected` (%`i`)
+: return the ID of the %%i%th selected object (as counted from the top, or from the bottom if %`i` is negative).
+
+#`selected` (%`type$`)
+: return the ID of the topmost selected object of type %`type$`.
+
+#`selected` (%`type$`, %`i`)
+: return the ID of the %%i%th selected object of type %`type$` (as counted from the top, or from the bottom if %`i` is negative).
+
+Usage
+=====
+For examples, see @@Scripting 4.3. Querying objects at .
+
+################################################################################
+"`selected$`"
+© Paul Boersma 2023
+
+A function that can be used in @Formulas.
+
+Syntax and semantics
+====================
+#`selected$` ( )
+: return the full name (type + name) of the topmost selected object.
+
+#`selected$` (%`i`)
+: return the full name (type + name) of the %%i%th selected object (as counted from the top, or from the bottom if %`i` is negative).
+
+#`selected$` (%`type$`)
+: return the name of the topmost selected object of type %`type$`.
+
+#`selected$` (%`type$`, %`i`)
+: return the name of the %%i%th selected object of type %`type$` (as counted from the top, or from the bottom if %`i` is negative).
+
+Usage
+=====
+This function is useful if you want to write or draw the name of the object.
+For selecting an object, using @`selected` is safer,
+as explained in @@Scripting 4.3. Querying objects at .
+
################################################################################
"`selected#`"
© Paul Boersma 2023
@@ -3681,8 +3742,8 @@ Syntax and semantics
#`selected#` ( )
: return a list of the IDs of all currently selected objects.
-#`selected#` (%`type`)
-: return a list of the IDs of all currently selected objects of type %`type`.
+#`selected#` (%`type$`)
+: return a list of the IDs of all currently selected objects of type %`type$`.
Example
=======
@@ -3741,8 +3802,8 @@ Syntax and semantics
#`selected$#` ( )
: return a list of the names of all currently selected objects.
-#`selected$#` (%`type`)
-: return a list of the names of all currently selected objects of type %`type`.
+#`selected$#` (%`type$`)
+: return a list of the names of all currently selected objects of type %`type$`.
Pitfall
=======
=====================================
fon/manual_scripting.cpp
=====================================
@@ -671,28 +671,28 @@ MAN_BEGIN (U"Scripting 3.2. Numeric variables", U"ppgb", 20230201)
INTRO (U"In any general procedural programming language you can work with %variables, "
"which are places in your computer's memory where you can store a number or anything else.")
NORMAL (U"For instance, you could put the number 3.1 into the variable $%b in the following way:")
-CODE (U"%b = 3.1")
-NORMAL (U"This statement is called as %assignment, i.e., you %assign the %value 3.1 to the %variable $%b. "
- "We read this statement aloud as “$%b becomes 3.1” (or “$%b gets 3.1”, but not “$%b is 3.1”). "
- "What this means is that after this statement, the memory location $%b %contains the numeric value (number) 3.1.")
-NORMAL (U"You can regard a variable as a box: you put the value 3.1 into the box named $%b. "
- "Or you can regard a variable as a house: the house is called $%b and now the family “3.1” is living there. "
+CODE (U"b = 3.1")
+NORMAL (U"This statement is called as %assignment, i.e., you %assign the %value 3.1 to the %variable %`b`. "
+ "We read this statement aloud as “%`b` becomes 3.1” (or “%`b` gets 3.1”, but not “%`b` is 3.1”). "
+ "What this means is that after this statement, the memory location %`b` %contains the numeric value (number) 3.1.")
+NORMAL (U"You can regard a variable as a box: you put the value 3.1 into the box named %`b`. "
+ "Or you can regard a variable as a house: the house is called %`b` and now the family “3.1” is living there. "
"Or you can regard it as any other storage location.")
NORMAL (U"To see what value a variable contains (what’s in the box, or who lives in the house), "
- "you can use the $#writeInfoLine function:")
-CODE (U"%b = 3.1")
-CODE (U"writeInfoLine: “The value is ”, %b, “.”")
+ "you can use the #`writeInfoLine` function:")
+CODE (U"b = 3.1")
+CODE (U"writeInfoLine: “The value is ”, b, “.”")
NORMAL (U"This will put the text “`The value is 3.1.`” into the Info window, as you are invited to verify.")
NORMAL (U"A variable is called a variable because it is %variable, i.e. its value can change. Try the script")
-CODE (U"%b = 3.1")
-CODE (U"%b = 5.8")
-CODE (U"writeInfoLine: “The value is ”, %b, “.”")
-NORMAL (U"You will see that `b` ends up having the value 5.8. The first line puts the value 3.1 there, but the second line "
+CODE (U"b = 3.1")
+CODE (U"b = 5.8")
+CODE (U"writeInfoLine: “The value is ”, b, “.”")
+NORMAL (U"You will see that %`b` ends up having the value 5.8. The first line puts the value 3.1 there, but the second line "
"replaces it with 5.8. It’s like taking the 3.1 out of the box and putting the 5.8 in its stead. "
"Or the family 3.1 moves from the house, and the family called 5.8 moves in.")
NORMAL (U"In an assignment, the part to the right of the “becomes” sign (the “=” sign) doesn’t have to be a number; "
"it can be any %formula that %evaluates to a number. For instance, the script")
-CODE (U"%b = 3.1 * 2")
+CODE (U"b = 3.1 * 2")
CODE (U"writeInfoLine: “The value is ”, b, “.”")
NORMAL (U"puts the text “`The value is 6.2.`” into the Info window. This works because Praat handles the first line "
"in the following way:")
@@ -701,22 +701,22 @@ LIST_ITEM (U"2. the value 6.2 is subsequently stored in the variable `b`.")
NORMAL (U"After line 1 has been executed, the variable %`b` just contains the value 6.2, nothing more; "
"the variable %`b` doesn’t remember that that value has been computed by multiplying 3.1 with 2.")
NORMAL (U"Formulas can contain more things than numbers: they can also contain other variables:")
-CODE (U"%b = 3.1")
-CODE (U"%c = %b * 2")
-CODE (U"writeInfoLine: “The value of b is ”, %b, “, and the value of c is ”, %c, “.”")
+CODE (U"b = 3.1")
+CODE (U"c = b * 2")
+CODE (U"writeInfoLine: “The value of b is ”, b, “, and the value of c is ”, c, “.”")
NORMAL (U"In the first line, %`b` gets the value 3.1. In the second line, the formula `b * 2` first has to be evaluated. "
"Praat looks up the value of %`b` (which is 3.1), so that it knows that the formula actually means `3.1 * 2`. "
"Praat evaluates this formula and stores the result (namely the value 6.2) "
"into the variable %`c`, which will then contain nothing else than the value 6.2. "
"The Info window thus reports “`The value of b is 3.1, and the value of c is 6.2.`”.")
NORMAL (U"After these explanations, consider the following script:")
-CODE (U"%b = 3.1")
-CODE (U"%c = %b * 2")
-CODE (U"%b = 5.8")
-CODE (U"writeInfoLine: “The value of c is ”, %c, “.”")
+CODE (U"b = 3.1")
+CODE (U"c = b * 2")
+CODE (U"b = 5.8")
+CODE (U"writeInfoLine: “The value of c is ”, c, “.”")
NORMAL (U"Can you figure out what the Info will report? If you think it will report "
"“`The value of c is 6.2.`”, then you are correct: after the first line, %`b` contains the value 3.1; "
- "after the second line, the value of $%c is therefore 6.2, and nothing more; "
+ "after the second line, the value of %`c` is therefore 6.2, and nothing more; "
"after line 3, the value of %`b` has changed to 5.8, but the value of %`c` hasn’t changed and is still 6.2.")
NORMAL (U"If you thought that %`c` would end up having the value 11.6, then you’re thinking in terms "
"of a non-procedural language such as Prolog; you may have thought that the thing assigned to %`c` in the second line "
@@ -746,10 +746,10 @@ NORMAL (U"This is the mean power of the whole Sound.")
NORMAL (U"In a script, you want to use the value of this power in the script itself, not in the Info window, "
"perhaps because you want to do computations with it or because you want to report the value with a nice text around it. "
"This is how you do the latter:")
-CODE (U"%power = Get power: 0.0, 0.0")
-CODE (U"writeInfoLine: “The power of this sound is ”, %power, “ Pascal-squared.”")
+CODE (U"power = Get power: 0.0, 0.0")
+CODE (U"writeInfoLine: “The power of this sound is ”, power, “ Pascal-squared.”")
NORMAL (U"The first line of this script executes the menu command ##Get power...#, "
- "but puts the value 0.1350605005239421 into the variable $%power instead of into the Info window "
+ "but puts the value 0.1350605005239421 into the variable %`power` instead of into the Info window "
"(the variable can have any name you like, as long as it starts with a lower-case letter "
"and consists of letters and digits; see @@Scripting 5.1. Variables@).")
NORMAL (U"The second line then reports the value in the Info window, this time with a nice text around it:")
@@ -827,8 +827,8 @@ SCRIPT (6, 3, U""
)
NORMAL (U"A numeric query stores in a numeric variable only the first number that it can find in the text that would appear in the Info window. "
"For instance, the script")
-CODE (U"%power = Get power: 0.0, 0.0")
-CODE (U"writeInfoLine: %power")
+CODE (U"power = Get power: 0.0, 0.0")
+CODE (U"writeInfoLine: power")
NORMAL (U"could give you the following result:")
SCRIPT (6, 3, U""
Manual_DRAW_WINDOW (3, "Praat Info", "File Edit Search Convert Font Help")
@@ -995,38 +995,38 @@ MAN_END
MAN_BEGIN (U"Scripting 4.1. Selecting objects", U"ppgb", 20180428)
NORMAL (U"To simulate the mouse-clicked and dragged selection in the list of objects, "
- "you have the functions #`selectObject`, #`plusObject` and #`minusObject`.")
+ "you have the functions @`selectObject`, @`plusObject` and @`minusObject`.")
NORMAL (U"Suppose you start Praat and use ##Create Sound as tone...# to create a Sound called %tone. "
"In the object list it looks like “1. Sound tone”. "
"Suppose you then do ##To Spectrum...# from the ##Analyse Spectrum# menu. "
"A second object, called “2. Spectrum tone” appears in the list and is selected. "
"To select and play the Sound, you can do either")
-CODE (U"selectObject: 1")
+CODE (U"\\#`{selectObject}: 1")
CODE (U"Play")
NORMAL (U"or")
-CODE (U"selectObject: “Sound tone”")
+CODE (U"\\#`{selectObject}: “Sound tone”")
CODE (U"Play")
NORMAL (U"So you can select an object either by its unique ID (identifier: the unique number by which it appears in the list) "
"or by name.")
-NORMAL (U"The function #selectObject works by first deselecting all objects, and then selecting the one you mention. "
- "If you don’t want to deselect the existing selection, you can use #plusObject or #minusObject. "
+NORMAL (U"The function @`selectObject` works by first deselecting all objects, and then selecting the one you mention. "
+ "If you don’t want to deselect the existing selection, you can use @`plusObject` or @`minusObject`. "
"When the Sound is selected, you can select the Spectrum as well by doing")
-CODE (U"plusObject: 2")
+CODE (U"\\#`{plusObject}: 2")
NORMAL (U"or")
-CODE (U"plusObject: “Spectrum tone”")
+CODE (U"\\#`{plusObject}: “Spectrum tone”")
NORMAL (U"If you then want to deselect the Sound, and keep the Spectrum selected, you can do")
CODE (U"\\#`{minusObject}: 1")
NORMAL (U"or")
-CODE (U"minusObject: “Sound tone”")
+CODE (U"\\#`{minusObject}: “Sound tone”")
NORMAL (U"All these functions can take more than one argument. To select the Sound and the Spectrum together, you can do")
CODE (U"\\#`{selectObject}: 1, 2")
NORMAL (U"or")
-CODE (U"selectObject: “Sound tone”, “Spectrum tone”")
+CODE (U"\\#`{selectObject}: “Sound tone”, “Spectrum tone”")
NORMAL (U"or even")
-CODE (U"selectObject: 1, “Spectrum tone”")
+CODE (U"\\#`{selectObject}: 1, “Spectrum tone”")
NORMAL (U"or, using a numeric vector:")
CODE (U"myObjects# = { 1, 2 }")
-CODE (U"selectObject: myObjects#")
+CODE (U"\\#`{selectObject}: myObjects#")
ENTRY (U"How to refer to objects created in your script")
NORMAL (U"In a script, you typically don't know whether the IDs of the objects are 1 and 2, or much higher numbers. "
"Fortunately, commands that create a new object give you the ID of the object that is created, "
@@ -1038,7 +1038,7 @@ CODE (U"Play ; the Sound is selected, so it plays")
CODE (U"To Spectrum: “yes”")
CODE (U"Draw: 0, 5000, 20, 80, “yes” ; the Spectrum is selected, so it is drawn")
CODE (U"# Remove the created Spectrum and Sound:")
-CODE (U"plusObject: sound ; the Spectrum was already selected")
+CODE (U"\\#`{plusObject}: sound ; the Spectrum was already selected")
CODE (U"Remove")
NORMAL (U"You could also select the objects by name:")
CODE (U"Create Sound as pure tone: “sine377”,")
@@ -1047,97 +1047,141 @@ CODE (U"Play ; the Sound is selected, so it plays")
CODE (U"To Spectrum: “yes”")
CODE (U"Draw: 0, 5000, 20, 80, “yes” ; the Spectrum is selected, so it is drawn")
CODE (U"# Remove the created Spectrum and Sound:")
-CODE (U"plusObject: “Sound sine377” ; the Spectrum was already selected")
+CODE (U"\\#`{plusObject}: “Sound sine377” ; the Spectrum was already selected")
CODE (U"Remove")
NORMAL (U"This works even if there are multiple objects called “Sound sine377”, "
- "because if there are more objects with the same name, #selectObject and #plusObject select the most recently created one, "
+ "because if there are more objects with the same name, @`selectObject` and @`plusObject` select the most recently created one, "
"i.e., the one nearest to the bottom of the list of objects.")
MAN_END
-MAN_BEGIN (U"Scripting 4.2. Removing objects", U"ppgb", 20140111)
-NORMAL (U"In @@Scripting 4.1. Selecting objects|\\SS4.1@ we saw that objects could be removed by selecting them first and then calling the #Remove command. "
- "A faster way is the #removeObject function, which can also remove unselected objects:")
-CODE (U"sound = Create Sound as pure tone: “sine377”,")
-CODE (U"... 1, 0, 1, 44100, 377, 0.2, 0.01, 0.01 ; remember the ID of the Sound")
-CODE (U"Play ; the Sound is selected, so it plays")
-CODE (U"spectrum = To Spectrum: “yes” ; remember the ID of the Spectrum")
-CODE (U"Draw: 0, 5000, 20, 80, “yes” ; the Spectrum is selected, so it is drawn")
-CODE (U"# Remove the created Spectrum and Sound:")
-CODE (U"\\#{removeObject}: sound, spectrum ; remove one selected and one unselected object")
-NORMAL (U"The #removeObject function keeps the objects selected that were selected before "
- "(except of course the ones it throws away). "
- "This allows you to easily throw away objects as soon as you no longer need them:")
-CODE (U"sound = Create Sound as pure tone: “sine377”,")
-CODE (U"... 1, 0, 1, 44100, 377, 0.2, 0.01, 0.01 ; remember the ID of the Sound")
-CODE (U"Play ; the Sound is selected, so it plays")
-CODE (U"spectrum = To Spectrum: “yes”")
-CODE (U"\\#{removeObject}: sound ; we no longer need the Sound, so we remove it")
-CODE (U"Draw: 0, 5000, 20, 80, “yes” ; the Spectrum is still selected, so it is drawn")
-CODE (U"\\#{removeObject}: spectrum ; remove the last object created by the script")
-ENTRY (U"Selecting and removing all objects from the list (don't)")
-NORMAL (U"A very strange command, which you should not normally use, is `select all`:")
- CODE1 (U"\\#{select all}")
- CODE1 (U"Remove")
-NORMAL (U"This selects all objects in the list and then removes them. "
- "Please try not to use this, because it will remove even the objects that your script did not create! "
- "After all, you don’t want the users of your script to lose the objects they created! "
- "So please try to remove in your script only the objects that your script created, "
- "even if the script is for your own use (because if it is a nice script, others will want to use it).")
-MAN_END
-MAN_BEGIN (U"Scripting 4.3. Querying objects", U"ppgb", 20180427)
-NORMAL (U"You can get the name of a selected object into a string variable. "
- "For instance, the following reads the name of the second selected Sound "
- "(as counted from the top of the list of objects) into the variable %`name$`:")
-CODE (U"name$ = selected$ (“Sound”, 2)")
-NORMAL (U"If the Sound was called “Sound hallo”, the variable %`name$` will contain the string “hallo”. "
- "To get the name of the topmost selected Sound object, you can leave out the number:")
-CODE (U"name$ = selected$ (“Sound”)")
-NORMAL (U"To get the full name (type + name) of the third selected object, you do:")
-CODE (U"fullName$ = selected$ (3)")
-NORMAL (U"To get the full name of the topmost selected object, you do:")
-CODE (U"fullName$ = selected$ ()")
-NORMAL (U"To get the type and name out of the full name, you do:")
-CODE (U"type$ = extractWord$ (fullName$, “”)")
-CODE (U"name$ = extractLine$ (fullName$, “ ”)")
-NORMAL (U"Negative numbers count from the bottom. Thus, to get the name of the bottom-most selected Sound "
- "object, you say")
-CODE (U"name$ = selected$ (“Sound”, -1)")
-NORMAL (U"You would use `selected$` () for drawing the object name in a picture:")
-CODE (U"Draw: 0, 0, 0, 0, \"yes\"")
-CODE (U"name$ = selected$ (“Sound”)")
-CODE (U"Text top: “no”, “This is sound ” + name$")
-NORMAL (U"For identifying previously selected objects, this method is not very suitable, since "
- "there may be multiple objects with the same name:")
-CODE (U"# The following two lines are OK:")
-CODE (U"soundName$ = selected$ (“Sound”, -1)")
-CODE (U"pitchName$ = selected$ (“Pitch”)")
-CODE (U"# But the following line is questionable, since it doesn't")
-CODE (U"# necessarily select the previously selected Pitch again:")
-CODE (U"selectObject: “Pitch ” + pitchName$")
-NORMAL (U"Instead of this error-prone approach, you should get the object’s unique ID. "
- "The correct version of our example becomes:")
-CODE (U"sound = selected (“Sound”, -1)")
-CODE (U"pitch = selected (“Pitch”)")
-CODE (U"# Correct:")
-CODE (U"selectObject: pitch")
-NORMAL (U"To get the number of selected Sound objects into a variable, use")
-CODE (U"numberOfSelectedSounds = numberOfSelected (“Sound”)")
-NORMAL (U"To get the number of selected objects into a variable, use")
-CODE (U"numberOfSelectedObjects = numberOfSelected ()")
-ENTRY (U"Example: doing something to every selected Sound")
-CODE (U"sounds# = selected# (“Sound”)")
-CODE (U"# Median pitches of all selected sounds:")
-CODE (U"for i to size (sounds#)")
- CODE1 (U"selectObject: sounds# [i]")
- CODE1 (U"To Pitch: 0.0, 75, 600")
- CODE1 (U"f0 = Get quantile: 0, 0, 0.50, “Hertz”")
- CODE1 (U"appendInfoLine: f0")
- CODE1 (U"Remove")
-CODE (U"endfor")
-CODE (U"# Restore selection:")
-CODE (U"selectObject (sounds#)")
-MAN_END
+MAN_PAGES_BEGIN
+R"~~~(
+################################################################################
+"Scripting 4.2. Removing objects"
+© Paul Boersma 1999,2004,2006–2008,2011,2013,2014
+
+In @@Scripting 4.1. Selecting objects|\SS4.1@ we saw that objects could be removed by
+selecting them first and then calling the #Remove command.
+A faster way is the #removeObject function, which can also remove unselected objects:
+{;
+ sound = Create Sound as pure tone: “sine377”,
+ ... 1, 0, 1, 44100, 377, 0.2, 0.01, 0.01 ; remember the ID of the Sound
+ Play ; the Sound is selected, so it plays
+ spectrum = To Spectrum: “yes” ; remember the ID of the Spectrum
+ Draw: 0, 5000, 20, 80, “yes” ; the Spectrum is selected, so it is drawn
+ # Remove the created Spectrum and Sound:
+ \#`{removeObject}: sound, spectrum ; remove one selected and one unselected object
+}
+The #removeObject function keeps the objects selected that were selected before
+(except of course the ones it throws away).
+This allows you to easily throw away objects as soon as you no longer need them:
+{;
+ sound = Create Sound as pure tone: “sine377”,
+ ... 1, 0, 1, 44100, 377, 0.2, 0.01, 0.01 ; remember the ID of the Sound
+ Play ; the Sound is selected, so it plays
+ spectrum = To Spectrum: “yes”
+ \#`{removeObject}: sound ; we no longer need the Sound, so we remove it
+ Draw: 0, 5000, 20, 80, “yes” ; the Spectrum is still selected, so it is drawn
+ \#`{removeObject}: spectrum ; remove the last object created by the script
+}
+Selecting and removing all objects from the list (don’t)
+========================================================
+A very strange command, which you should not normally use, is `select all`:
+{;
+ \#{select all}
+ Remove
+}
+This selects all objects in the list and then removes them.
+Please try not to use this, because it will remove even the objects that your script did not create!
+After all, you don’t want the users of your script to lose the objects they created!
+So please try to remove in your script only the objects that your script created,
+even if the script is for your own use (because if it is a nice script, others will want to use it).
+
+################################################################################
+"Scripting 4.3. Querying objects"
+© Paul Boersma 1999,2004,2006–2008,2011,2013,2014,2018,2023
+
+You can get the name of a selected object into a string variable.
+For instance, the following reads the name of the second selected Sound
+(as counted from the top of the list of objects) into the variable %`name$`:
+{;
+ name$ = \#`{selected$} (“Sound”, 2)
+}
+If the Sound was called “Sound hallo”, the variable %`name$` will contain the string “hallo”.
+To get the name of the topmost selected Sound object, you can leave out the number:
+{;
+ name$ = selected$ (“Sound”)
+}
+To get the full name (type + name) of the third selected object, you do:
+{;
+ fullName$ = selected$ (3)
+}
+To get the full name of the topmost selected object, you do:
+{;
+ fullName$ = selected$ ()
+}
+To get the type and name out of the full name, you do:
+{;
+ type$ = \`{extractWord$} (fullName$, “”)
+ name$ = \`{extractLine$} (fullName$, “ ”)
+}
+Negative numbers count from the bottom. Thus, to get the name of the bottom-most selected Sound
+object, you say
+{;
+ name$ = selected$ (“Sound”, -1)
+}
+You would use `selected$` () for drawing the object name in a picture:
+{;
+ Draw: 0, 0, 0, 0, “yes”
+ name$ = selected$ (“Sound”)
+ Text top: “no”, “This is sound ” + name$
+}
+For identifying previously selected objects, this method is not very suitable, since
+there may be multiple objects with the same name:
+{;
+ # The following two lines are OK:
+ soundName$ = selected$ (“Sound”, -1)
+ pitchName$ = selected$ (“Pitch”)
+ # But the following line is questionable, since it doesn’t
+ # necessarily select the previously selected Pitch again:
+ selectObject: “Pitch ” + pitchName$
+}
+Instead of this error-prone approach, you should get the object’s unique ID.
+The correct version of our example becomes:
+{;
+ sound = selected (“Sound”, -1)
+ pitch = selected (“Pitch”)
+ # Correct:
+ selectObject: pitch
+}
+To get the number of selected Sound objects into a variable, use
+{;
+ numberOfSelectedSounds = numberOfSelected (“Sound”)
+}
+To get the number of selected objects into a variable, use
+{;
+ numberOfSelectedObjects = numberOfSelected ()
+}
+Example: doing something to every selected Sound
+================================================
+{;
+ sounds# = \#`{selected#} (“Sound”)
+ # Median pitches of all selected sounds:
+ for i to size (sounds#)
+ selectObject: sounds# [i]
+ To Pitch (filtered ac): 0.0, 50, 800, 15, “no”, 0.03, 0.09, 0.50, 0.055, 0.35, 0.14
+ f0 = Get quantile: 0, 0, 0.50, “Hertz”
+ appendInfoLine: f0
+ Remove
+ endfor
+ # Restore selection:
+ selectObject (sounds#)
+}
+
+################################################################################
+)~~~"
+MAN_PAGES_END
MAN_BEGIN (U"Scripting 5. Language elements reference", U"ppgb", 20170718)
NORMAL (U"In a Praat script, you can use variables, expressions, and functions, of numeric as well as string type, "
=====================================
fon/manual_whatsnew.cpp
=====================================
@@ -29,6 +29,19 @@ R"~~~(
Latest changes in Praat.
+##6.4.01# (30 November 2023)
+• Removed some visible percent signs before variable names from the scripting tutorial.
+• SoundEditor/TextGridEditor logging: when logging 'f0',
+ Praat now correctly reports values in Hz (rather than logarithms)
+ if Unit is set to “Hertz (logarithmic)”.
+ This bug had existed since Praat version 4.3.16 (June 2005).
+• SoundEditor/TextGridEditor scripting compatibility: made old versions of “Pitch settings...”
+ and “Advanced pitch settings...” available to scripts again, made the old denominations
+ “autocorrelation” and “cross-correlation” (as pitch analysis methods) available to scripts again,
+ and made obsolete versions of pitch analysis settings (such as “Pitch silence threshold”)
+ available again, now under the COMPATIBILITY section of the output of “Editor info”.
+ This will allow older editor scripts to continue to run without change.
+
##6.4# (15 November 2023)
• New pitch analysis methods: @@Sound: To Pitch (filtered ac)...@ and
@@Sound: To Pitch (filtered cc)... at .
=====================================
fon/praat_Sound.cpp
=====================================
@@ -1607,12 +1607,12 @@ DO
}
FORM (CONVERT_EACH_TO_ONE__Sound_to_Pitch_ac, U"Sound: To Pitch (ac)", U"Sound: To Pitch (ac)...") {
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
REAL (timeStep, U"Time step (s)", U"0.0 (= auto)")
POSITIVE (pitchFloor, U"Pitch floor (Hz)", U"75.0")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", U"15")
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", U"0.03")
REAL (voicingThreshold, U"Voicing threshold", U"0.45")
REAL (octaveCost, U"Octave cost", U"0.01")
@@ -1632,12 +1632,12 @@ DO
CONVERT_EACH_TO_ONE_END (my name.get())
}
FORM (CONVERT_EACH_TO_ONE__Sound_to_Pitch_cc, U"Sound: To Pitch (cc)", U"Sound: To Pitch (cc)...") {
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
REAL (timeStep, U"Time step (s)", U"0.0 (= auto)")
POSITIVE (pitchFloor, U"Pitch floor (Hz)", U"75.0")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", U"15")
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", U"0.03")
REAL (voicingThreshold, U"Voicing threshold", U"0.45")
REAL (octaveCost, U"Octave cost", U"0.01")
@@ -1658,13 +1658,13 @@ DO
}
FORM (CONVERT_EACH_TO_ONE__Sound_to_Pitch_rawAc, U"Sound: To Pitch (raw ac)", U"Sound: To Pitch (raw ac)...") {
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
REAL (timeStep, U"Time step (s)", U"0.0 (= auto)")
POSITIVE (pitchFloor, U"Pitch floor (Hz)", U"75.0")
POSITIVE (pitchCeiling, U"Pitch ceiling (Hz)", U"600.0")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", U"15")
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", U"0.03")
REAL (voicingThreshold, U"Voicing threshold", U"0.45")
REAL (octaveCost, U"Octave cost", U"0.01")
@@ -1684,13 +1684,13 @@ DO
}
FORM (CONVERT_EACH_TO_ONE__Sound_to_Pitch_rawCc, U"Sound: To Pitch (raw cc)", U"Sound: To Pitch (raw cc)...") {
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
REAL (timeStep, U"Time step (s)", U"0.0 (= auto)")
POSITIVE (pitchFloor, U"Pitch floor (Hz)", U"75.0")
POSITIVE (pitchCeiling, U"Pitch ceiling (Hz)", U"600.0")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", U"15")
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", U"0.03")
REAL (voicingThreshold, U"Voicing threshold", U"0.45")
REAL (octaveCost, U"Octave cost", U"0.01")
@@ -1710,15 +1710,15 @@ DO
}
FORM (CONVERT_EACH_TO_ONE__Sound_to_Pitch_filteredAc, U"Sound: To Pitch (filtered ac)", U"Sound: To Pitch (filtered ac)...") {
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
REAL (timeStep, U"Time step (s)", U"0.0 (= auto)")
POSITIVE (pitchFloor, U"Pitch floor (Hz)", U"50.0")
POSITIVE (pitchCeiling, U"Pitch ceiling (Hz)", U"800.0")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", U"15")
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Preprocessing")
+ LABEL (U"Preprocessing...")
POSITIVE (attenuationAtCeiling, U"Attenuation at ceiling", U"0.03")
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", U"0.09")
REAL (voicingThreshold, U"Voicing threshold", U"0.50")
REAL (octaveCost, U"Octave cost", U"0.055")
@@ -1738,15 +1738,15 @@ DO
}
FORM (CONVERT_EACH_TO_ONE__Sound_to_Pitch_filteredCc, U"Sound: To Pitch (filtered cc)", U"Sound: To Pitch (filtered cc)...") {
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
REAL (timeStep, U"Time step (s)", U"0.0 (= auto)")
POSITIVE (pitchFloor, U"Pitch floor (Hz)", U"50.0")
POSITIVE (pitchCeiling, U"Pitch ceiling (Hz)", U"800.0")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", U"15")
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Preprocessing")
+ LABEL (U"Preprocessing...")
POSITIVE (attenuationAtCeiling, U"Attenuation at ceiling", U"0.03")
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", U"0.09")
REAL (voicingThreshold, U"Voicing threshold", U"0.50")
REAL (octaveCost, U"Octave cost", U"0.055")
=====================================
foned/SoundAnalysisArea.cpp
=====================================
@@ -482,6 +482,17 @@ void structSoundAnalysisArea :: v1_info () {
MelderInfo_writeLine (U"Log 2 format: ", our instancePref_log2_format());
MelderInfo_writeLine (U"Log 3 script: ", our instancePref_logScript3());
MelderInfo_writeLine (U"Log 4 script: ", our instancePref_logScript4());
+ /*
+ COMPATIBILITY < 6400
+ */
+ MelderInfo_writeLine (U"\nCOMPATIBILITY (obsolete settings for the benefit of old scripts):");
+ MelderInfo_writeLine (U"Pitch max. number of candidates: ", our instancePref_pitch_rawAcCc_maximumNumberOfCandidates());
+ MelderInfo_writeLine (U"Pitch very accurate: ", our instancePref_pitch_rawAcCc_veryAccurate());
+ MelderInfo_writeLine (U"Pitch silence threshold: ", our instancePref_pitch_rawAcCc_silenceThreshold(), U" of global peak");
+ MelderInfo_writeLine (U"Pitch voicing threshold: ", our instancePref_pitch_rawAcCc_voicingThreshold(), U" (periodic power / total power)");
+ MelderInfo_writeLine (U"Pitch octave cost: ", our instancePref_pitch_rawAcCc_octaveCost(), U" per octave");
+ MelderInfo_writeLine (U"Pitch octave jump cost: ", our instancePref_pitch_rawAcCc_octaveJumpCost(), U" per octave");
+ MelderInfo_writeLine (U"Pitch voiced/unvoiced cost: ", our instancePref_pitch_rawAcCc_voicedUnvoicedCost());
}
@@ -691,6 +702,7 @@ static void do_log (SoundAnalysisArea me, int which) {
value = Pitch_getValueAtTime (my d_pitch.get(), tmin, my instancePref_pitch_unit(), 1);
else
value = Pitch_getMean (my d_pitch.get(), tmin, tmax, my instancePref_pitch_unit());
+ value = Function_convertToNonlogarithmic (my d_pitch.get(), value, Pitch_LEVEL_FREQUENCY, (int) my instancePref_pitch_unit());
} else if (varName [0] == U'f' && varName [1] >= U'1' && varName [1] <= U'5' && varName [2] == U'\0') {
SoundAnalysisArea_haveVisibleFormants (me);
if (part == SoundAnalysisArea_PART_CURSOR)
@@ -962,6 +974,33 @@ static void menu_cb_showPitch (SoundAnalysisArea me, EDITOR_ARGS) {
VOID_EDITOR_END
}
+static void menu_cb_pitchSettings_BEFORE_6400 (SoundAnalysisArea me, EDITOR_ARGS) {
+ EDITOR_FORM (U"Pitch settings", U"Intro 4.2. Configuring the pitch contour")
+ LABEL (U"YOU SHOULD NEVER SEE THIS OBSOLETE SETTINGS WINDOW;")
+ LABEL (U"IT IS HERE ONLY FOR COMPATIBILITY WITH OLD SCRIPTS.")
+ POSITIVE (pitchFloor, U"left Pitch range (Hz)", my default_pitch_floor())
+ POSITIVE (pitchCeiling, U"right Pitch range (Hz)", my default_pitch_ceiling())
+ OPTIONMENU_ENUM (kPitch_unit, unit, U"Unit", my default_pitch_unit ())
+ CHOICE_ENUM (kSoundAnalysisArea_pitch_analysisMethod, analysisMethod, U"Analysis method", my default_pitch_method())
+ OPTIONMENU_ENUM (kSoundAnalysisArea_pitch_drawingMethod, drawingMethod, U"Drawing method", my default_pitch_drawingMethod())
+ EDITOR_OK
+ EDITOR_DO
+ Melder_require (pitchCeiling > pitchFloor,
+ U"The pitch ceiling has to be greater than the pitch floor, so they cannot be ",
+ pitchCeiling, U" and ", pitchFloor, U" ", kPitch_unit_getText (unit), U", respectively."
+ );
+ my setInstancePref_pitch_floor (pitchFloor);
+ my setInstancePref_pitch_ceiling (pitchCeiling);
+ my setInstancePref_pitch_unit (unit);
+ my setInstancePref_pitch_method (analysisMethod);
+ my setInstancePref_pitch_drawingMethod (drawingMethod);
+ my d_pitch. reset();
+ my d_intensity. reset();
+ my d_pulses. reset();
+ FunctionEditor_redraw (my functionEditor());
+ EDITOR_END
+}
+
static void menu_cb_pitchSettings (SoundAnalysisArea me, EDITOR_ARGS) {
EDITOR_FORM (U"Pitch settings", U"Intro 4.2. Configuring the pitch contour")
POSITIVE (pitchFloor, U"left Pitch range (Hz)", my default_pitch_floor())
@@ -1015,7 +1054,7 @@ static void menu_cb_pitchSettings (SoundAnalysisArea me, EDITOR_ARGS) {
} else {
SET_STRING (note2, U"(your “time step strategy” has its standard value: automatic)")
}
- EDITOR_DO
+ EDITOR_DO_ALTERNATIVE (menu_cb_pitchSettings_BEFORE_6400)
Melder_require (pitchCeiling > pitchFloor,
U"The pitch ceiling has to be greater than the pitch floor, so they cannot be ",
pitchCeiling, U" and ", pitchFloor, U" ", kPitch_unit_getText (unit), U", respectively."
@@ -1034,14 +1073,56 @@ static void menu_cb_pitchSettings (SoundAnalysisArea me, EDITOR_ARGS) {
EDITOR_END
}
+static void menu_cb_advancedPitchSettings (SoundAnalysisArea me, EDITOR_ARGS) { // COMPATIBILITY < 6400
+ EDITOR_FORM (U"Advanced pitch settings", U"Advanced pitch settings...")
+ LABEL (U"YOU SHOULD NEVER SEE THIS OBSOLETE SETTINGS WINDOW;")
+ LABEL (U"IT IS HERE ONLY FOR COMPATIBILITY WITH OLD SCRIPTS.")
+ REAL (viewFrom, U"left View range (units)", my default_pitch_viewFrom ())
+ REAL (viewTo, U"right View range (units)", my default_pitch_viewTo ())
+ BOOLEAN (veryAccurate, U"Very accurate", false)
+ NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", my default_pitch_rawAcCc_maximumNumberOfCandidates ())
+ REAL (silenceThreshold, U"Silence threshold", my default_pitch_rawAcCc_silenceThreshold ())
+ REAL (voicingThreshold, U"Voicing threshold", my default_pitch_rawAcCc_voicingThreshold ())
+ REAL (octaveCost, U"Octave cost", my default_pitch_rawAcCc_octaveCost ())
+ REAL (octaveJumpCost, U"Octave-jump cost", my default_pitch_rawAcCc_octaveJumpCost ())
+ REAL (voicedUnvoicedCost, U"Voiced / unvoiced cost", my default_pitch_rawAcCc_voicedUnvoicedCost ())
+ EDITOR_OK
+ SET_REAL (viewFrom, my instancePref_pitch_viewFrom())
+ SET_REAL (viewTo, my instancePref_pitch_viewTo())
+ SET_BOOLEAN (veryAccurate, my instancePref_pitch_rawAcCc_veryAccurate())
+ SET_INTEGER (maximumNumberOfCandidates, my instancePref_pitch_rawAcCc_maximumNumberOfCandidates())
+ SET_REAL (silenceThreshold, my instancePref_pitch_rawAcCc_silenceThreshold())
+ SET_REAL (voicingThreshold, my instancePref_pitch_rawAcCc_voicingThreshold())
+ SET_REAL (octaveCost, my instancePref_pitch_rawAcCc_octaveCost())
+ SET_REAL (octaveJumpCost, my instancePref_pitch_rawAcCc_octaveJumpCost())
+ SET_REAL (voicedUnvoicedCost, my instancePref_pitch_rawAcCc_voicedUnvoicedCost())
+ EDITOR_DO
+ if (maximumNumberOfCandidates < 2)
+ Melder_throw (U"Your maximum number of candidates should be greater than 1.");
+ my setInstancePref_pitch_viewFrom (viewFrom);
+ my setInstancePref_pitch_viewTo (viewTo);
+ my setInstancePref_pitch_rawAcCc_veryAccurate (veryAccurate);
+ my setInstancePref_pitch_rawAcCc_maximumNumberOfCandidates (maximumNumberOfCandidates);
+ my setInstancePref_pitch_rawAcCc_silenceThreshold (silenceThreshold);
+ my setInstancePref_pitch_rawAcCc_voicingThreshold (voicingThreshold);
+ my setInstancePref_pitch_rawAcCc_octaveCost (octaveCost);
+ my setInstancePref_pitch_rawAcCc_octaveJumpCost (octaveJumpCost);
+ my setInstancePref_pitch_rawAcCc_voicedUnvoicedCost (voicedUnvoicedCost);
+ my d_pitch. reset();
+ my d_intensity. reset();
+ my d_pulses. reset();
+ FunctionEditor_redraw (my functionEditor());
+ EDITOR_END
+}
+
static void menu_cb_advancedPitchSettings_rawAcCc (SoundAnalysisArea me, EDITOR_ARGS) {
EDITOR_FORM (U"Advanced pitch settings (raw AC and CC)", U"Advanced pitch settings (raw AC and CC)...")
LABEL (U"Settings for the RAW autocorrelation and cross-correlation methods only.")
LABEL (U"")
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", my default_pitch_rawAcCc_maximumNumberOfCandidates ())
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", my default_pitch_rawAcCc_silenceThreshold ())
REAL (voicingThreshold, U"Voicing threshold", my default_pitch_rawAcCc_voicingThreshold ())
REAL (octaveCost, U"Octave cost", my default_pitch_rawAcCc_octaveCost ())
@@ -1076,12 +1157,12 @@ static void menu_cb_advancedPitchSettings_filteredAcCc (SoundAnalysisArea me, ED
EDITOR_FORM (U"Advanced pitch settings (filtered AC and CC)", U"Advanced pitch settings (filtered AC and CC)...")
LABEL (U"Settings for the FILTERED autocorrelation and cross-correlation methods only.")
LABEL (U"")
- LABEL (U"Finding the candidates")
+ LABEL (U"Finding the candidates...")
NATURAL (maximumNumberOfCandidates, U"Max. number of candidates", my default_pitch_filteredAcCc_maximumNumberOfCandidates ())
BOOLEAN (veryAccurate, U"Very accurate", false)
- LABEL (U"Preprocessing")
+ LABEL (U"Preprocessing...")
POSITIVE (attenuationAtCeiling, U"Attenuation at ceiling", my default_pitch_filteredAcCc_attenuationAtCeiling ())
- LABEL (U"Finding a path")
+ LABEL (U"Finding a path...")
REAL (silenceThreshold, U"Silence threshold", my default_pitch_filteredAcCc_silenceThreshold ())
REAL (voicingThreshold, U"Voicing threshold", my default_pitch_filteredAcCc_voicingThreshold ())
REAL (octaveCost, U"Octave cost", my default_pitch_filteredAcCc_octaveCost ())
@@ -1827,6 +1908,8 @@ void structSoundAnalysisArea :: v_createMenus () {
);
FunctionAreaMenu_addCommand (menu, U"Pitch settings...", 0,
menu_cb_pitchSettings, this);
+ FunctionAreaMenu_addCommand (menu, U"Advanced pitch settings...", GuiMenu_HIDDEN,
+ menu_cb_advancedPitchSettings, this);
FunctionAreaMenu_addCommand (menu, U"Advanced pitch settings (filtered AC and CC)...", 0,
menu_cb_advancedPitchSettings_filteredAcCc, this);
FunctionAreaMenu_addCommand (menu, U"Advanced pitch settings (raw AC and CC)...", 0,
=====================================
foned/SoundAnalysisArea_enums.h
=====================================
@@ -32,7 +32,9 @@ enums_end (kSoundAnalysisArea_pitch_drawingMethod, 3, AUTOMATIC)
enums_begin (kSoundAnalysisArea_pitch_analysisMethod, 1)
enums_add (kSoundAnalysisArea_pitch_analysisMethod, 1, FILTERED_AUTOCORRELATION, U"filtered autocorrelation")
enums_add (kSoundAnalysisArea_pitch_analysisMethod, 2, RAW_CROSS_CORRELATION, U"raw cross-correlation")
+ enums_alt (kSoundAnalysisArea_pitch_analysisMethod, RAW_CROSS_CORRELATION, U"cross-correlation") // COMPATIBILITY < 6400
enums_add (kSoundAnalysisArea_pitch_analysisMethod, 3, RAW_AUTOCORRELATION, U"raw autocorrelation")
+ enums_alt (kSoundAnalysisArea_pitch_analysisMethod, RAW_AUTOCORRELATION, U"autocorrelation") // COMPATIBILITY < 6400
enums_add (kSoundAnalysisArea_pitch_analysisMethod, 4, FILTERED_CROSS_CORRELATION, U"filtered cross-correlation")
enums_end (kSoundAnalysisArea_pitch_analysisMethod, 4, FILTERED_AUTOCORRELATION)
=====================================
sys/EditorM.h
=====================================
@@ -46,6 +46,37 @@ _form_inited_: \
UiForm_parseStringE (cmd, _narg_, _args_, _sendingString_, optionalInterpreter); \
} else {
+#define EDITOR_DO_ALTERNATIVE(alternative) \
+ UiForm_do (cmd -> d_uiform.get(), false); \
+ } else if (! _sendingForm_) { \
+ try { \
+ UiForm_parseStringE (cmd, _narg_, _args_, _sendingString_, optionalInterpreter); \
+ } catch (MelderError) { \
+ if (Melder_hasCrash ()) \
+ throw; \
+ autostring32 _parkedError = Melder_dup_f (Melder_getError ()); \
+ Melder_clearError (); \
+ try { \
+ static autoEditorCommand _alternativeCmd; \
+ if (! _alternativeCmd) \
+ _alternativeCmd = Thing_new (EditorCommand); \
+ _alternativeCmd -> d_editor = cmd -> d_editor; \
+ _alternativeCmd -> sender = cmd -> sender; \
+ _alternativeCmd -> menu = cmd -> menu; \
+ _alternativeCmd -> itemTitle = Melder_dup (cmd -> itemTitle.get()); \
+ _alternativeCmd -> itemWidget = nullptr; \
+ _alternativeCmd -> commandCallback = cmd -> commandCallback; \
+ _alternativeCmd -> script = Melder_dup (cmd -> script.get()); \
+ _alternativeCmd -> d_uiform = autoUiForm (); \
+ alternative (me, _alternativeCmd.get(), _sendingForm_, _narg_, _args_, _sendingString_, optionalInterpreter); \
+ } catch (MelderError) { \
+ Melder_clearError (); \
+ Melder_appendError (_parkedError.get()); \
+ throw; \
+ } \
+ } \
+ } else {
+
#define EDITOR_END \
}
@@ -301,8 +332,10 @@ _form_inited_: \
[[maybe_unused]] enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
_compilerTypeCheckDummy = enumeratedVariable; \
} \
- UiForm_addChoice (cmd -> d_uiform.get(), (int *) & enumeratedVariable, nullptr, nullptr, labelText, \
- (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
+ UiForm_addChoiceEnum (cmd -> d_uiform.get(), (int *) & enumeratedVariable, nullptr, nullptr, labelText, \
+ (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN, \
+ (enum_generic_getValue) EnumeratedType##_getValue \
+ ); \
for (int _ienum = (int) EnumeratedType::MIN; _ienum <= (int) EnumeratedType::MAX; _ienum ++) \
UiForm_addOption (cmd -> d_uiform.get(), EnumeratedType##_getText ((enum EnumeratedType) _ienum)); \
@@ -319,8 +352,10 @@ _form_inited_: \
[[maybe_unused]] enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
_compilerTypeCheckDummy = enumeratedVariable; \
} \
- UiForm_addOptionMenu (cmd -> d_uiform.get(), (int *) & enumeratedVariable, nullptr, nullptr, labelText, \
- (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
+ UiForm_addOptionMenuEnum (cmd -> d_uiform.get(), (int *) & enumeratedVariable, nullptr, nullptr, labelText, \
+ (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN, \
+ (enum_generic_getValue) EnumeratedType##_getValue \
+ ); \
for (int _ienum = (int) EnumeratedType::MIN; _ienum <= (int) EnumeratedType::MAX; _ienum ++) \
UiForm_addOption (cmd -> d_uiform.get(), EnumeratedType##_getText ((enum EnumeratedType) _ienum)); \
=====================================
sys/Ui.cpp
=====================================
@@ -934,7 +934,9 @@ static UiField UiForm_addField (UiForm me, _kUiField_type type, conststring32 la
return my field [my numberOfFields].get();
}
-UiField UiForm_addReal (UiForm me, double *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addReal (UiForm me, double *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::REAL_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -943,7 +945,9 @@ UiField UiForm_addReal (UiForm me, double *variable, conststring32 variableName,
return thee;
}
-UiField UiForm_addRealOrUndefined (UiForm me, double *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addRealOrUndefined (UiForm me, double *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::REAL_OR_UNDEFINED_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -952,7 +956,9 @@ UiField UiForm_addRealOrUndefined (UiForm me, double *variable, conststring32 va
return thee;
}
-UiField UiForm_addPositive (UiForm me, double *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addPositive (UiForm me, double *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::POSITIVE_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -961,7 +967,9 @@ UiField UiForm_addPositive (UiForm me, double *variable, conststring32 variableN
return thee;
}
-UiField UiForm_addInteger (UiForm me, integer *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addInteger (UiForm me, integer *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::INTEGER_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -970,7 +978,9 @@ UiField UiForm_addInteger (UiForm me, integer *variable, conststring32 variableN
return thee;
}
-UiField UiForm_addNatural (UiForm me, integer *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addNatural (UiForm me, integer *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::NATURAL_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -979,7 +989,9 @@ UiField UiForm_addNatural (UiForm me, integer *variable, conststring32 variableN
return thee;
}
-UiField UiForm_addWord (UiForm me, conststring32 *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addWord (UiForm me, conststring32 *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::WORD_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -988,7 +1000,9 @@ UiField UiForm_addWord (UiForm me, conststring32 *variable, conststring32 variab
return thee;
}
-UiField UiForm_addSentence (UiForm me, conststring32 *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addSentence (UiForm me, conststring32 *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::SENTENCE_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -1005,7 +1019,9 @@ UiField UiForm_addLabel (UiForm me, conststring32 *variable, conststring32 label
return thee;
}
-UiField UiForm_addBoolean (UiForm me, bool *variable, conststring32 variableName, conststring32 labelText, bool defaultValue) {
+UiField UiForm_addBoolean (UiForm me, bool *variable, conststring32 variableName,
+ conststring32 labelText, bool defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::BOOLEAN_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy integerDefaultValue = defaultValue;
@@ -1151,7 +1167,22 @@ UiField UiForm_addStringArray (UiForm me, constSTRVEC *variable, conststring32 v
return thee;
}
-UiField UiForm_addChoice (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName, conststring32 labelText, int defaultValue, int base) {
+UiField UiForm_addChoice (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, int defaultValue, int base)
+{
+ UiField thee = UiForm_addField (me, _kUiField_type::CHOICE_, labelText);
+ my referenceToLatestUsedChoiceOrOptionMenu = thee;
+ thy integerDefaultValue = defaultValue;
+ thy intVariable = intVariable;
+ thy stringVariable = stringVariable;
+ thy variableName = variableName;
+ thy subtract = ( base == 1 ? 0 : 1 );
+ return thee;
+}
+
+UiField UiForm_addChoiceEnum (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, int defaultValue, int base, enum_generic_getValue getValueFunction)
+{
UiField thee = UiForm_addField (me, _kUiField_type::CHOICE_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = thee;
thy integerDefaultValue = defaultValue;
@@ -1159,10 +1190,13 @@ UiField UiForm_addChoice (UiForm me, int *intVariable, conststring32 *stringVari
thy stringVariable = stringVariable;
thy variableName = variableName;
thy subtract = ( base == 1 ? 0 : 1 );
+ thy getValueFunction = getValueFunction;
return thee;
}
-UiField UiForm_addOptionMenu (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName, conststring32 labelText, int defaultValue, int base) {
+UiField UiForm_addOptionMenu (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, int defaultValue, int base)
+{
UiField thee = UiForm_addField (me, _kUiField_type::OPTIONMENU_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = thee;
thy integerDefaultValue = defaultValue;
@@ -1173,7 +1207,23 @@ UiField UiForm_addOptionMenu (UiForm me, int *intVariable, conststring32 *string
return thee;
}
-UiField UiForm_addList (UiForm me, integer *integerVariable, conststring32 *stringVariable, conststring32 variableName, conststring32 labelText, constSTRVEC strings, integer defaultValue) {
+UiField UiForm_addOptionMenuEnum (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, int defaultValue, int base, enum_generic_getValue getValueFunction)
+{
+ UiField thee = UiForm_addField (me, _kUiField_type::OPTIONMENU_, labelText);
+ my referenceToLatestUsedChoiceOrOptionMenu = thee;
+ thy integerDefaultValue = defaultValue;
+ thy intVariable = intVariable;
+ thy stringVariable = stringVariable;
+ thy variableName = variableName;
+ thy subtract = ( base == 1 ? 0 : 1 );
+ thy getValueFunction = getValueFunction;
+ return thee;
+}
+
+UiField UiForm_addList (UiForm me, integer *integerVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, constSTRVEC strings, integer defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::LIST_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy strings = strings;
@@ -1184,7 +1234,9 @@ UiField UiForm_addList (UiForm me, integer *integerVariable, conststring32 *stri
return thee;
}
-UiField UiForm_addColour (UiForm me, MelderColour *colourVariable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addColour (UiForm me, MelderColour *colourVariable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::COLOUR_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -1193,7 +1245,9 @@ UiField UiForm_addColour (UiForm me, MelderColour *colourVariable, conststring32
return thee;
}
-UiField UiForm_addChannel (UiForm me, integer *variable, conststring32 variableName, conststring32 labelText, conststring32 defaultValue) {
+UiField UiForm_addChannel (UiForm me, integer *variable, conststring32 variableName,
+ conststring32 labelText, conststring32 defaultValue)
+{
UiField thee = UiForm_addField (me, _kUiField_type::CHANNEL_, labelText);
my referenceToLatestUsedChoiceOrOptionMenu = nullptr;
thy stringDefaultValue = Melder_dup (defaultValue);
@@ -2034,21 +2088,25 @@ static void UiField_argToValue (UiField me, Stackel arg, Interpreter /* interpre
{
if (arg -> which != Stackel_STRING)
Melder_throw (U"Option argument “", my name.get(), U"” should be a string, not ", arg -> whichText(), U".");
- my integerValue = 0;
- for (int i = 1; i <= my options.size; i ++) {
- UiOption b = my options.at [i];
- if (str32equ (arg -> getString(), b -> name.get()))
- my integerValue = i;
- }
- if (my integerValue == 0) {
- /*
- Retry with different case.
- */
+ if (my getValueFunction) {
+ my integerValue = my getValueFunction (arg -> getString()) + my subtract;
+ } else {
+ my integerValue = 0;
for (int i = 1; i <= my options.size; i ++) {
UiOption b = my options.at [i];
- if (Melder_equ_firstCharacterCaseInsensitive (arg -> getString(), b -> name.get()))
+ if (str32equ (arg -> getString(), b -> name.get()))
my integerValue = i;
}
+ if (my integerValue == 0) {
+ /*
+ Retry with different case.
+ */
+ for (int i = 1; i <= my options.size; i ++) {
+ UiOption b = my options.at [i];
+ if (Melder_equ_firstCharacterCaseInsensitive (arg -> getString(), b -> name.get()))
+ my integerValue = i;
+ }
+ }
}
if (my integerValue == 0) {
if (my intVariable)
@@ -2229,21 +2287,25 @@ static void UiField_stringToValue (UiField me, conststring32 string, Interpreter
case _kUiField_type::CHOICE_:
case _kUiField_type::OPTIONMENU_:
{
- my integerValue = 0;
- for (int i = 1; i <= my options.size; i ++) {
- UiOption b = my options.at [i];
- if (str32equ (string, b -> name.get()))
- my integerValue = i;
- }
- if (my integerValue == 0) {
- /*
- Retry with different case.
- */
+ if (my getValueFunction) {
+ my integerValue = my getValueFunction (string) + my subtract;
+ } else {
+ my integerValue = 0;
for (int i = 1; i <= my options.size; i ++) {
UiOption b = my options.at [i];
- if (Melder_equ_firstCharacterCaseInsensitive (string, b -> name.get()))
+ if (str32equ (string, b -> name.get()))
my integerValue = i;
}
+ if (my integerValue == 0) {
+ /*
+ Retry with different case.
+ */
+ for (int i = 1; i <= my options.size; i ++) {
+ UiOption b = my options.at [i];
+ if (Melder_equ_firstCharacterCaseInsensitive (string, b -> name.get()))
+ my integerValue = i;
+ }
+ }
}
if (my integerValue == 0)
Melder_throw (U"Field “", my name.get(), U"” must not have the value “", string, U"”.");
=====================================
sys/Ui.h
=====================================
@@ -134,6 +134,7 @@ Thing_define (UiField, Thing) {
GuiRadioButton radioButton; // for CHOICE_
GuiList list;
GuiOptionMenu optionMenu;
+ enum_generic_getValue getValueFunction;
GuiButton pushButton; // like "Browse..." for INFILE_, OUTFILE_, FOLDER_ (2021-03-30)
int y;
@@ -244,8 +245,12 @@ UiField UiForm_addStringArray (UiForm me, constSTRVEC *variable, conststring32 v
conststring32 labelText, constSTRVEC defaultValue, integer numberOfLines = 7);
UiField UiForm_addChoice (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
conststring32 labelText, int defaultValue, int base);
+UiField UiForm_addChoiceEnum (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, int defaultValue, int base, enum_generic_getValue getValueFunction);
UiField UiForm_addOptionMenu (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
conststring32 labelText, int defaultValue, int base);
+UiField UiForm_addOptionMenuEnum (UiForm me, int *intVariable, conststring32 *stringVariable, conststring32 variableName,
+ conststring32 labelText, int defaultValue, int base, enum_generic_getValue getValueFunction);
UiOption UiForm_addOption (UiForm me, conststring32 optionText);
UiField UiForm_addList (UiForm me, integer *integerVariable, conststring32 *stringVariable, conststring32 variableName,
conststring32 labelText, constSTRVEC strings, integer defaultValue);
=====================================
sys/praatM.h
=====================================
@@ -225,8 +225,10 @@
[[maybe_unused]] enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
_compilerTypeCheckDummy = enumeratedVariable; \
} \
- UiForm_addChoice (_dia_.get(), (int *) & enumeratedVariable, nullptr, U"" #enumeratedVariable, \
- labelText, (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
+ UiForm_addChoiceEnum (_dia_.get(), (int *) & enumeratedVariable, nullptr, U"" #enumeratedVariable, \
+ labelText, (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN, \
+ (enum_generic_getValue) EnumeratedType##_getValue \
+ ); \
for (int ienum = (int) EnumeratedType::MIN; ienum <= (int) EnumeratedType::MAX; ienum ++) \
UiForm_addOption (_dia_.get(), EnumeratedType##_getText ((enum EnumeratedType) ienum));
@@ -236,8 +238,10 @@
[[maybe_unused]] enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
_compilerTypeCheckDummy = enumeratedVariable; \
} \
- UiForm_addOptionMenu (_dia_.get(), (int *) & enumeratedVariable, nullptr, U"" #enumeratedVariable, \
- labelText, (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
+ UiForm_addOptionMenuEnum (_dia_.get(), (int *) & enumeratedVariable, nullptr, U"" #enumeratedVariable, \
+ labelText, (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN, \
+ (enum_generic_getValue) EnumeratedType##_getValue \
+ ); \
for (int ienum = (int) EnumeratedType::MIN; ienum <= (int) EnumeratedType::MAX; ienum ++) \
UiForm_addOption (_dia_.get(), EnumeratedType##_getText ((enum EnumeratedType) ienum));
@@ -247,8 +251,10 @@
[[maybe_unused]] enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
_compilerTypeCheckDummy = enumeratedVariable; \
} \
- UiForm_addOptionMenu (_dia_.get(), nullptr, & enumeratedVariableAsString, U"" #enumeratedVariableAsString, \
- labelText, (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
+ UiForm_addOptionMenuEnum (_dia_.get(), nullptr, & enumeratedVariableAsString, U"" #enumeratedVariableAsString, \
+ labelText, (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN, \
+ (enum_generic_getValue) EnumeratedType##_getValue \
+ ); \
for (int ienum = (int) EnumeratedType::MIN; ienum <= (int) EnumeratedType::MAX; ienum ++) \
UiForm_addOption (_dia_.get(), EnumeratedType##_getText ((enum EnumeratedType) ienum));
=====================================
sys/praat_version.h
=====================================
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.4
+#define PRAAT_VERSION_STR 6.4.01
#define PRAAT_VERSION_NUM 6400
#define PRAAT_YEAR 2023
#define PRAAT_MONTH November
-#define PRAAT_DAY 15
+#define PRAAT_DAY 30
View it on GitLab: https://salsa.debian.org/med-team/praat/-/commit/f4394a63e1c0d6f29b7e47b2c9a6c6f40b92116e
--
View it on GitLab: https://salsa.debian.org/med-team/praat/-/commit/f4394a63e1c0d6f29b7e47b2c9a6c6f40b92116e
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/20231203/6fc3172e/attachment-0001.htm>
More information about the debian-med-commit
mailing list