[med-svn] [Git][med-team/praat][upstream] New upstream version 6.1.50
Rafael Laboissière (@rafael)
gitlab at salsa.debian.org
Sun Jul 4 16:28:28 BST 2021
Rafael Laboissière pushed to branch upstream at Debian Med / praat
Commits:
eb03c933 by Rafael Laboissière at 2021-07-04T06:20:27-03:00
New upstream version 6.1.50
- - - - -
16 changed files:
- dwtest/test_MDS.praat
- dwtools/Configuration.cpp
- dwtools/KlattTable.cpp
- dwtools/Proximity.cpp
- fon/manual_Script.cpp
- fon/manual_soundFiles.cpp
- fon/manual_tutorials.cpp
- sys/Formula.cpp
- sys/Interpreter.cpp
- sys/praat.cpp
- sys/praat_script.cpp
- sys/praat_script.h
- sys/praat_version.h
- + test/dwtools/KlattTable.praat
- + test/fon/Spectrum.praat
- test/script/undefined.praat
Changes:
=====================================
dwtest/test_MDS.praat
=====================================
@@ -1,35 +1,72 @@
# test_MDS.praat
appendInfoLine: "test_MDS.praat"
+
@test_additiveConstant
+
+ at testLetterRExample
+
@testDissimilarityInterface
-# side effect: 6 configurations in the list of objects: configuration[1]...configuration[6]
-# testINDSCAL uses these 6 configurations
- at testINDSCAL
- at testProcrustus
-for i to 6
- removeObject: configuration [i]
-endfor
+ at testDissimilarityToConfiguration: 5
+
+ at testCarrolWishExample
+
+ at testProcrustes
appendInfoLine: "test_MDS.praat OK"
-procedure testProcrustus
- appendInfoLine: tab$, tab$, "Configuration & Configuration"
- for .i from 2 to 6
- selectObject: configuration [1]
- plusObject: configuration [.i]
- .procrustus [1] = To Procrustes: "no"
- plusObject: configuration [.i]
- .ct [.i] = To Configuration
- plusObject: configuration [1]
- .procrustus [2] = To Procrustes... no
- @check_if_identity_transform: .procrustus [2]
- removeObject: .procrustus [1], .procrustus [2]
+procedure testLetterRExample
+ appendInfoLine: tab$, "test Dissimilarity letter R"
+ .dissimilarity = Create letter R example: 0
+ .numberOfRows = Get number of rows
+ .numberOfColumns = Get number of columns
+ assert .numberOfRows = .numberOfColumns
+ assert .numberOfRows = 32
+
+ for .irow to .numberOfRows
+ .rowLabel$ = Get row label: .irow
+ .rowIndex = Get row index: .rowLabel$
+ assert .irow = .rowIndex; '.irow' '.rowIndex'
endfor
- for .i from 2 to 6
- removeObject: .ct [.i]
+ for .icol to .numberOfColumns
+ .columnLabel$ = Get column label: .icol
+ .columnIndex = Get column index: .columnLabel$
+ assert .icol = .columnIndex; '.icol' '.columnIndex'
endfor
+
+ # check some dissimilarity values
+ assert object[.dissimilarity, 1, 1] = 0
+ assert object[.dissimilarity, 1, 2] = 6
+ assert object[.dissimilarity, 1, 3] = 9
+ assert object[.dissimilarity, 12, 10] = 7
+ assert object[.dissimilarity, 22, 13] = 46
+ assert object[.dissimilarity, 32, 27] = 79
+ assert object[.dissimilarity, 32, 31] = 7
+ .norm = Get table norm
+
+ .additiveConstant = Get additive constant
+ assert abs (.additiveConstant -153.74)/ 153.74 < 1e-6
+
+ removeObject: .dissimilarity
+ appendInfoLine: tab$, "test Dissimilarity letter R OK"
+endproc
+
+procedure testProcrustes
+ appendInfoLine: tab$, "Procrustes: Configuration & Configuration"
+ .dissimilarity1 = Create letter R example: 0.4
+ .configuration1 = To Configuration (monotone mds): 2, "Primary approach", 1e-5, 50, 1
+ .dissimilarity2 = Create letter R example: 0.5
+ .configuration2 = To Configuration (monotone mds): 2, "Primary approach", 1e-5, 50, 1
+ selectObject: .configuration1, .configuration2
+ .procrustes1 = To Procrustes: "no"
+ plusObject: .configuration2
+ .ct1 = To Configuration
+ plusObject: .configuration1
+ .procrustes2 = To Procrustes: "no"
+ @check_if_identity_transform: .procrustes2
+ removeObject: .procrustes1, .procrustes2, .ct1,.dissimilarity1, .dissimilarity2, .configuration1, .configuration2
+ appendInfoLine: tab$, "Procrustes: Configuration & Configuration OK"
endproc
procedure check_if_identity_transform: .p
@@ -50,63 +87,101 @@ procedure check_if_identity_transform: .p
endfor
endproc
+procedure testDissimilarityToConfiguration: .numberOfTries
+ appendInfoLine: tab$, "Dissimilarity to Configuration"
+ .mdsToConfigurationCommands$# = {"To Configuration (monotone mds): 2, ""Primary approach"", 1e-5, 2, 1",
+ ... "To Configuration (i-spline mds): 2, 1, 1, 1e-5, 2, 1",
+ ... "To Configuration (interval mds): 2, 1e-5, 2, 1",
+ ... "To Configuration (ratio mds): 2, 1e-5, 2, 1",
+ ... "To Configuration (absolute mds): 2, 1e-5, 2, 1",
+ ... "To Configuration (kruskal): 2, 2, ""Primary approach"", ""Kruskal's stress-1"", 1e-5, 2, 1" }
+
+ .mdsImproveConfigurationCommands$# = {"To Configuration (monotone mds): ""Primary approach"", 1e-5, 50, 1",
+ ... "To Configuration (i-spline mds): 1, 1, 1e-5, 50, 1",
+ ... "To Configuration (interval mds): 1e-5, 50, 1",
+ ... "To Configuration (ratio mds): 1e-5, 50, 1",
+ ... "To Configuration (absolute mds): 1e-5, 50, 1",
+ ... "To Configuration (kruskal): ""Primary approach"", ""Kruskal's stress-1"", 1e-5, 50, 1" }
+
+ .mdsStressQuery$# = { "Get stress (monotone mds): ""Primary approach"", ""Normalized""",
+ ... "Get stress (i-spline mds): 1, 2, ""Normalized""",
+ ... "Get stress (interval mds): ""Normalized""",
+ ... "Get stress (ratio mds): ""Normalized""",
+ ... "Get stress (absolute mds): ""Normalized""",
+ ... "Get stress: ""Primary approach"", ""Kruskal's stress-1"""}
+
+ for .itry to .numberOfTries
+ .noiseStdev = randomUniform (0, 10)
+ .dissimilarity = Create letter R example: .noiseStdev
+ for .icommand to size (.mdsToConfigurationCommands$#)
+ selectObject: .dissimilarity
+ .command$ = .mdsToConfigurationCommands$# [.icommand]
+ .conf = '.command$'
+ selectObject: .conf, .dissimilarity
+ .getStressCommand$ = .mdsStressQuery$# [.icommand]
+ .stressBefore = '.getStressCommand$'
+ .improveCommand$ = .mdsImproveConfigurationCommands$# [.icommand]
+ .confImproved = '.improveCommand$'
+ selectObject: .dissimilarity, .confImproved
+ .stressAfter = '.getStressCommand$'
+ assert .stressAfter <= .stressBefore+1e-5; '.stressAfter' <= '.stressBefore'
+ removeObject: .conf, .confImproved
+ endfor
+ removeObject: .dissimilarity
+ endfor
+ appendInfoLine: tab$, "Dissimilarity to Configuration OK"
+endproc
+
procedure testDissimilarityInterface
appendInfoLine: tab$, "test interface"
appendInfoLine: tab$, tab$, "Query"
.dissimilarity = Create letter R example: 0
.numberOfRows = Get number of rows
.numberOfColumns = Get number of columns
- for .irow to .numberOfRows
- .rowLabel$ = Get row label: .irow
- .rowIndex = Get row index: .rowLabel$
- assert .irow = .rowIndex; '.irow' '.rowIndex'
- endfor
- for .icol to .numberOfColumns
- .columnLabel$ = Get column label: .icol
- .columnIndex = Get column index: .columnLabel$
- assert .icol = .columnIndex; '.icol' '.columnIndex'
- endfor
for .irow to .numberOfRows
for .icol to .numberOfColumns
val = Get value: .irow, .icol
endfor
endfor
- .norm = Get table norm
- .additiveConstant = Get additive constant
appendInfoLine: tab$, tab$, "Modify: skipped"
appendInfoLine: tab$, tab$, "Synthesize: skipped"
appendInfoLine: tab$, tab$, "Extract part"
selectObject: .dissimilarity
- .tmp1 = Extract row ranges: "1 2"
+ .tor1 = Extract row ranges: "1 2"
.numberOfRows1 = Get number of rows
assert .numberOfRows1 == 2; '.numberOfRows1' "= 2"
+
selectObject: .dissimilarity
- .tmp2 = Extract rows where: "1"
+ .tor2 = Extract rows where: "1"
.numberOfRows2 = Get number of rows
.numberOfColumns2 = Get number of columns
assert .numberOfRows2 == .numberOfRows; '.numberOfRows2' "==" '.numberOfRows'
assert .numberOfColumns2 == .numberOfColumns; '.numberOfColumns2' "==" '.numberOfColumns'
+
selectObject: .dissimilarity
- .tmp3 = Extract column ranges: "1 2"
+ .tor3 = Extract column ranges: "1 2"
.numberOfColumns3 = Get number of columns
assert .numberOfColumns3 == 2; '.numberOfColumns3' "= 2"
+
selectObject: .dissimilarity
- .tmp4 = Extract columns where: "1"
+ .tor4 = Extract columns where: "1"
.numberOfRows4 = Get number of rows
.numberOfColumns4 = Get number of columns
assert .numberOfRows4 == .numberOfRows; '.numberOfRows4' "==" '.numberOfRows'
assert .numberOfColumns4 == .numberOfColumns; '.numberOfColumns4' "==" '.numberOfColumns'
- removeObject: .tmp1, .tmp2, .tmp3, .tmp4
+ removeObject: .tor1, .tor2, .tor3, .tor4
+
for .irow to .numberOfRows
selectObject: .dissimilarity
.rowLabel$ = Get row label: .irow
- .tmpi = Extract rows where label: "is equal to", .rowLabel$
+ .tori = Extract rows where label: "is equal to", .rowLabel$
.numberOfRows5 = Get number of rows
assert .numberOfRows5 >= 1
- removeObject: .tmpi
+ removeObject: .tori
endfor
+
for .icol to .numberOfColumns
selectObject: .dissimilarity
.columnLabel$ = Get column label: .icol
@@ -121,6 +196,7 @@ procedure testDissimilarityInterface
.strings1 = Extract row labels as Strings
.numberOfStrings = Get number of strings
assert .numberOfStrings == .numberOfRows
+
selectObject: .dissimilarity
.strings2 = Extract column labels as Strings
.numberOfStrings = Get number of strings
@@ -132,12 +208,14 @@ procedure testDissimilarityInterface
.table = To Table: "col1"
.numberOfColumnsT = Get number of columns
assert .numberOfColumnsT = .numberOfColumns + 1
+
selectObject: .dissimilarity
.matrix = To Matrix
.numberOfRowsM = Get number of rows
.numberOfColumnsM = Get number of columns
assert .numberOfRowsM == .numberOfRows
assert .numberOfColumnsM == .numberOfColumns
+
selectObject: .dissimilarity
.tableOfReal = To TableOfReal
.numberOfRowsT = Get number of rows
@@ -146,153 +224,26 @@ procedure testDissimilarityInterface
assert .numberOfColumnsT == .numberOfColumns
removeObject: .table, .matrix, .tableOfReal
- appendInfoLine: tab$, tab$, "To Configuration"
- selectObject: .dissimilarity
- for .ipar to 6
- .numberOfDimensions$ [.ipar] = "2, "
- endfor
- .numberOfDimensions$[6] = "2, 2, "
- .minimizationParameters$ = "1e-05, 10, 1"
- .mdsCommand$ [1] = "To Configuration (monotone mds): "
- .extraParameters$ [1] = """Primary approach"", "
- .mdsCommand$ [2] = "To Configuration (i-spline mds): "
- .extraParameters$ [2] = "1, 1, "
- .mdsCommand$ [3] = "To Configuration (interval mds): "
- .extraParameters$ [3] = ""
- .mdsCommand$ [4] = "To Configuration (ratio mds): "
- .extraParameters$ [4] = ""
- .mdsCommand$ [5] = "To Configuration (absolute mds): "
- .extraParameters$ [5] = ""
- .mdsCommand$ [6] = "To Configuration (kruskal): "
- .extraParameters$ [6] = """Primary approach"", ""Kruskal's stress-1"", "
-
- # Create a random configuration
- .command$ = .mdsCommand$ [1] + .numberOfDimensions$ [1] + .extraParameters$ [1] + .minimizationParameters$
- .randomConfiguration = '.command$'
- Formula: "randomUniform (-1, 1)"
- Rename: "random"
-
- # Use the 6 different "To Configuration (..)" commands to get 6 configurations
-
- for .itype to 6
- selectObject: .dissimilarity
- .command$ = .mdsCommand$ [.itype] + .numberOfDimensions$ [.itype] + .extraParameters$ [.itype] + .minimizationParameters$
- configuration [.itype] = '.command$'
- endfor
-
- # Use the dissimilarity and the configuration and try to improve the configuration
-
- appendInfoLine: tab$, tab$, "Dissimilarity & Configuration"
- .minimizationParameters$ = "1e-08, 50, 1"
- for .itype to 6
- selectObject: .dissimilarity, configuration [.itype]
- .command$ = .mdsCommand$ [.itype] + .extraParameters$ [.itype] + .minimizationParameters$
- .configuration [.itype] = '.command$'
- endfor
-
- .stressMeasure$ [1] = "Normalized"
- .stressMeasure$ [2] = "Kruskal's stress-1"
- .stressMeasure$ [3] = "Kruskal's stress-2"
- .stressMeasure$ [4] = "Raw"
- .tiesHandling$ [1] = "Primary approach"
- .tiesHandling$ [2] = "Secondary approach"
- ;.stressCalculation$ [1] = "Formula1"
- ;.stressCalculation$ [2] = "Formula2"
- .stressCalculation$ [1] = "Kruskal's stress-1"
- .stressCalculation$ [2] = "Kruskal's stress-1"
-
- # test kruskal's stress-1 and stress-2
-
- for .ities to 2
- selectObject: .dissimilarity, .randomConfiguration
- .stress1_random = Get stress (monotone mds): .tiesHandling$ [.ities], .stressMeasure$ [2]
- .stress2_random = Get stress (monotone mds): .tiesHandling$ [.ities], .stressMeasure$ [3]
- assert .stress1_random <= .stress2_random; '.stress1_random' <= '.stress2_random' ? random
- for .i to 6
- selectObject: .dissimilarity, .configuration [.i]
- .stress1 = Get stress (monotone mds): .tiesHandling$ [.ities], .stressMeasure$ [2]
- .stress2 = Get stress (monotone mds): .tiesHandling$ [.ities], .stressMeasure$ [3]
- assert .stress1 <= .stress1_random; '.stress1' <= '.stress1_random' ? '.ities' conf['.i']
- assert .stress2 <= .stress2_random; '.stress2' <= '.stress2_random' ? '.ities' conf['.i']
- assert .stress1 <= .stress2; '.stress1' <= '.stress2' ? '.ities' conf['.i']
- endfor
- endfor
-if 0
- for .k to 4
- selectObject: .dissimilarity, .randomConfiguration
- .stress0 = Get stress (i-spline mds): 1, 3, .stressMeasure$ [.k]
- selectObject: .dissimilarity, configuration [2]
- .stress1 = Get stress (i-spline mds): 1, 3, .stressMeasure$ [.k]
- assert .stress1 <= .stress0
- selectObject: .dissimilarity, .configuration [2]
- .stress2 = Get stress (i-spline mds): 1, 3, .stressMeasure$ [.k]
- assert .stress2 <= .stress1; '.stress2' '.stress1' '.k'
- endfor
- for .k from 1 to 4
- selectObject: .dissimilarity, .randomConfiguration
- .stress10 = Get stress (interval mds): .stressMeasure$ [.k]
- selectObject: .dissimilarity, configuration [3]
- .stress11 = Get stress (interval mds): .stressMeasure$ [.k]
- assert .stress11 <= .stress10 ; '.k'
- selectObject: .dissimilarity, .configuration [3]
- .stress12 = Get stress (interval mds): .stressMeasure$ [.k]
- assert .stress12 <= .stress11 ; '.k'
- selectObject: .dissimilarity, .randomConfiguration
- .stress20 = Get stress (ratio mds): .stressMeasure$ [.k]
- selectObject: .dissimilarity, configuration [4]
- .stress21 = Get stress (ratio mds): .stressMeasure$ [.k]
- assert .stress21 <= .stress20 ; '.k'
- selectObject: .dissimilarity, .configuration [4]
- .stress22 = Get stress (ratio mds): .stressMeasure$ [.k]
- assert .stress22 <= .stress21 ; '.k' '.stress22' < '.stress21' ?
- selectObject: .dissimilarity, .randomConfiguration
- .stress30 = Get stress (absolute mds): .stressMeasure$ [.k]
- selectObject: .dissimilarity, configuration [5]
- .stress31 = Get stress (absolute mds): .stressMeasure$ [.k]
- assert .stress31 <= .stress30 ; '.k'
- selectObject: .dissimilarity, .configuration [5]
- .stress32 = Get stress (absolute mds): .stressMeasure$ [.k]
- assert .stress32 <= .stress31 ; '.k'
- endfor
-endif
-
- for .itype to 6
- removeObject: .configuration [.itype]
- endfor
-
- removeObject: .dissimilarity, .randomConfiguration
+ removeObject: .dissimilarity
+ appendInfoLine: tab$, "test interface OK"
endproc
-procedure dissimilarity_to_Configurations: .dissimilarity
-
-endproc
-
-procedure testINDSCAL
- for .i to 6
- selectObject: configuration [.i]
- .distance [.i] = To Distance
- endfor
-
- selectObject: .distance [1]
- for .i from 2 to 6
- plusObject: .distance [.i]
- endfor
-
- To Configuration (indscal): 2, "no", 1e-5, 10, 1, "yes", "no"
- .configuration = selected ("Configuration")
+procedure testCarrolWishExample
+ appendInfoLine: tab$, "INDSCAL Carroll Wish example"
+ Create INDSCAL Carroll Wish example: 0.0
+ .dissimilarities# = selected# ("Dissimilarity")
+ To Distance: "yes"
+ .distances# = selected# ("Distance")
+ To Configuration (indscal): 2, "no", 1e-5, 100, 1, "yes", "no"
+ .conf = selected ("Configuration")
.salience = selected ("Salience")
-
- # test old interface
- ;To Configuration (indscal): "no", 1e-5, 10
- ;.configuration2 = selected ("Configuration")
- ;.salience2 = selected ("Salience")
- ;removeObject: .configuration2, .salience2
-
- for .i from 1 to 6
- removeObject: .distance[.i]
+ selectObject: .dissimilarities# [1], .distances# [1]
+ for .i from 2 to size (.dissimilarities#)
+ plusObject: .dissimilarities# [.i], .distances# [.i]
endfor
-
- removeObject: .configuration, .salience
+ plusObject: .salience, .conf
+ Remove
+ appendInfoLine: tab$, "INDSCAL Carroll Wish example OK"
endproc
procedure test_additiveConstant
=====================================
dwtools/Configuration.cpp
=====================================
@@ -390,16 +390,21 @@ autoConfiguration TableOfReal_to_Configuration_pca (TableOfReal me, integer numb
/********************** Examples *********************************************/
+/*
+ 20210614: Configuration_createLetterRExample. Revert to version without initialisation lists because
+ that version is buggy when compiled with gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0
+ It turn out that x1 and y2 will contain the same values as x2 and y2.
+*/
autoConfiguration Configuration_createLetterRExample (int choice) {
- const constVEC x1 = {
+ const double x1[33] = { 0,
-5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
-5, -4, -3, -2, -1, 0, 1, 2.25, 3, 3,
2.25, 1, 0, -1, -2, -3, -4, -1, 0, 1, 2, 3 };
- const constVEC y1 = {
+ const double y1[33] = { 0,
-6, -5, -4, -3, -2, -1, 0, 1, 2, 3,
4, 4, 4, 4, 4, 4, 4, 3.5, 2, 1,
-0.5, -1, -1, -1, -1, -1, -1, -2, -3, -4, -5, -6 };
- const constVEC x2 = { 0.94756043346272423, 0.73504466902509913,
+ const double x2[33] = {0, 0.94756043346272423, 0.73504466902509913,
0.4528453515175927, 0.46311499024105723, 0.30345454816993439,
0.075184942115601547, -0.090010071904764719, -0.19630977381424003,
-0.36341509807865086, -0.54216996409132612, -0.68704678013309872,
@@ -410,7 +415,7 @@ autoConfiguration Configuration_createLetterRExample (int choice) {
0.18201798315035453, 0.048445620192953162, 0.081595930742961439,
0.20063623749033621, 0.28546520751183313, 0.39384438699721991,
0.62832258520372286, 0.78548335015622228, 1.0610707888793069 };
- const constVEC y2 = { 0.49630791172076621, 0.53320347382055022,
+ const double y2[33] = {0, 0.49630791172076621, 0.53320347382055022,
0.62384637225470441, 0.47592708487655661, 0.50364353255684202,
0.55311720162084443, 0.55118713773007066, 0.50007736370068601,
0.40432332354648709, 0.49817059660482677, 0.49803436631629411,
@@ -424,14 +429,12 @@ autoConfiguration Configuration_createLetterRExample (int choice) {
try {
autoConfiguration me = Configuration_create (32, 2);
Thing_setName (me.get(), ( choice == 2 ? U"R_fit" : U"R" ));
- for (integer i = 1; i <= 32; i ++)
- TableOfReal_setRowLabel (me.get(), i, Melder_integer (i));
- if (choice == 2) {
- my data.column (1) <<= x2;
- my data.column (2) <<= y2;
- } else {
- my data.column (1) <<= x1;
- my data.column (2) <<= y1;
+ for (integer i = 1; i <= 32; i ++) {
+ char32 s [20];
+ Melder_sprint (s, 20, i);
+ TableOfReal_setRowLabel (me.get(), i, s);
+ my data [i] [1] = ( choice == 2 ? x2 [i] : x1 [i] );
+ my data [i] [2] = ( choice == 2 ? y2 [i] : y1 [i] );
}
return me;
} catch (MelderError) {
=====================================
dwtools/KlattTable.cpp
=====================================
@@ -392,9 +392,9 @@ typedef struct structKlattFrame {
integer Gain0; /* Overall gain, 60 dB is unity, 0 to 60 */
} *KlattFrame;
-static const constSTRVEC theColumnNames = { U"f0", U"av", U"f1", U"b1", U"f2", U"b2", U"f3", U"b3", U"f4", U"b4", U"f5", U"b5", U"f6", U"b6",
+static autoSTRVEC theColumnNames = copy_STRVEC (constSTRVEC ({ U"f0", U"av", U"f1", U"b1", U"f2", U"b2", U"f3", U"b3", U"f4", U"b4", U"f5", U"b5", U"f6", U"b6",
U"fnz", U"bnz", U"fnp", U"bnp", U"ah", U"kopen", U"aturb", U"tilt", U"af", U"skew",
- U"a1", U"b1p", U"a2", U"b2p", U"a3", U"b3p", U"a4", U"b4p", U"a5", U"b5p", U"a6", U"b6p", U"anp", U"ab", U"avp", U"gain" };
+ U"a1", U"b1p", U"a2", U"b2p", U"a3", U"b3p", U"a4", U"b4p", U"a5", U"b5p", U"a6", U"b6p", U"anp", U"ab", U"avp", U"gain" }));
static double DBtoLIN (integer dB) {
static const double amptable [88] = {
@@ -463,13 +463,13 @@ autoKlattTable KlattTable_readFromRawTextFile (MelderFile fs) {
U"A KlattTable needs ", KlattTable_NPAR, U" columns.");
autoKlattTable me = Thing_new (KlattTable);
- Table_initWithColumnNames (me.get(), thy ny, theColumnNames);
+ Table_initWithColumnNames (me.get(), thy ny, theColumnNames.get());
for (integer irow = 1; irow <= thy ny; irow ++) {
for (integer jcol = 1; jcol <= KlattTable_NPAR; jcol ++) {
double val = thy z [irow] [jcol];
if (jcol > 3 && jcol < 13 && (jcol % 2 == 0) && val <= 0) // bw == 0?
val = thy z [irow] [jcol - 1] / 10;
- Table_setNumericValue ( (Table) me.get(), irow, jcol, val);
+ Table_setNumericValue (me.get(), irow, jcol, val);
}
}
return me;
@@ -557,7 +557,7 @@ autoKlattTable KlattTable_create (double frameDuration, double totalDuration) {
try {
autoKlattTable me = Thing_new (KlattTable);
const integer nrows = Melder_ifloor (totalDuration / frameDuration) + 1;
- Table_initWithColumnNames (me.get(), nrows, theColumnNames);
+ Table_initWithColumnNames (me.get(), nrows, theColumnNames.get());
return me;
} catch (MelderError) {
Melder_throw (U"KlattTable not created.");
@@ -618,13 +618,13 @@ static void KlattGlobal_getFrame (KlattGlobal me, KlattFrame thee) {
}
/*
-This function adds F0 flutter, as specified in:
+ This function adds F0 flutter, as specified in:
-"Analysis, synthesis and perception of voice quality variations among
-female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990.
+ "Analysis, synthesis and perception of voice quality variations among
+ female and male talkers", D.H. Klatt and L.C. Klatt, JASA 87(2), February 1990.
-Flutter is added by applying a quasi-random element constructed from three
-slowly varying sine waves.
+ Flutter is added by applying a quasi-random element constructed from three
+ slowly varying sine waves.
*/
static void KlattFrame_flutter (KlattGlobal me) {
@@ -640,9 +640,9 @@ static void KlattFrame_flutter (KlattGlobal me) {
}
/*
- Random number generator (return a number between -8191 and +8191)
- Noise spectrum is tilted down by soft low-pass filter having a pole near
- the origin in the z-plane, i.e. output = input + (0.75 * lastoutput)
+ Random number generator (return a number between -8191 and +8191)
+ Noise spectrum is tilted down by soft low-pass filter having a pole near
+ the origin in the Z-plane, i.e. output = input + (0.75 * lastoutput)
*/
static double KlattGlobal_gen_noise (KlattGlobal me) {
static double nlast = 0.0;
@@ -1079,12 +1079,12 @@ static int KlattTable_checkLimits (KlattTable me) {
for (integer j = 1; j <= KlattTable_NPAR; j ++) {
if (nviolations_lower [j] > 0) {
if (nviolations_upper [j] > 0)
- MelderInfo_writeLine (theColumnNames [j], U": ", nviolations_lower [j], U" frame(s) < min = ",
+ MelderInfo_writeLine (theColumnNames [j].get(), U": ", nviolations_lower [j], U" frame(s) < min = ",
nviolations_lower [j], U"; ", nviolations_upper [j], U" frame(s) > max = ", upper [j]);
else
- MelderInfo_writeLine (theColumnNames [j], U": ", nviolations_lower [j], U" frame(s) < min = ", lower [j]);
+ MelderInfo_writeLine (theColumnNames [j].get(), U": ", nviolations_lower [j], U" frame(s) < min = ", lower [j]);
} else if (nviolations_upper [j] > 0) {
- MelderInfo_writeLine (theColumnNames [j], U": ", nviolations_upper [j], U" frame(s) > max = ", upper [j]);
+ MelderInfo_writeLine (theColumnNames [j].get(), U": ", nviolations_upper [j], U" frame(s) > max = ", upper [j]);
}
}
MelderInfo_close ();
@@ -1114,50 +1114,50 @@ autoSound KlattTable_to_Sound (KlattTable me, double samplingFrequency, int synt
for (integer col = 1; col <= KlattTable_NPAR; col ++)
par [col] = Table_getNumericValue_Assert (me, irow, col); // ppgb: truncatie?
integer jcol = 1;
- frame -> F0hz10 = par [jcol ++];
- frame -> AVdb = par [jcol ++];
- frame -> Fhz [1] = par [jcol ++];
- frame -> Bhz [1] = par [jcol ++];
- frame -> Fhz [2] = par [jcol ++];
- frame -> Bhz [2] = par [jcol ++];
- frame -> Fhz [3] = par [jcol ++];
- frame -> Bhz [3] = par [jcol ++];
- frame -> Fhz [4] = par [jcol ++];
- frame -> Bhz [4] = par [jcol ++];
- frame -> Fhz [5] = par [jcol ++];
- frame -> Bhz [5] = par [jcol ++];
- frame -> Fhz [6] = par [jcol ++];
- frame -> Bhz [6] = par [jcol ++];
- frame -> FNZhz = par [jcol ++];
- frame -> BNZhz = par [jcol ++];
- frame -> FNPhz = par [jcol ++];
- frame -> BNPhz = par [jcol ++];
- frame -> ah = par [jcol ++];
- frame -> Kopen = par [jcol ++];
- frame -> Aturb = par [jcol ++];
- frame -> TLTdb = par [jcol ++];
- frame -> AF = par [jcol ++];
- frame -> Kskew = par [jcol ++];
- frame -> A [1] = par [jcol ++];
- frame -> Bphz [1] = par [jcol ++];
- frame -> A [2] = par [jcol ++];
- frame -> Bphz [2] = par [jcol ++];
- frame -> A [3] = par [jcol ++];
- frame -> Bphz [3] = par [jcol ++];
- frame -> A [4] = par [jcol ++];
- frame -> Bphz [4] = par [jcol ++];
- frame -> A [5] = par [jcol ++];
- frame -> Bphz [5] = par [jcol ++];
- frame -> A [6] = par [jcol ++];
- frame -> Bphz [6] = par [jcol ++];
- frame -> ANP = par [jcol ++];
- frame -> AB = par [jcol ++];
- frame -> AVpdb = par [jcol ++];
- frame -> Gain0 = par [jcol ++];;
- frame -> Fhz [7] = 6500;
- frame -> Bhz [7] = 600;
- frame -> Fhz [8] = 7500;
- frame -> Bhz [8] = 600;
+ frame -> F0hz10 = par [jcol ++];
+ frame -> AVdb = par [jcol ++];
+ frame -> Fhz [1] = par [jcol ++];
+ frame -> Bhz [1] = par [jcol ++];
+ frame -> Fhz [2] = par [jcol ++];
+ frame -> Bhz [2] = par [jcol ++];
+ frame -> Fhz [3] = par [jcol ++];
+ frame -> Bhz [3] = par [jcol ++];
+ frame -> Fhz [4] = par [jcol ++];
+ frame -> Bhz [4] = par [jcol ++];
+ frame -> Fhz [5] = par [jcol ++];
+ frame -> Bhz [5] = par [jcol ++];
+ frame -> Fhz [6] = par [jcol ++];
+ frame -> Bhz [6] = par [jcol ++];
+ frame -> FNZhz = par [jcol ++];
+ frame -> BNZhz = par [jcol ++];
+ frame -> FNPhz = par [jcol ++];
+ frame -> BNPhz = par [jcol ++];
+ frame -> ah = par [jcol ++];
+ frame -> Kopen = par [jcol ++];
+ frame -> Aturb = par [jcol ++];
+ frame -> TLTdb = par [jcol ++];
+ frame -> AF = par [jcol ++];
+ frame -> Kskew = par [jcol ++];
+ frame -> A [1] = par [jcol ++];
+ frame -> Bphz [1] = par [jcol ++];
+ frame -> A [2] = par [jcol ++];
+ frame -> Bphz [2] = par [jcol ++];
+ frame -> A [3] = par [jcol ++];
+ frame -> Bphz [3] = par [jcol ++];
+ frame -> A [4] = par [jcol ++];
+ frame -> Bphz [4] = par [jcol ++];
+ frame -> A [5] = par [jcol ++];
+ frame -> Bphz [5] = par [jcol ++];
+ frame -> A [6] = par [jcol ++];
+ frame -> Bphz [6] = par [jcol ++];
+ frame -> ANP = par [jcol ++];
+ frame -> AB = par [jcol ++];
+ frame -> AVpdb = par [jcol ++];
+ frame -> Gain0 = par [jcol ++];;
+ frame -> Fhz [7] = 6500;
+ frame -> Bhz [7] = 600;
+ frame -> Fhz [8] = 7500;
+ frame -> Bhz [8] = 600;
KlattGlobal_getFrame (thee, frame);
@@ -1176,7 +1176,6 @@ autoSound KlattTable_to_Sound (KlattTable me, double samplingFrequency, int synt
}
}
-
autoKlattTable KlattTable_createExample () {
const integer nrows = 1376;
const struct klatt_params {
@@ -2561,7 +2560,7 @@ autoKlattTable KlattTable_createExample () {
};
try {
autoKlattTable me = Thing_new (KlattTable);
- Table_initWithColumnNames (me.get(), nrows, theColumnNames);
+ Table_initWithColumnNames (me.get(), nrows, theColumnNames.get());
Melder_assert (theColumnNames.size == KlattTable_NPAR);
for (integer irow = 1; irow <= nrows; irow ++) {
for (integer jcol = 1; jcol <= KlattTable_NPAR; jcol ++) {
=====================================
dwtools/Proximity.cpp
=====================================
@@ -1,6 +1,6 @@
/* Proximity.cpp
*
- * Copyright (C) 1993-2019 David Weenink
+ * Copyright (C) 1993-2021 David Weenink
*
* 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
=====================================
fon/manual_Script.cpp
=====================================
@@ -3013,7 +3013,8 @@ CODE (U"confusion\\# \\# = {{ 3, 6, 2 }, { 8, 2, 1 }}")
NORMAL (U"After this, the variable %%confusion\\# \\# % contains the value {{ 3, 6, 2 }, { 8, 2, 1 }}. "
"We say that the matrix %%confusion\\# % has two %rows and three %columns, i.e. it contains six numbers.")
NORMAL (U"Whereas a numeric vector with five dimensions could be seen (see above) as a street that contains five houses, "
- "the matrix %%confusion\\# \\# % can be seen as a city district with two avenues crossed by three streets.")
+ "the matrix %%confusion\\# \\# % can be seen as a city district with two avenues crossed by three streets, "
+ "where everybody lives on an intersection (the analogies start to get less realistic).")
ENTRY (U"6. Creating a matrix")
NORMAL (U"You can create a matrix in many ways. The first way we saw was with a ##matrix literal#, "
"i.e. a series of series of numbers (or numeric formulas) between nested braces.")
=====================================
fon/manual_soundFiles.cpp
=====================================
@@ -217,9 +217,9 @@ NORMAL (U"Vorbis is a general-purpose patent-free lossy audio compression format
MAN_END
MAN_BEGIN (U"Sound files 2.9. Ogg Opus files", U"djmw", 20210604)
-NORMAL (U"Opus is a general-purpose patent-free lossy audio compression format. "
- "It is a newer and better format than @@Sound files 2.8. Ogg Vorbis files|Vorbis at . "
- "According to the website at ##https://xiph.org/#: \"It was developed by the Xiph.Org Foundation and standardized by the Internet Engineering Task Force, designed to efficiently "
+NORMAL (U"Opus is a general-purpose patent-free lossy audio compression format, "
+ "a successor to @@Sound files 2.8. Ogg Vorbis files|Vorbis at . "
+ "According to Xiph.Org's website, this format \"was developed by the Xiph.Org Foundation and standardized by the Internet Engineering Task Force, designed to efficiently "
"code speech and general audio in a single format, while remaining low-latency enough for real-time interactive communication "
"and low-complexity enough for low-end embedded processors.\" "
"Praat supports Ogg Opus decoding through open source code made available at "
=====================================
fon/manual_tutorials.cpp
=====================================
@@ -22,8 +22,13 @@
void manual_tutorials_init (ManPages me);
void manual_tutorials_init (ManPages me) {
-MAN_BEGIN (U"What's new?", U"ppgb", 20210612)
+MAN_BEGIN (U"What's new?", U"ppgb", 20210620)
INTRO (U"Latest changes in Praat.")
+NORMAL (U"##6.1.50# (20 June 2021)")
+LIST_ITEM (U"• RealTier: editing, Formula, conversion from and to Matrix and Table and other tiers such as PitchTier, "
+ "DurationTier, IntensityTier and AmplitudeTier.")
+LIST_ITEM (U"• Scripting: can now assign multiple objects to a vector.")
+LIST_ITEM (U"• Fix crashes in ##Create letter R example# and ##Create KlattTable example# introduced in 6.1.49.")
NORMAL (U"##6.1.49# (12 June 2021)")
LIST_ITEM (U"• @PitchTier, @IntensityTier, @DurationTier and @AmplitudeTier windows: save preferences.")
LIST_ITEM (U"• @Manipulation window: removed unused semitone options.")
=====================================
sys/Formula.cpp
=====================================
@@ -56,6 +56,9 @@ static int ilabel, ilexan, iparse, numberOfInstructions, numberOfStringConstants
enum { NO_SYMBOL_,
+#define DECLARE_WITH_TENSORS(symbol) \
+ symbol, symbol##VEC_, symbol##MAT_,
+
/* First, all symbols after which "-" is unary. */
/* The list ends with "MINUS_" itself. */
@@ -87,18 +90,23 @@ enum { NO_SYMBOL_,
/* Functions of 1 variable; if you add, update the #defines. */
#define LOW_FUNCTION_1 ABS_
- ABS_, ROUND_, FLOOR_, CEILING_,
- RECTIFY_, RECTIFY_VEC_, RECTIFY_MAT_,
- SQRT_, SIN_, COS_, TAN_, ARCSIN_, ARCCOS_, ARCTAN_, SINC_, SINCPI_,
- EXP_, EXP_VEC_, EXP_MAT_,
- SINH_, COSH_, TANH_, TANH_VEC_,
- ARCSINH_, ARCCOSH_, ARCTANH_,
+ DECLARE_WITH_TENSORS (ABS_)
+ DECLARE_WITH_TENSORS (ROUND_) DECLARE_WITH_TENSORS (FLOOR_) DECLARE_WITH_TENSORS (CEILING_)
+ DECLARE_WITH_TENSORS (RECTIFY_)
+ DECLARE_WITH_TENSORS (SQRT_)
+ DECLARE_WITH_TENSORS (SIN_) DECLARE_WITH_TENSORS (COS_) DECLARE_WITH_TENSORS (TAN_)
+ DECLARE_WITH_TENSORS (ARCSIN_) DECLARE_WITH_TENSORS (ARCCOS_) DECLARE_WITH_TENSORS (ARCTAN_)
+ SINC_, SINCPI_,
+ DECLARE_WITH_TENSORS (EXP_)
+ DECLARE_WITH_TENSORS (SINH_) DECLARE_WITH_TENSORS (COSH_) DECLARE_WITH_TENSORS (TANH_)
+ DECLARE_WITH_TENSORS (ARCSINH_) DECLARE_WITH_TENSORS (ARCCOSH_) DECLARE_WITH_TENSORS (ARCTANH_)
SIGMOID_, SIGMOID_VEC_, SOFTMAX_VEC_, SOFTMAX_PER_ROW_MAT_,
INV_SIGMOID_, ERF_, ERFC_, GAUSS_P_, GAUSS_Q_, INV_GAUSS_Q_,
RANDOM_BERNOULLI_, RANDOM_BERNOULLI_VEC_,
RANDOM_POISSON_, TRANSPOSE_MAT_,
ROW_SUMS_VEC_, COLUMN_SUMS_VEC_,
- LOG2_, LN_, LOG10_, LN_GAMMA_,
+ DECLARE_WITH_TENSORS (LOG2_) DECLARE_WITH_TENSORS (LN_) DECLARE_WITH_TENSORS (LOG10_)
+ LN_GAMMA_,
HERTZ_TO_BARK_, BARK_TO_HERTZ_, PHON_TO_DIFFERENCE_LIMENS_, DIFFERENCE_LIMENS_TO_PHON_,
HERTZ_TO_MEL_, MEL_TO_HERTZ_, HERTZ_TO_SEMITONES_, SEMITONES_TO_HERTZ_,
ERB_, HERTZ_TO_ERB_, ERB_TO_HERTZ_,
@@ -223,6 +231,9 @@ enum { NO_SYMBOL_,
/* they are used in error messages and in debugging (see Formula_print). */
static const conststring32 Formula_instructionNames [1 + highestSymbol] = { U"",
+ #define NAME_WITH_TENSORS(name) \
+ U"" #name, U"" #name "#", U"" #name "##",
+
U"if", U"then", U"else", U"(", U"[", U"{", U",", U":", U"from", U"to",
U"or", U"and", U"not", U"=", U"<>", U"<=", U"<", U">=", U">",
U"+", U"-", U"*", U"/", U"div", U"mod", U"^", U"_call", U"_neg",
@@ -232,18 +243,23 @@ static const conststring32 Formula_instructionNames [1 + highestSymbol] = { U"",
U"row", U"col", U"nrow", U"ncol", U"row$", U"col$", U"y", U"x",
U"self", U"self$", U"object", U"object$", U"_matrix", U"_matrix$",
U"stopwatch",
- U"abs", U"round", U"floor", U"ceiling",
- U"rectify", U"rectify#", U"rectify##",
- U"sqrt", U"sin", U"cos", U"tan", U"arcsin", U"arccos", U"arctan", U"sinc", U"sincpi",
- U"exp", U"exp#", U"exp##",
- U"sinh", U"cosh", U"tanh", U"tanh#",
- U"arcsinh", U"arccosh", U"arctanh",
+ NAME_WITH_TENSORS (abs)
+ NAME_WITH_TENSORS (round) NAME_WITH_TENSORS (floor) NAME_WITH_TENSORS (ceiling)
+ NAME_WITH_TENSORS (rectify)
+ NAME_WITH_TENSORS (sqrt)
+ NAME_WITH_TENSORS (sin) NAME_WITH_TENSORS (cos) NAME_WITH_TENSORS (tan)
+ NAME_WITH_TENSORS (arcsin) NAME_WITH_TENSORS (arccos) NAME_WITH_TENSORS (arctan)
+ U"sinc", U"sincpi",
+ NAME_WITH_TENSORS (exp)
+ NAME_WITH_TENSORS (sinh) NAME_WITH_TENSORS (cosh) NAME_WITH_TENSORS (tanh)
+ NAME_WITH_TENSORS (arcsinh) NAME_WITH_TENSORS (arccosh) NAME_WITH_TENSORS (arctanh)
U"sigmoid", U"sigmoid#", U"softmax#", U"softmaxPerRow##",
U"invSigmoid", U"erf", U"erfc", U"gaussP", U"gaussQ", U"invGaussQ",
U"randomBernoulli", U"randomBernoulli#",
U"randomPoisson", U"transpose##",
U"rowSums#", U"columnSums#",
- U"log2", U"ln", U"log10", U"lnGamma",
+ NAME_WITH_TENSORS (log2) NAME_WITH_TENSORS (ln) NAME_WITH_TENSORS (log10)
+ U"lnGamma",
U"hertzToBark", U"barkToHertz", U"phonToDifferenceLimens", U"differenceLimensToPhon",
U"hertzToMel", U"melToHertz", U"hertzToSemitones", U"semitonesToHertz",
U"erb", U"hertzToErb", U"erbToHertz",
@@ -3331,230 +3347,99 @@ static void do_softmaxPerRow_MAT () {
U" requires a numeric matrix argument, not ", x->whichText(), U".");
}
}
-static void do_abs () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : fabs (x->number));
- } else {
- Melder_throw (U"Cannot take the absolute value (abs) of ", x->whichText(), U".");
- }
-}
-static void do_round () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : floor (x->number + 0.5));
- } else {
- Melder_throw (U"Cannot round ", x->whichText(), U".");
- }
-}
-static void do_floor () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : Melder_roundDown (x->number));
- } else {
- Melder_throw (U"Cannot round down (floor) ", x->whichText(), U".");
- }
-}
-static void do_ceiling () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : Melder_roundUp (x->number));
- } else {
- Melder_throw (U"Cannot round up (ceiling) ", x->whichText(), U".");
- }
-}
-static void do_rectify () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : x->number > 0.0 ? x->number : 0.0);
- } else {
- Melder_throw (U"Cannot rectify ", x->whichText(), U".");
- }
-}
-static void do_rectify_VEC () {
- Stackel x = pop;
- if (x->which == Stackel_NUMERIC_VECTOR) {
- integer nelm = x->numericVector.size;
- autoVEC result = raw_VEC (nelm);
- for (integer i = 1; i <= nelm; i ++) {
- double xvalue = x->numericVector [i];
- result [i] = isundef (xvalue) ? undefined : xvalue > 0.0 ? xvalue : 0.0;
- }
- pushNumericVector (result.move());
- } else {
- Melder_throw (U"Cannot rectify ", x->whichText(), U".");
- }
-}
-static void do_rectify_MAT () {
- Stackel x = topOfStack;
- if (x->which == Stackel_NUMERIC_MATRIX) {
- if (x->owned) {
- integer nrow = x->numericMatrix.nrow, ncol = x->numericMatrix.ncol;
- for (integer irow = 1; irow <= nrow; irow ++) {
- for (integer icol = 1; icol <= ncol; icol ++) {
- double xvalue = x->numericMatrix [irow] [icol];
- x->numericMatrix [irow] [icol] = isundef (xvalue) ? undefined : xvalue > 0.0 ? xvalue : 0.0;
- }
- }
- } else {
- pop;
- integer nrow = x->numericMatrix.nrow, ncol = x->numericMatrix.ncol;
- autoMAT result = raw_MAT (nrow, ncol);
- for (integer irow = 1; irow <= nrow; irow ++) {
- for (integer icol = 1; icol <= ncol; icol ++) {
- double xvalue = x->numericMatrix [irow] [icol];
- result [irow] [icol] = isundef (xvalue) ? undefined : xvalue > 0.0 ? xvalue : 0.0;
- }
- }
- pushNumericMatrix (result.move());
- }
- } else {
- Melder_throw (U"Cannot rectify ", x->whichText(), U".");
- }
-}
-static void do_sqrt () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined :
- x->number < 0.0 ? undefined : sqrt (x->number));
- } else {
- Melder_throw (U"Cannot take the square root (sqrt) of ", x->whichText(), U".");
- }
-}
-static void do_sin () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : sin (x->number));
- } else {
- Melder_throw (U"Cannot take the sine (sin) of ", x->whichText(), U".");
- }
-}
-static void do_cos () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : cos (x->number));
- } else {
- Melder_throw (U"Cannot take the cosine (cos) of ", x->whichText(), U".");
- }
-}
-static void do_tan () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : tan (x->number));
- } else {
- Melder_throw (U"Cannot take the tangent (tan) of ", x->whichText(), U".");
- }
-}
-static void do_arcsin () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined :
- fabs (x->number) > 1.0 ? undefined : asin (x->number));
- } else {
- Melder_throw (U"Cannot take the arcsine (arcsin) of ", x->whichText(), U".");
- }
-}
-static void do_arccos () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined :
- fabs (x->number) > 1.0 ? undefined : acos (x->number));
- } else {
- Melder_throw (U"Cannot take the arccosine (arccos) of ", x->whichText(), U".");
- }
-}
-static void do_arctan () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : atan (x->number));
- } else {
- Melder_throw (U"Cannot take the arctangent (arctan) of ", x->whichText(), U".");
- }
-}
-static void do_exp () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : exp (x->number));
- } else {
- Melder_throw (U"Cannot exponentiate (exp) ", x->whichText(), U".");
- }
-}
-static void do_exp_VEC () {
- Stackel x = pop;
- if (x->which == Stackel_NUMERIC_VECTOR) {
- integer nelm = x->numericVector.size;
- autoVEC result = raw_VEC (nelm);
- for (integer i = 1; i <= nelm; i ++)
- result [i] = exp (x->numericVector [i]);
- pushNumericVector (result.move());
- } else {
- Melder_throw (U"Cannot exponentiate (exp) ", x->whichText(), U".");
- }
-}
-static void do_exp_MAT () {
- Stackel x = pop;
- if (x->which == Stackel_NUMERIC_MATRIX) {
- integer nrow = x->numericMatrix.nrow, ncol = x->numericMatrix.ncol;
- autoMAT result = raw_MAT (nrow, ncol);
- for (integer irow = 1; irow <= nrow; irow ++)
- for (integer icol = 1; icol <= ncol; icol ++)
- result [irow] [icol] = exp (x->numericMatrix [irow] [icol]);
- pushNumericMatrix (result.move());
- } else {
- Melder_throw (U"Cannot exponentiate (exp) ", x->whichText(), U".");
- }
-}
-static void do_sinh () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : sinh (x->number));
- } else {
- Melder_throw (U"Cannot take the hyperbolic sine (sinh) of ", x->whichText(), U".");
- }
-}
-static void do_cosh () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : cosh (x->number));
- } else {
- Melder_throw (U"Cannot take the hyperbolic cosine (cosh) of ", x->whichText(), U".");
- }
-}
-static void do_tanh () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined : tanh (x->number));
- } else {
- Melder_throw (U"Cannot take the hyperbolic tangent (tanh) of ", x->whichText(), U".");
- }
-}
-static void do_log2 () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined :
- x->number <= 0.0 ? undefined : log (x->number) * NUMlog2e);
- } else {
- Melder_throw (U"Cannot take the base-2 logarithm (log2) of ", x->whichText(), U".");
- }
-}
-static void do_ln () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined :
- x->number <= 0.0 ? undefined : log (x->number));
- } else {
- Melder_throw (U"Cannot take the natural logarithm (ln) of ", x->whichText(), U".");
- }
-}
-static void do_log10 () {
- Stackel x = pop;
- if (x->which == Stackel_NUMBER) {
- pushNumber (isundef (x->number) ? undefined :
- x->number <= 0.0 ? undefined : log10 (x->number));
- } else {
- Melder_throw (U"Cannot take the base-10 logarithm (log10) of ", x->whichText(), U".");
- }
-}
+
+#define DO_NUM_WITH_TENSORS(function, formula, message) \
+static void do_##function () { \
+ Stackel x = pop; \
+ if (x->which == Stackel_NUMBER) { \
+ const double xvalue = x->number; \
+ pushNumber (formula); \
+ } else if (x->which == Stackel_NUMERIC_VECTOR) { \
+ Melder_throw (U"The function " #function " requires a numeric argument, " \
+ "not a vector. Did you mean to use " #function "# instead?"); \
+ } else if (x->which == Stackel_NUMERIC_MATRIX) { \
+ Melder_throw (U"The function " #function " requires a numeric argument, " \
+ "not a matrix. Did you mean to use " #function "## instead?"); \
+ } else { \
+ Melder_throw (message, x->whichText(), \
+ U". The function " #function " requires a numeric argument"); \
+ } \
+} \
+static void do_##function##_VEC () { \
+ Stackel x = topOfStack; \
+ if (x->which == Stackel_NUMERIC_VECTOR) { \
+ if (x->owned) { \
+ const integer numberOfElements = x->numericVector.size; \
+ for (integer i = 1; i <= numberOfElements; i ++) { \
+ const double xvalue = x->numericVector [i]; \
+ x->numericVector [i] = isundef (xvalue) ? undefined : formula; \
+ } \
+ } else { \
+ pop; \
+ const integer numberOfElements = x->numericVector.size; \
+ autoVEC result = raw_VEC (numberOfElements); \
+ for (integer i = 1; i <= numberOfElements; i ++) { \
+ const double xvalue = x->numericVector [i]; \
+ result [i] = isundef (xvalue) ? undefined : formula; \
+ } \
+ pushNumericVector (result.move()); \
+ } \
+ } else { \
+ Melder_throw (message, x->whichText(), \
+ U". The function " #function " requires a vector argument"); \
+ } \
+} \
+static void do_##function##_MAT () { \
+ Stackel x = topOfStack; \
+ if (x->which == Stackel_NUMERIC_MATRIX) { \
+ if (x->owned) { \
+ const integer nrow = x->numericMatrix.nrow, ncol = x->numericMatrix.ncol; \
+ for (integer irow = 1; irow <= nrow; irow ++) { \
+ for (integer icol = 1; icol <= ncol; icol ++) { \
+ const double xvalue = x->numericMatrix [irow] [icol]; \
+ x->numericMatrix [irow] [icol] = isundef (xvalue) ? undefined : formula; \
+ } \
+ } \
+ } else { \
+ pop; \
+ const integer nrow = x->numericMatrix.nrow, ncol = x->numericMatrix.ncol; \
+ autoMAT result = raw_MAT (nrow, ncol); \
+ for (integer irow = 1; irow <= nrow; irow ++) { \
+ for (integer icol = 1; icol <= ncol; icol ++) { \
+ const double xvalue = x->numericMatrix [irow] [icol]; \
+ result [irow] [icol] = isundef (xvalue) ? undefined : formula; \
+ } \
+ } \
+ pushNumericMatrix (result.move()); \
+ } \
+ } else { \
+ Melder_throw (message, x->whichText(), \
+ U". The function " #function " requires a matrix argument"); \
+ } \
+}
+DO_NUM_WITH_TENSORS (abs, fabs (xvalue), U"Cannot take the absolute value (abs) of ")
+DO_NUM_WITH_TENSORS (round, floor (xvalue + 0.5), U"Cannot round ")
+DO_NUM_WITH_TENSORS (floor, Melder_roundDown (xvalue), U"Cannot round down (floor) ")
+DO_NUM_WITH_TENSORS (ceiling, Melder_roundUp (xvalue), U"Cannot round up (ceiling) ")
+DO_NUM_WITH_TENSORS (rectify, xvalue < 0.0 ? 0.0 : xvalue, U"Cannot rectify ") // NaN-safe
+DO_NUM_WITH_TENSORS (sqrt, /*xvalue < 0.0 ? undefined :*/ sqrt (xvalue), U"Cannot take the square root (sqrt) of ")
+DO_NUM_WITH_TENSORS (sin, sin (xvalue), U"Cannot take the sine (sin) of ")
+DO_NUM_WITH_TENSORS (cos, cos (xvalue), U"Cannot take the cosine (cos) of ")
+DO_NUM_WITH_TENSORS (tan, tan (xvalue), U"Cannot take the tangent (tan) of ")
+DO_NUM_WITH_TENSORS (arcsin, /*fabs (xvalue) > 1.0 ? undefined :*/ asin (xvalue), U"Cannot take the arcsine (arcsin) of ")
+DO_NUM_WITH_TENSORS (arccos, /*fabs (xvalue) > 1.0 ? undefined :*/ acos (xvalue), U"Cannot take the arccosine (arccos) of ")
+DO_NUM_WITH_TENSORS (arctan, atan (xvalue), U"Cannot take the arctangent (arctan) of ")
+DO_NUM_WITH_TENSORS (exp, exp (xvalue), U"Cannot exponentiate (exp) ")
+DO_NUM_WITH_TENSORS (sinh, sinh (xvalue), U"Cannot take the hyperbolic sine (sinh) of ")
+DO_NUM_WITH_TENSORS (cosh, cosh (xvalue), U"Cannot take the hyperbolic cosine (cosh) of ")
+DO_NUM_WITH_TENSORS (tanh, tanh (xvalue), U"Cannot take the hyperbolic tangent (tanh) of ")
+DO_NUM_WITH_TENSORS (arcsinh, asinh (xvalue), U"Cannot take the hyperbolic arcsine (arcsinh) of ")
+DO_NUM_WITH_TENSORS (arccosh, acosh (xvalue), U"Cannot take the hyperbolic arccosine (arccosh) of ")
+DO_NUM_WITH_TENSORS (arctanh, atanh (xvalue), U"Cannot take the hyperbolic arctangent (arctanh) of ")
+DO_NUM_WITH_TENSORS (log2, /*xvalue <= 0.0 ? undefined :*/ log (xvalue) * NUMlog2e, U"Cannot take the base-2 logarithm (log2) of ")
+DO_NUM_WITH_TENSORS (ln, /*xvalue <= 0.0 ? undefined :*/ log (xvalue), U"Cannot take the natural logarithm (ln) of ")
+DO_NUM_WITH_TENSORS (log10, /*xvalue <= 0.0 ? undefined :*/ log10 (xvalue), U"Cannot take the base-10 logarithm (log10) of ")
+
static void do_sum () {
Stackel x = pop;
if (x->which == Stackel_NUMERIC_VECTOR) {
@@ -7273,32 +7158,32 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
} break; case MINUS_: { do_minus ();
} break; case POWER_: { do_power ();
/********** Functions of 1 variable: **********/
-} break; case ABS_: { do_abs ();
-} break; case ROUND_: { do_round ();
-} break; case FLOOR_: { do_floor ();
-} break; case CEILING_: { do_ceiling ();
-} break; case RECTIFY_: { do_rectify ();
-} break; case RECTIFY_VEC_: { do_rectify_VEC ();
-} break; case RECTIFY_MAT_: { do_rectify_MAT ();
-} break; case SQRT_: { do_sqrt ();
-} break; case SIN_: { do_sin ();
-} break; case COS_: { do_cos ();
-} break; case TAN_: { do_tan ();
-} break; case ARCSIN_: { do_arcsin ();
-} break; case ARCCOS_: { do_arccos ();
-} break; case ARCTAN_: { do_arctan ();
+
+#define CASE_NUM_WITH_TENSORS(label, function) \
+} break; case label: { function (); \
+} break; case label##VEC_: { function##_VEC (); \
+} break; case label##MAT_: { function##_MAT ();
+CASE_NUM_WITH_TENSORS (ABS_, do_abs)
+CASE_NUM_WITH_TENSORS (ROUND_, do_round)
+CASE_NUM_WITH_TENSORS (FLOOR_, do_floor)
+CASE_NUM_WITH_TENSORS (CEILING_, do_ceiling)
+CASE_NUM_WITH_TENSORS (RECTIFY_, do_rectify)
+CASE_NUM_WITH_TENSORS (SQRT_, do_sqrt)
+CASE_NUM_WITH_TENSORS (SIN_, do_sin)
+CASE_NUM_WITH_TENSORS (COS_, do_cos)
+CASE_NUM_WITH_TENSORS (TAN_, do_tan)
+CASE_NUM_WITH_TENSORS (ARCSIN_, do_arcsin)
+CASE_NUM_WITH_TENSORS (ARCCOS_, do_arccos)
+CASE_NUM_WITH_TENSORS (ARCTAN_, do_arctan)
} break; case SINC_: { do_function_n_n (NUMsinc);
} break; case SINCPI_: { do_function_n_n (NUMsincpi);
-} break; case EXP_: { do_exp ();
-} break; case EXP_VEC_: { do_exp_VEC ();
-} break; case EXP_MAT_: { do_exp_MAT ();
-} break; case SINH_: { do_sinh ();
-} break; case COSH_: { do_cosh ();
-} break; case TANH_: { do_tanh ();
-} break; case TANH_VEC_: { do_functionvec_n_n (tanh);
-} break; case ARCSINH_: { do_function_n_n (NUMarcsinh);
-} break; case ARCCOSH_: { do_function_n_n (NUMarccosh);
-} break; case ARCTANH_: { do_function_n_n (NUMarctanh);
+CASE_NUM_WITH_TENSORS (EXP_, do_exp)
+CASE_NUM_WITH_TENSORS (SINH_, do_sinh)
+CASE_NUM_WITH_TENSORS (COSH_, do_cosh)
+CASE_NUM_WITH_TENSORS (TANH_, do_tanh)
+CASE_NUM_WITH_TENSORS (ARCSINH_, do_arcsinh)
+CASE_NUM_WITH_TENSORS (ARCCOSH_, do_arccosh)
+CASE_NUM_WITH_TENSORS (ARCTANH_, do_arctanh)
} break; case SIGMOID_: { do_function_n_n (NUMsigmoid);
} break; case SIGMOID_VEC_: { do_functionvec_n_n (NUMsigmoid);
} break; case SOFTMAX_VEC_: { do_softmax_VEC ();
@@ -7315,9 +7200,9 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
} break; case TRANSPOSE_MAT_: { do_transpose_MAT ();
} break; case ROW_SUMS_VEC_: { do_rowSums_VEC ();
} break; case COLUMN_SUMS_VEC_: { do_columnSums_VEC ();
-} break; case LOG2_: { do_log2 ();
-} break; case LN_: { do_ln ();
-} break; case LOG10_: { do_log10 ();
+CASE_NUM_WITH_TENSORS (LOG2_, do_log2)
+CASE_NUM_WITH_TENSORS (LN_, do_ln)
+CASE_NUM_WITH_TENSORS (LOG10_, do_log10)
} break; case LN_GAMMA_: { do_function_n_n (NUMlnGamma);
} break; case HERTZ_TO_BARK_: { do_function_n_n (NUMhertzToBark);
} break; case BARK_TO_HERTZ_: { do_function_n_n (NUMbarkToHertz);
=====================================
sys/Interpreter.cpp
=====================================
@@ -1374,14 +1374,15 @@ static void assignToNumericVectorElement (Interpreter me, char32 *& p, const cha
MelderString_empty (& valueString);
autoMelderDivertInfo divert (& valueString);
MelderString_appendCharacter (& valueString, 1); // will be overwritten by something totally different if any MelderInfo function is called....
- int status = praat_executeCommand (me, p);
- if (status == 0) {
+ bool status = praat_executeCommand (me, p);
+ if (! status) {
value = undefined;
- } else if (valueString.string [0] == 1) { // ...not overwritten by any MelderInfo function? then the return value will be the selected object
+ } else if (my returnType == kInterpreter_ReturnType::OBJECT_) {
int IOBJECT, selectedObject = 0, numberOfSelectedObjects = 0;
WHERE (SELECTED) { selectedObject = IOBJECT; numberOfSelectedObjects += 1; }
if (numberOfSelectedObjects > 1)
- Melder_throw (U"Multiple objects selected. Cannot assign object ID to vector element.");
+ Melder_throw (U"Multiple objects selected. Cannot assign object IDs to vector element. "
+ "Perhaps use a vector variable instead.");
if (numberOfSelectedObjects == 0)
Melder_throw (U"No objects selected. Cannot assign object ID to vector element.");
value = theCurrentPraatObjects -> list [selectedObject]. id;
@@ -1509,23 +1510,25 @@ static void assignToNumericMatrixElement (Interpreter me, char32 *& p, const cha
MelderString_empty (& valueString);
autoMelderDivertInfo divert (& valueString);
MelderString_appendCharacter (& valueString, 1); // will be overwritten by something totally different if any MelderInfo function is called....
- int status = praat_executeCommand (me, p);
- if (status == 0) {
+ bool status = praat_executeCommand (me, p);
+ if (! status) {
value = undefined;
- } else if (valueString.string [0] == 1) { // ...not overwritten by any MelderInfo function? then the return value will be the selected object
+ } else if (my returnType == kInterpreter_ReturnType::OBJECT_) {
int IOBJECT, selectedObject = 0, numberOfSelectedObjects = 0;
WHERE (SELECTED) { selectedObject = IOBJECT; numberOfSelectedObjects += 1; }
- if (numberOfSelectedObjects > 1) {
- Melder_throw (U"Multiple objects selected. Cannot assign object ID to matrix element.");
- } else if (numberOfSelectedObjects == 0) {
+ if (numberOfSelectedObjects > 1)
+ Melder_throw (U"Multiple objects selected. Cannot assign object IDs to matrix element. "
+ "Perhaps use a vector variable instead.");
+ if (numberOfSelectedObjects == 0)
Melder_throw (U"No objects selected. Cannot assign object ID to matrix element.");
- } else {
- value = theCurrentPraatObjects -> list [selectedObject]. id;
- }
+ value = theCurrentPraatObjects -> list [selectedObject]. id;
} else {
value = Melder_atof (valueString.string); // including --undefined--
}
} else {
+ /*
+ Get the value of the formula.
+ */
Interpreter_numericExpression (me, p, & value);
}
InterpreterVariable var = Interpreter_hasVariable (me, matrixName);
@@ -1599,8 +1602,11 @@ static void assignToStringArrayElement (Interpreter me, char32 *& p, const char3
*/
MelderString_empty (& valueString);
autoMelderDivertInfo divert (& valueString);
- int status = praat_executeCommand (me, p);
- value = ( status == 0 ? autostring32 () : Melder_dup (valueString.string) );
+ bool status = praat_executeCommand (me, p);
+ if (! status)
+ value = autostring32();
+ else
+ value = Melder_dup (valueString.string);
} else {
/*
Get the value of the formula.
@@ -1832,8 +1838,9 @@ void Interpreter_run (Interpreter me, char32 *text) {
trace (U"resume");
c0 = command2.string [0]; // resume in order to allow things like 'c$' = 5
if ((! Melder_isLetter (c0) || Melder_isUpperCaseLetter (c0)) && c0 != U'@' &&
- ! (c0 == U'.' && Melder_isLetter (command2.string [1]) && ! Melder_isUpperCaseLetter (command2.string [1]))) {
- praat_executeCommand (me, command2.string);
+ ! (c0 == U'.' && Melder_isLetter (command2.string [1]) && ! Melder_isUpperCaseLetter (command2.string [1])))
+ {
+ (void) praat_executeCommand (me, command2.string);
/*
* Interpret control flow and variables.
*/
@@ -2045,7 +2052,7 @@ void Interpreter_run (Interpreter me, char32 *text) {
/*
Make sure that lines like "echo = 3" will not be regarded as assignments.
*/
- praat_executeCommand (me, command2.string);
+ (void) praat_executeCommand (me, command2.string);
} else
fail = true;
break;
@@ -2239,7 +2246,7 @@ void Interpreter_run (Interpreter me, char32 *text) {
* Make sure that lines like "print = 3" will not be regarded as assignments.
*/
if (command2.string [5] == U' ' || (str32nequ (command2.string + 5, U"line", 4) && (command2.string [9] == U' ' || command2.string [9] == U'\0'))) {
- praat_executeCommand (me, command2.string);
+ (void) praat_executeCommand (me, command2.string);
} else
fail = true;
} else
@@ -2378,20 +2385,26 @@ void Interpreter_run (Interpreter me, char32 *text) {
p ++; // go to first token after assignment
if (*p == U'\0')
Melder_throw (U"Missing right-hand expression in assignment to string array ", arrayName.string, U".");
+ InterpreterVariable var = Interpreter_lookUpVariable (me, arrayName.string);
if (isCommand (p)) {
/*
Statement like: lines$# = Get all strings
*/
- praat_executeCommand (me, p);
- if (my returnType != kInterpreter_ReturnType::STRINGARRAY_)
- Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p), U"; not assigned to the string array variable \"", arrayName.string, U"\".");
- InterpreterVariable var = Interpreter_lookUpVariable (me, arrayName.string);
- var -> stringArrayValue = my returnedStringArray.move();
+ bool status = praat_executeCommand (me, p);
+ if (! status)
+ var -> stringArrayValue = autoSTRVEC(); // anything can have happened, including an incorrect returnType
+ else if (my returnType == kInterpreter_ReturnType::STRINGARRAY_)
+ var -> stringArrayValue = my returnedStringArray.move();
+ else
+ Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p),
+ U"; not assigned to the string array variable \"", arrayName.string, U"\".");
} else {
+ /*
+ Statement like: files$# = fileNames$# ("*.wav")
+ */
STRVEC value;
bool owned;
Interpreter_stringArrayExpression (me, p, & value, & owned);
- InterpreterVariable var = Interpreter_lookUpVariable (me, arrayName.string);
StringArrayVariable_move (var, value, owned);
}
} else if (*p == U'[') {
@@ -2506,12 +2519,18 @@ void Interpreter_run (Interpreter me, char32 *text) {
*/
MelderString_empty (& valueString); // empty because command may print nothing; also makes sure that valueString.string exists
autoMelderDivertInfo divert (& valueString);
- int status = praat_executeCommand (me, p);
- if (my returnType == kInterpreter_ReturnType::STRING_ || my returnType == kInterpreter_ReturnType::REAL_ || my returnType == kInterpreter_ReturnType::INTEGER_) {
- InterpreterVariable var = Interpreter_lookUpVariable (me, variableName);
- var -> stringValue = Melder_dup (status ? valueString.string : U"");
- } else
- Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p), U"; not assigned to the string variable \"", variableName, U"\".");
+ bool status = praat_executeCommand (me, p);
+ InterpreterVariable var = Interpreter_lookUpVariable (me, variableName);
+ if (! status)
+ var -> stringValue = Melder_dup (U""); // anything can have happened, including an incorrect returnType
+ else if (my returnType == kInterpreter_ReturnType::STRING_ ||
+ my returnType == kInterpreter_ReturnType::REAL_ ||
+ my returnType == kInterpreter_ReturnType::INTEGER_
+ )
+ var -> stringValue = Melder_dup (valueString.string);
+ else
+ Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p),
+ U"; not assigned to the string variable \"", variableName, U"\".");
} else {
/*
Evaluate a string expression and assign the result to the variable.
@@ -2560,20 +2579,23 @@ void Interpreter_run (Interpreter me, char32 *text) {
while (Melder_isHorizontalSpace (*p)) p ++; // go to first token after assignment
if (*p == U'\0')
Melder_throw (U"Missing right-hand expression in assignment to matrix ", matrixName.string, U".");
+ InterpreterVariable var = Interpreter_lookUpVariable (me, matrixName.string);
if (isCommand (p)) {
/*
Statement like: values## = Get all values
*/
- praat_executeCommand (me, p);
- if (my returnType != kInterpreter_ReturnType::REALMATRIX_)
- Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p), U"; not assigned to the matrix variable \"", matrixName.string, U"\".");
- InterpreterVariable var = Interpreter_lookUpVariable (me, matrixName.string);
- var -> numericMatrixValue = my returnedRealMatrix.move();
+ bool status = praat_executeCommand (me, p);
+ if (! status)
+ var -> numericMatrixValue = autoMAT(); // anything can have happened, including an incorrect returnType
+ else if (my returnType == kInterpreter_ReturnType::REALMATRIX_)
+ var -> numericMatrixValue = my returnedRealMatrix.move();
+ else
+ Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p),
+ U"; not assigned to the matrix variable \"", matrixName.string, U"\".");
} else {
MAT value;
bool owned;
Interpreter_numericMatrixExpression (me, p, & value, & owned);
- InterpreterVariable var = Interpreter_lookUpVariable (me, matrixName.string);
NumericMatrixVariable_move (var, value, owned);
}
} else if (*p == U'[') {
@@ -2679,20 +2701,26 @@ void Interpreter_run (Interpreter me, char32 *text) {
p ++; // go to first token after assignment
if (*p == U'\0')
Melder_throw (U"Missing right-hand expression in assignment to vector ", vectorName.string, U".");
+ InterpreterVariable var = Interpreter_lookUpVariable (me, vectorName.string);
if (isCommand (p)) {
/*
Statement like: times# = Get all times
*/
- praat_executeCommand (me, p);
- if (my returnType != kInterpreter_ReturnType::REALVECTOR_)
+ bool status = praat_executeCommand (me, p);
+ if (! status)
+ var -> numericVectorValue = autoVEC(); // anything can have happened, including an incorrect returnType
+ else if (my returnType == kInterpreter_ReturnType::OBJECT_) {
+ var -> numericVectorValue = autoVEC();
+ int IOBJECT;
+ WHERE (SELECTED) *var -> numericVectorValue. append() = ID;
+ } else if (my returnType == kInterpreter_ReturnType::REALVECTOR_)
+ var -> numericVectorValue = my returnedRealVector.move();
+ else
Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p), U"; not assigned to the vector variable \"", vectorName.string, U"\".");
- InterpreterVariable var = Interpreter_lookUpVariable (me, vectorName.string);
- var -> numericVectorValue = my returnedRealVector.move();
} else {
VEC value;
bool owned;
Interpreter_numericVectorExpression (me, p, & value, & owned);
- InterpreterVariable var = Interpreter_lookUpVariable (me, vectorName.string);
NumericVectorVariable_move (var, value, owned);
}
} else if (*p == U'[') {
@@ -2790,7 +2818,7 @@ void Interpreter_run (Interpreter me, char32 *text) {
/*
Command ends here: it may be a PraatShell command.
*/
- praat_executeCommand (me, command2.string);
+ (void) praat_executeCommand (me, command2.string);
continue; // next line
}
char32 *endOfVariable = p;
@@ -2833,7 +2861,7 @@ void Interpreter_run (Interpreter me, char32 *text) {
Melder_assert (! result. stringResult);
Interpreter_anyExpression (me, index.string, & result);
if (result.expressionType == kFormula_EXPRESSION_TYPE_NUMERIC) {
- double numericIndexValue = result. numericResult;
+ const double numericIndexValue = result. numericResult;
MelderString_append (& indexedVariableName, numericIndexValue);
} else if (result.expressionType == kFormula_EXPRESSION_TYPE_STRING) {
MelderString_append (& indexedVariableName, U"\"", result. stringResult.get(), U"\"");
@@ -2853,7 +2881,7 @@ void Interpreter_run (Interpreter me, char32 *text) {
/*
Not an assignment: perhaps a PraatShell command (select, echo, execute, pause ...).
*/
- praat_executeCommand (me, variableName);
+ (void) praat_executeCommand (me, variableName);
continue; // next line
}
p += ( typeOfAssignment == 0 ? 1 : 2 );
@@ -2874,24 +2902,23 @@ void Interpreter_run (Interpreter me, char32 *text) {
MelderString_empty (& valueString);
autoMelderDivertInfo divert (& valueString);
MelderString_appendCharacter (& valueString, 1); // will be overwritten by something totally different if any MelderInfo function is called...
- int status = praat_executeCommand (me, p);
- if (status == 0) {
- value = undefined;
+ bool status = praat_executeCommand (me, p);
+ if (! status) {
+ value = undefined; // anything can have happened, including an incorrect return type
} else if (my returnType == kInterpreter_ReturnType::OBJECT_) {
int IOBJECT, selectedObject = 0, numberOfSelectedObjects = 0;
WHERE (SELECTED) { selectedObject = IOBJECT; numberOfSelectedObjects += 1; }
- if (numberOfSelectedObjects > 1) {
- Melder_throw (U"Multiple objects selected. Cannot assign object ID to variable.");
- } else if (numberOfSelectedObjects == 0) {
+ if (numberOfSelectedObjects > 1)
+ Melder_throw (U"Multiple objects selected. Cannot assign object IDs to numeric variable. "
+ "Perhaps use a vector variable instead.");
+ if (numberOfSelectedObjects == 0)
Melder_throw (U"No objects selected. Cannot assign object ID to variable.");
- } else {
- value = theCurrentPraatObjects -> list [selectedObject]. id;
- }
- } else if (my returnType != kInterpreter_ReturnType::REAL_ && my returnType != kInterpreter_ReturnType::INTEGER_) {
- Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p), U"; not assigned to the numeric variable \"", variableName, U"\".");
- } else {
+ value = theCurrentPraatObjects -> list [selectedObject]. id;
+ } else if (my returnType == kInterpreter_ReturnType::REAL_ || my returnType == kInterpreter_ReturnType::INTEGER_) {
value = Melder_atof (valueString.string); // including --undefined--
- }
+ } else
+ Melder_throw (kInterpreter_ReturnType_errorMessage (my returnType, p),
+ U"; not assigned to the numeric variable \"", variableName, U"\".");
} else {
/*
Get the value of the formula.
=====================================
sys/praat.cpp
=====================================
@@ -1898,7 +1898,7 @@ void praat_run () {
char32 *newline = str32chr (line, U'\n');
if (newline) *newline = U'\0';
try {
- praat_executeCommand (nullptr, line);
+ (void) praat_executeCommand (nullptr, line); // should contain no cases of "nocheck"
} catch (MelderError) {
Melder_clearError (); // ignore this line, but not necessarily the next
}
=====================================
sys/praat_script.cpp
=====================================
@@ -180,7 +180,7 @@ static int parseCommaSeparatedArguments (Interpreter interpreter, char32 *argume
return narg;
}
-int praat_executeCommand (Interpreter interpreter, char32 *command) {
+bool praat_executeCommand (Interpreter interpreter, char32 *command) {
if (interpreter)
interpreter -> returnType = kInterpreter_ReturnType::VOID_; // clear return type to its default
@@ -274,26 +274,26 @@ int praat_executeCommand (Interpreter interpreter, char32 *command) {
}
} else if (str32nequ (command, U"nowarn ", 7)) {
autoMelderWarningOff nowarn;
- praat_executeCommand (interpreter, command + 7);
+ return praat_executeCommand (interpreter, command + 7);
} else if (str32nequ (command, U"noprogress ", 11)) {
autoMelderProgressOff noprogress;
- praat_executeCommand (interpreter, command + 11);
+ return praat_executeCommand (interpreter, command + 11);
} else if (str32nequ (command, U"nocheck ", 8)) {
try {
- praat_executeCommand (interpreter, command + 8);
+ return praat_executeCommand (interpreter, command + 8);
} catch (MelderError) {
Melder_clearError ();
- return 0;
+ return false;
}
} else if (str32nequ (command, U"demo ", 5)) {
autoDemoOpen demo;
- praat_executeCommand (interpreter, command + 5);
+ return praat_executeCommand (interpreter, command + 5);
} else if (str32nequ (command, U"asynchronous ", 13)) {
autoMelderAsynchronous asynchronous;
- praat_executeCommand (interpreter, command + 13);
+ return praat_executeCommand (interpreter, command + 13);
} else if (str32nequ (command, U"pause ", 6) || str32equ (command, U"pause")) {
if (theCurrentPraatApplication -> batch)
- return 1; // in batch we ignore pause statements
+ return true; // in batch we ignore pause statements
UiPause_begin (theCurrentPraatApplication -> topShell, U"stop or continue", interpreter);
UiPause_comment (str32equ (command, U"pause") ? U"..." : command + 6);
UiPause_end (1, 1, 0, U"Continue", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, interpreter);
@@ -532,7 +532,7 @@ int praat_executeCommand (Interpreter interpreter, char32 *command) {
}
praat_updateSelection ();
}
- return 1;
+ return true;
}
void praat_executeCommandFromStandardInput (conststring32 programName) {
@@ -549,7 +549,7 @@ void praat_executeCommandFromStandardInput (conststring32 programName) {
*newLine = '\0';
autostring32 command32 = Melder_8to32 (command8);
try {
- praat_executeCommand (nullptr, command32.get());
+ (void) praat_executeCommand (nullptr, command32.get());
} catch (MelderError) {
Melder_flushError (programName, U": Command \"", Melder_peek8to32 (command8), U"\" not executed.");
}
=====================================
sys/praat_script.h
=====================================
@@ -2,7 +2,7 @@
#define _praat_script_h_
/* praat_script.h
*
- * Copyright (C) 1992-2005,2007,2009-2016,2018 Paul Boersma
+ * Copyright (C) 1992-2005,2007,2009-2016,2018,2021 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
@@ -20,7 +20,7 @@
#include "Interpreter.h"
-int praat_executeCommand (Interpreter me, char32 *command);
+bool praat_executeCommand (Interpreter me, char32 *command); // returns false only if nocheck cancelled an error
void praat_executeCommandFromStandardInput (conststring32 programName);
void praat_executeScriptFromFile (MelderFile file, conststring32 arguments);
void praat_executeScriptFromFileName (conststring32 fileName, integer narg, Stackel args);
=====================================
sys/praat_version.h
=====================================
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.1.49
-#define PRAAT_VERSION_NUM 6149
+#define PRAAT_VERSION_STR 6.1.50
+#define PRAAT_VERSION_NUM 6150
#define PRAAT_YEAR 2021
#define PRAAT_MONTH June
-#define PRAAT_DAY 12
+#define PRAAT_DAY 20
=====================================
test/dwtools/KlattTable.praat
=====================================
@@ -0,0 +1,17 @@
+# KlattTable.praat
+# Paul Boersma 2021-06-16
+
+klattTable = Create KlattTable example
+table = To Table
+
+#
+# Test whether list initialization worked correctly.
+#
+numberOfColumns = Get number of columns
+assert numberOfColumns = 40
+firstColumnLabel$ = Get column label: 1
+assert firstColumnLabel$ = "f0"
+lastColumnLabel$ = Get column label: numberOfColumns
+assert lastColumnLabel$ = "gain"
+
+removeObject: klattTable, table
=====================================
test/fon/Spectrum.praat
=====================================
@@ -0,0 +1,12 @@
+s1 = Create Sound from formula: "s1", 1, 0, 1, 44100, "1/2 * sin(2*pi*377*x) + randomGauss(0,0.1)"
+s2 = Copy: "s2"
+plusObject: s1
+asserterror Multiple objects selected. Cannot assign object IDs to numeric variable. Perhaps use a vector variable instead.
+a = To Spectrum: "yes"
+removeObject: "Spectrum s1", "Spectrum s2"
+selectObject: s1, s2
+a# = To Spectrum: "yes"
+assert a# = { s1, s2 } + 4
+writeInfoLine: a#
+plusObject: s1, s2
+Remove
\ No newline at end of file
=====================================
test/script/undefined.praat
=====================================
@@ -40,6 +40,31 @@ assert 0 * undefined = undefined
assert 1 / undefined = undefined
assert 0 ^ undefined = undefined
assert undefined ^ undefined = undefined
+assert abs (undefined) = undefined
+assert round (undefined) = undefined
+assert floor (undefined) = undefined
+assert ceiling (undefined) = undefined
+assert rectify (undefined) = undefined
+assert sin (undefined) = undefined
+assert cos (undefined) = undefined
+assert tan (undefined) = undefined
+assert arcsin (undefined) = undefined
+assert arccos (undefined) = undefined
+assert arctan (undefined) = undefined
+assert sinh (undefined) = undefined
+assert cosh (undefined) = undefined
+assert tanh (undefined) = undefined
+assert arcsinh (undefined) = undefined
+assert arccosh (undefined) = undefined
+assert arctanh (undefined) = undefined
+assert exp (undefined) = undefined
+assert log2 (undefined) = undefined
+assert ln (undefined) = undefined
+assert log10 (undefined) = undefined
+assert exp (1e6) = undefined
+assert 0 * exp (1e6) = undefined
+assert sqrt (-1) = undefined
+assert 0 * sqrt (-1) = undefined
#
# Propagation within larger expressions.
@@ -58,4 +83,5 @@ assert 0 ^ 0 = 1
;assert undefined ^ 0 = 1
assert undefined ^ 0 = undefined
;assert sqrt (-1) ^ 0 = 1
-assert sqrt (-1) ^ 0 = undefined
\ No newline at end of file
+assert sqrt (-1) ^ 0 = undefined
+
View it on GitLab: https://salsa.debian.org/med-team/praat/-/commit/eb03c933f751a2ce1ec787c296ce8325ae50b258
--
View it on GitLab: https://salsa.debian.org/med-team/praat/-/commit/eb03c933f751a2ce1ec787c296ce8325ae50b258
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/20210704/7a952065/attachment-0001.htm>
More information about the debian-med-commit
mailing list