[med-svn] [Git][med-team/praat][master] 5 commits: New upstream version 6.0.49
Rafael Laboissiere
gitlab at salsa.debian.org
Mon Mar 11 17:15:00 GMT 2019
Rafael Laboissiere pushed to branch master at Debian Med / praat
Commits:
b71b6d8b by Rafael Laboissiere at 2019-03-10T22:07:49Z
New upstream version 6.0.49
- - - - -
29daecfe by Rafael Laboissiere at 2019-03-10T22:10:24Z
Merge tag 'upstream/6.0.49'
Upstream version 6.0.49
- - - - -
542eef41 by Rafael Laboissiere at 2019-03-10T22:36:57Z
d/copyright: Reflect upstream changes
- - - - -
83777a4d by Rafael Laboissiere at 2019-03-11T05:42:56Z
d/What_s_new_.html: Update upstream changelog
Gbp-Dch: Ignore
- - - - -
ca3058be by Rafael Laboissiere at 2019-03-11T17:14:00Z
Changelog entry for version 6.0.49-1
Gbp-Dch: Ignore
- - - - -
26 changed files:
- debian/What_s_new_.html
- debian/changelog
- debian/copyright
- dwtools/CC.cpp
- dwtools/CC.h
- dwtools/CCs_to_DTW.cpp
- dwtools/Sound_and_Spectrogram_extensions.cpp
- dwtools/praat_David_init.cpp
- fon/Makefile
- fon/Pitch.cpp
- fon/Pitch.h
- fon/Sound.cpp
- fon/Sound.h
- + fon/SoundSet.cpp
- + fon/SoundSet.h
- fon/manual_tutorials.cpp
- fon/praat_Fon.cpp
- fon/praat_Matrix.cpp
- fon/praat_Sound.cpp
- main/praat.plist
- melder/MAT.h
- melder/MelderString.h
- melder/melder_strings.cpp
- sys/Formula.cpp
- sys/praat_version.h
- + test/stat/Table_undefined.praat
Changes:
=====================================
debian/What_s_new_.html
=====================================
@@ -7,6 +7,18 @@ What's new?
<p>
Latest changes in Praat.</p>
<p>
+<b>6.0.49</b> (2 March 2019)</p>
+<ul>
+<li>
+ Removed a bug introduced in 6.0.41 whereby a script could misreport an undefined table value.
+<li>
+ Removed a bug introduced in 6.0.44 whereby an MFCC's maximum frequency could be ignored.
+<li>
+ Pitch: Tabulate candidates.
+<li>
+ SoundSet.
+</ul>
+<p>
<b>6.0.48</b> (17 February 2019)</p>
<ul>
<li>
@@ -644,7 +656,7 @@ What used to be new?</h3>
</ul>
<hr>
<address>
- <p>© ppgb, February 17, 2019</p>
+ <p>© ppgb, March 2, 2019</p>
</address>
</body>
</html>
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+praat (6.0.49-1) unstable; urgency=medium
+
+ * New upstream version 6.0.49
+ * d/copyright: Reflect upstream changes
+
+ -- Rafael Laboissiere <rafael at debian.org> Sun, 10 Mar 2019 19:37:06 -0300
+
praat (6.0.48-1) unstable; urgency=medium
* New upstream version 6.0.48
=====================================
debian/copyright
=====================================
@@ -5,7 +5,7 @@ Source: http://www.fon.hum.uva.nl/praat/download_sources.html
Files: *
Copyright: 1990-2019 Paul Boersma
- 1992-2018 David Weenink
+ 1992-2019 David Weenink
2007 Erez Volk
2002 Hansjoerg Mixdorff
2008, 2017 Stefan de Konink
=====================================
dwtools/CC.cpp
=====================================
@@ -1,6 +1,6 @@
/* CC.cpp
*
- * Copyright (C) 1993-2018 David Weenink
+ * Copyright (C) 1993-2019 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
@@ -49,7 +49,7 @@
Thing_implement (CC, Sampled, 1);
-static integer CC_getMaximumNumberOfCoefficientsUsed (CC me) {
+integer CC_getMaximumNumberOfCoefficientsUsed (CC me) {
integer numberOfCoefficients = 0;
for (integer iframe = 1; iframe <= my nx; iframe ++) {
CC_Frame cf = & my frame [iframe];
=====================================
dwtools/CC.h
=====================================
@@ -2,7 +2,7 @@
#define _CC_h_
/* CC.h
*
- * Copyright (C) 1993-2017 David Weenink
+ * Copyright (C) 1993-2019 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
@@ -34,6 +34,8 @@ void CC_init (CC me, double tmin, double tmax, integer nt, double dt, double t1,
void CC_getNumberOfCoefficients_extrema (CC me, integer startframe, integer endframe, integer *min, integer *max);
+integer CC_getMaximumNumberOfCoefficientsUsed (CC me);
+
integer CC_getMinimumNumberOfCoefficients (CC me, integer startframe, integer endframe);
integer CC_getMaximumNumberOfCoefficients (CC me, integer startframe, integer endframe);
=====================================
dwtools/CCs_to_DTW.cpp
=====================================
@@ -56,7 +56,7 @@ autoDTW CCs_to_DTW (CC me, CC thee, double coefficientWeight, double logEnergyWe
integer nr = Melder_ifloor (regressionWindowLength / my dx);
Melder_require (my maximumNumberOfCoefficients == thy maximumNumberOfCoefficients,
- U"CC orders should be equal.");
+ U"The maximum number of coefficients should be equal.");
Melder_require (! (coefficientRegressionWeight != 0.0 && nr < 2),
U"Time window for regression is too small.");
=====================================
dwtools/Sound_and_Spectrogram_extensions.cpp
=====================================
@@ -1,6 +1,6 @@
/* Sound_and_Spectrogram_extensions.cpp
*
- * Copyright (C) 1993-2018 David Weenink
+ * Copyright (C) 1993-2019 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
@@ -166,7 +166,7 @@ static void Sound_into_MelSpectrogram_frame (Sound me, MelSpectrogram thee, inte
autoSpectrum him = Sound_to_Spectrum_power (me);
for (integer ifilter = 1; ifilter <= thy ny; ifilter ++) {
- double power = 0;
+ longdouble power = 0.0;
double fc_mel = thy y1 + (ifilter - 1) * thy dy;
double fc_hz = thy v_frequencyToHertz (fc_mel);
double fl_hz = thy v_frequencyToHertz (fc_mel - thy dy);
@@ -180,7 +180,7 @@ static void Sound_into_MelSpectrogram_frame (Sound me, MelSpectrogram thee, inte
double a = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, f);
power += a * his z [1] [i];
}
- thy z [ifilter] [frame] = power;
+ thy z [ifilter] [frame] = double (power);
}
}
@@ -195,8 +195,10 @@ autoMelSpectrogram Sound_to_MelSpectrogram (Sound me, double analysisWidth, doub
if (fmax_mel <= 0.0 || fmax_mel > fceiling)
fmax_mel = fceiling;
- if (fmax_mel <= f1_mel)
- f1_mel = fbottom; fmax_mel = fceiling;
+ if (fmax_mel <= f1_mel) {
+ f1_mel = fbottom;
+ fmax_mel = fceiling;
+ }
if (f1_mel <= 0.0)
f1_mel = fbottom;
if (df_mel <= 0.0)
=====================================
dwtools/praat_David_init.cpp
=====================================
@@ -4072,6 +4072,12 @@ DO
NUMBER_ONE_END (U"")
}
+DIRECT (NUMMAT_PatternList_getAllValues) {
+ NUMMAT_ONE (PatternList)
+ autoMAT result = newMATcopy (my z.all());
+ NUMMAT_ONE_END
+}
+
FORM (MODIFY_PatternList_formula, U"PatternList: Formula", nullptr) {
LABEL (U"# `col` is the node number, `row` is the pattern number")
LABEL (U"for row from 1 to nrow ; for all patterns")
@@ -8159,6 +8165,7 @@ void praat_uvafon_David_init () {
praat_addAction1 (classPatternList, 0, MODIFY_BUTTON, nullptr, 0, 0);
praat_addAction1 (classPatternList, 0, U"Formula...", nullptr, 1, MODIFY_PatternList_formula);
praat_addAction1 (classPatternList, 0, U"Set value...", nullptr, 1, MODIFY_PatternList_setValue);
+ praat_addAction1 (classPatternList, 0, U"Get all values", nullptr, 0, NUMMAT_PatternList_getAllValues);
praat_addAction1 (classPatternList, 0, U"To Matrix", nullptr, 0, NEW_PatternList_to_Matrix);
praat_addAction2 (classPatternList, 1, classCategories, 1, U"To TableOfReal", nullptr, 0, NEW1_Matrix_Categories_to_TableOfReal);
=====================================
fon/Makefile
=====================================
@@ -1,5 +1,5 @@
# Makefile of the library "fon"
-# Paul Boersma, 10 August 2018
+# Paul Boersma, 28 February 2019
include ../makefile.defs
@@ -8,7 +8,7 @@ CPPFLAGS = -I ../kar -I ../melder -I ../sys -I ../dwsys -I ../stat -I ../dwtools
OBJECTS = Transition.o Distributions_and_Transition.o \
Function.o Sampled.o SampledXY.o Matrix.o Vector.o Polygon.o PointProcess.o \
Matrix_and_PointProcess.o Matrix_and_Polygon.o AnyTier.o RealTier.o \
- Sound.o LongSound.o Sound_files.o Sound_audio.o PointProcess_and_Sound.o Sound_PointProcess.o ParamCurve.o \
+ Sound.o LongSound.o SoundSet.o Sound_files.o Sound_audio.o PointProcess_and_Sound.o Sound_PointProcess.o ParamCurve.o \
Pitch.o Harmonicity.o Intensity.o Matrix_and_Pitch.o Sound_to_Pitch.o \
Sound_to_Intensity.o Sound_to_Harmonicity.o Sound_to_Harmonicity_GNE.o Sound_to_PointProcess.o \
Pitch_to_PointProcess.o Pitch_to_Sound.o Pitch_Intensity.o \
=====================================
fon/Pitch.cpp
=====================================
@@ -926,4 +926,40 @@ void Pitch_step (Pitch me, double step, double precision, double tmin, double tm
}
}
+static autoTable Pitch_Frame_tabulateCandidates (Pitch_Frame me) {
+ autoTable you = Table_createWithColumnNames (my nCandidates, U"frequency strength");
+ for (integer icand = 1; icand <= my nCandidates; icand ++) {
+ Pitch_Candidate candidate = & my candidate [icand];
+ Table_setNumericValue (you.get(), icand, 1, candidate -> frequency);
+ Table_setNumericValue (you.get(), icand, 2, candidate -> strength);
+ }
+ return you;
+}
+
+autoTable Pitch_tabulateCandidatesInFrame (Pitch me, integer frameNumber) {
+ Pitch_checkFrameNumber (me, frameNumber);
+ Pitch_Frame frame = & my frame [frameNumber];
+ return Pitch_Frame_tabulateCandidates (frame);
+}
+
+autoTable Pitch_tabulateCandidates (Pitch me) {
+ integer totalNumberOfCandidates = 0;
+ for (integer iframe = 1; iframe <= my nx; iframe ++) {
+ Pitch_Frame frame = & my frame [iframe];
+ totalNumberOfCandidates += frame -> nCandidates;
+ }
+ autoTable result = Table_createWithColumnNames(totalNumberOfCandidates, U"frame frequency strength");
+ integer rowNumber = 0;
+ for (integer iframe = 1; iframe <= my nx; iframe ++) {
+ Pitch_Frame frame = & my frame [iframe];
+ for (integer icand = 1; icand <= frame -> nCandidates; icand ++) {
+ Pitch_Candidate candidate = & frame -> candidate [icand];
+ Table_setNumericValue (result.get(), ++ rowNumber, 1, double (iframe));
+ Table_setNumericValue (result.get(), rowNumber, 2, candidate -> frequency);
+ Table_setNumericValue (result.get(), rowNumber, 3, candidate -> strength);
+ }
+ }
+ return result;
+}
+
/* End of file Pitch.cpp */
=====================================
fon/Pitch.h
=====================================
@@ -2,7 +2,7 @@
#define _Pitch_h_
/* Pitch.h
*
- * Copyright (C) 1992-2007,2009,2011,2012,2014-2018 Paul Boersma
+ * Copyright (C) 1992-2007,2009,2011,2012,2014-2019 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include "Sampled.h"
#include "Graphics.h"
+#include "Table.h"
Thing_declare (Interpreter);
#include "Pitch_enums.h"
@@ -203,5 +204,8 @@ void Pitch_step (Pitch me, double step, double precision, double tmin, double tm
void Pitch_formula (Pitch me, conststring32 formula, Interpreter interpreter);
+autoTable Pitch_tabulateCandidatesInFrame (Pitch me, integer frameNumber);
+autoTable Pitch_tabulateCandidates (Pitch me);
+
/* End of file Pitch.h */
#endif
=====================================
fon/Sound.cpp
=====================================
@@ -1273,34 +1273,4 @@ autoSound Sounds_crossCorrelate_short (Sound me, Sound thee, double tmin, double
Thing_implement (SoundList, Ordered, 0);
-integer SoundList_getMinimumNumberOfSamples (SoundList me) {
- integer result = INTEGER_MAX;
- for (integer isound = 1; isound <= my size; isound ++)
- if (my at [isound] -> nx < result)
- result = my at [isound] -> nx;
- return result;
-}
-
-autoMAT SoundList_getRandomizedPatterns (SoundList me, integer numberOfPatterns, integer patternSize) {
- try {
- integer minimumNumberOfSamples = SoundList_getMinimumNumberOfSamples (me);
- Melder_require (patternSize <= minimumNumberOfSamples,
- U"The pattern size cannot be ", patternSize, U", because there is a Sound that is only ", minimumNumberOfSamples, U" samples long.");
- autoMAT result = newMATzero (numberOfPatterns, patternSize);
- for (integer ipattern = 1; ipattern <= numberOfPatterns; ipattern ++) {
- integer soundNumber = NUMrandomInteger (1, my size);
- Sound sound = my at [soundNumber];
- integer numberOfSamples = sound -> nx;
- integer endSample = NUMrandomInteger (patternSize, numberOfSamples);
- integer startSample = endSample - (patternSize - 1);
- Melder_assert (startSample >= 1);
- constVEC const samples = sound -> z.row (1);
- result.row (ipattern) <<= samples. part (startSample, endSample);
- }
- return result;
- } catch (MelderError) {
- Melder_throw (me, U": no randomize patterns gotten.");
- }
-}
-
/* End of file Sound.cpp */
=====================================
fon/Sound.h
=====================================
@@ -346,8 +346,5 @@ autoSound Sound_deepenBandModulation (Sound me, double enhancement_dB,
Collection_define (SoundList, OrderedOf, Sound) {
};
-integer SoundList_getMinimumNumberOfSamples (SoundList me);
-autoMAT SoundList_getRandomizedPatterns (SoundList me, integer numberOfPatterns, integer patternSize);
-
/* End of file Sound.h */
#endif
=====================================
fon/SoundSet.cpp
=====================================
@@ -0,0 +1,87 @@
+/* SoundSet.cpp
+ *
+ * Copyright (C) 2019 Paul Boersma
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SoundSet.h"
+
+Thing_implement (SoundSet, Ordered, 0);
+
+integer SoundSet_getMinimumNumberOfSamples (SoundSet me) {
+ integer result = INTEGER_MAX;
+ for (integer isound = 1; isound <= my size; isound ++)
+ if (my at [isound] -> nx < result)
+ result = my at [isound] -> nx;
+ return result;
+}
+
+autoMAT SoundSet_getRandomizedPatterns (SoundSet me, integer numberOfPatterns, integer patternSize) {
+ try {
+ integer minimumNumberOfSamples = SoundSet_getMinimumNumberOfSamples (me);
+ Melder_require (patternSize <= minimumNumberOfSamples,
+ U"The pattern size cannot be ", patternSize, U", because there is a Sound that is only ", minimumNumberOfSamples, U" samples long.");
+ autoMAT result = newMATzero (numberOfPatterns, patternSize);
+ for (integer ipattern = 1; ipattern <= numberOfPatterns; ipattern ++) {
+ integer soundNumber = NUMrandomInteger (1, my size);
+ Sound sound = my at [soundNumber];
+ integer numberOfSamples = sound -> nx;
+ integer endSample = NUMrandomInteger (patternSize, numberOfSamples);
+ integer startSample = endSample - (patternSize - 1);
+ Melder_assert (startSample >= 1);
+ constVEC const samples = sound -> z.row (1);
+ result.row (ipattern) <<= samples. part (startSample, endSample);
+ }
+ return result;
+ } catch (MelderError) {
+ Melder_throw (me, U": no randomize patterns gotten.");
+ }
+}
+
+void SoundSet_Table_getRandomizedPatterns (SoundSet me, Table thee, conststring32 columnName, integer numberOfPatterns, integer inputSize, integer outputSize,
+ autoPatternList *out_inputs, autoPatternList *out_outputs)
+{
+ try {
+ Melder_require (thy rows.size == my size,
+ U"The number of rows of ", thee, U" should be equal to the number of elements of ", me);
+ integer columnNumber = Table_getColumnIndexFromColumnLabel (thee, columnName);
+ integer minimumNumberOfSamples = SoundSet_getMinimumNumberOfSamples (me);
+ Melder_require (inputSize <= minimumNumberOfSamples,
+ U"The input size cannot be ", inputSize, U", because there is a Sound that is only ", minimumNumberOfSamples, U" samples long.");
+ Table_numericize_Assert (thee, columnNumber);
+ autoPatternList inputs = PatternList_create (numberOfPatterns, inputSize);
+ autoPatternList outputs = PatternList_create (numberOfPatterns, outputSize);
+ for (integer ipattern = 1; ipattern <= numberOfPatterns; ipattern ++) {
+ integer soundNumber = NUMrandomInteger (1, my size);
+ Sound sound = my at [soundNumber];
+ integer numberOfSamples = sound -> nx;
+ integer endSample = NUMrandomInteger (inputSize, numberOfSamples);
+ integer startSample = endSample - (inputSize - 1);
+ Melder_assert (startSample >= 1);
+ constVEC const samples = sound -> z.row (1);
+ inputs -> z.row (ipattern) <<= samples. part (startSample, endSample);
+ integer classNumber = Melder_iround (thy rows.at [soundNumber] -> cells [columnNumber]. number);
+ Melder_require (classNumber >= 1 && classNumber <= outputSize,
+ U"The class number has to be betwene 1 and ", outputSize, U", not ", classNumber, U".");
+ outputs -> z [ipattern] [classNumber] = 1.0;
+ }
+ if (out_inputs) *out_inputs = inputs.move();
+ if (out_outputs) *out_outputs = outputs.move();
+ } catch (MelderError) {
+ Melder_throw (me, U" and ", thee, U": no randomized patterns gotten.");
+ }
+}
+
+/* End of file SoundSet.cpp */
=====================================
fon/SoundSet.h
=====================================
@@ -0,0 +1,37 @@
+#ifndef _SoundSet_h_
+#define _SoundSet_h_
+/* SoundSet.h
+ *
+ * Copyright (C) 2019 Paul Boersma
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Sound.h"
+#include "Table.h"
+#include "PatternList.h"
+
+/*
+ Abstract.
+*/
+Collection_define (SoundSet, OrderedOf, Sound) {
+};
+
+integer SoundSet_getMinimumNumberOfSamples (SoundSet me);
+autoMAT SoundSet_getRandomizedPatterns (SoundSet me, integer numberOfPatterns, integer patternSize);
+void SoundSet_Table_getRandomizedPatterns (SoundSet me, Table thee, conststring32 columnName, integer numberOfPatterns, integer inputSize, integer outputSize,
+ autoPatternList *out_inputs, autoPatternList *out_outputs);
+
+/* End of file Sound.h */
+#endif
=====================================
fon/manual_tutorials.cpp
=====================================
@@ -22,9 +22,14 @@
void manual_tutorials_init (ManPages me);
void manual_tutorials_init (ManPages me) {
-MAN_BEGIN (U"What's new?", U"ppgb", 20190217)
+MAN_BEGIN (U"What's new?", U"ppgb", 20190302)
INTRO (U"Latest changes in Praat.")
//LIST_ITEM (U"• Manual page about @@drawing a vowel triangle at .")
+NORMAL (U"##6.0.49# (2 March 2019)")
+LIST_ITEM (U"• Removed a bug introduced in 6.0.41 whereby a script could misreport an undefined table value.")
+LIST_ITEM (U"• Removed a bug introduced in 6.0.44 whereby an MFCC's maximum frequency could be ignored.")
+LIST_ITEM (U"• Pitch: Tabulate candidates.")
+LIST_ITEM (U"• SoundSet.")
NORMAL (U"##6.0.48# (17 February 2019)")
LIST_ITEM (U"• Removed a bug introduced in 6.0.44 whereby Praat could crash when drawing a function without any points.")
LIST_ITEM (U"• Removed a bug whereby Praat would not start up on macOS 10.10 (because of required GPU libraries).")
=====================================
fon/praat_Fon.cpp
=====================================
@@ -1559,6 +1559,21 @@ DO
NUMMAT_ONE_END
}
+FORM (NEW_Pitch_tabulateCandidatesInFrame, U"Pitch: Tabulate candidates in frame", nullptr) {
+ NATURAL (frameNumber, U"Frame number", U"1")
+ OK
+DO
+ CONVERT_EACH (Pitch)
+ autoTable result = Pitch_tabulateCandidatesInFrame (me, frameNumber);
+ CONVERT_EACH_END (my name.get(), U"_", frameNumber)
+}
+
+DIRECT (NEW_Pitch_tabulateCandidates) {
+ CONVERT_EACH (Pitch)
+ autoTable result = Pitch_tabulateCandidates (me);
+ CONVERT_EACH_END (my name.get())
+}
+
FORM (REAL_Pitch_getMinimum, U"Pitch: Get minimum", nullptr) {
praat_TimeFunction_RANGE (fromTime, toTime)
OPTIONMENU_ENUM (kPitch_unit, unit, U"Unit", kPitch_unit::DEFAULT)
@@ -3211,6 +3226,8 @@ praat_addAction1 (classFormant, 0, U"Hack", nullptr, 0, nullptr);
praat_addAction1 (classPitch, 2, U"Count differences", nullptr, 1, INFO_Pitch_difference);
praat_addAction1 (classPitch, 2, U"-- hack --", nullptr, 1, nullptr);
praat_addAction1 (classPitch, 1, U"Internal", nullptr, 1, nullptr);
+ praat_addAction1 (classPitch, 0, U"Tabulate candidates", nullptr, 2, NEW_Pitch_tabulateCandidates);
+ praat_addAction1 (classPitch, 0, U"Tabulate candidates in frame...", nullptr, 2, NEW_Pitch_tabulateCandidatesInFrame);
praat_addAction1 (classPitch, 1, U"Get all candidates in frame...", nullptr, 2, NUMMAT_Pitch_getAllCandidatesInFrame);
praat_addAction1 (classPitch, 0, U"Modify -", nullptr, 0, nullptr);
praat_TimeFunction_modify_init (classPitch);
=====================================
fon/praat_Matrix.cpp
=====================================
@@ -355,6 +355,23 @@ DIRECT (REAL_Matrix_getSum) {
NUMBER_ONE_END (U" (sum)");
}
+DIRECT (NUMMAT_Matrix_getAllValues) {
+ NUMMAT_ONE (Matrix)
+ autoMAT result = newMATcopy (my z.all());
+ NUMMAT_ONE_END
+}
+
+FORM (NUMVEC_Matrix_getAllValuesInRow, U"Get all values in row", nullptr) {
+ NATURAL (rowNumber, U"Row number", U"1")
+ OK
+DO
+ NUMVEC_ONE (Matrix)
+ Melder_require (rowNumber <= my ny,
+ U"The row number (", rowNumber, U") should not be greater than the number of rows (", my ny, U").");
+ autoVEC result = newVECcopy (my z.row (rowNumber));
+ NUMVEC_ONE_END
+}
+
// MARK: Modify
FORM (MODIFY_Matrix_formula, U"Matrix Formula", U"Formula...") {
@@ -829,6 +846,8 @@ void praat_Matrix_init () {
praat_addAction1 (classMatrix, 1, U"-- get value --", nullptr, 1, nullptr);
praat_addAction1 (classMatrix, 1, U"Get value in cell...", nullptr, 1, REAL_Matrix_getValueInCell);
praat_addAction1 (classMatrix, 1, U"Get value at xy...", nullptr, 1, REAL_Matrix_getValueAtXY);
+ praat_addAction1 (classMatrix, 1, U"Get all values", nullptr, 1, NUMMAT_Matrix_getAllValues);
+ praat_addAction1 (classMatrix, 1, U"Get all values in row...", nullptr, 1, NUMVEC_Matrix_getAllValuesInRow);
praat_addAction1 (classMatrix, 1, U"Get minimum", nullptr, 1, REAL_Matrix_getMinimum);
praat_addAction1 (classMatrix, 1, U"Get maximum", nullptr, 1, REAL_Matrix_getMaximum);
praat_addAction1 (classMatrix, 1, U"Get sum", nullptr, 1, REAL_Matrix_getSum);
=====================================
fon/praat_Sound.cpp
=====================================
@@ -1,6 +1,6 @@
/* praat_Sound_init.cpp
*
- * Copyright (C) 1992-2018 Paul Boersma
+ * Copyright (C) 1992-2019 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
#include "Sound_to_PointProcess.h"
#include "SoundEditor.h"
#include "SoundRecorder.h"
+#include "SoundSet.h"
#include "SpectrumEditor.h"
#include "TextGrid_Sound.h"
#include "mp3.h"
@@ -360,6 +361,14 @@ DIRECT (NEW1_Sounds_combineIntoSoundList) {
autoSoundList result = SoundList_create ();
for (integer iobject = 1; iobject <= list.size; iobject ++)
result -> addItem_move (Data_copy (list.at [iobject]));
+ CONVERT_LIST_END (U"list")
+}
+
+DIRECT (NEW1_Sounds_combineIntoSoundSet) {
+ CONVERT_LIST (Sound)
+ autoSoundSet result = SoundSet_create ();
+ for (integer iobject = 1; iobject <= list.size; iobject ++)
+ result -> addItem_move (Data_copy (list.at [iobject]));
CONVERT_LIST_END (U"ensemble")
}
@@ -2000,13 +2009,38 @@ FORM_SAVE (SAVE_Sound_saveAsWavFile, U"Save as WAV file", nullptr, U"wav") {
/***** SOUNDLIST *****/
-DIRECT (NEWMANY_Extract_all_Sounds) {
+DIRECT (NEWMANY_SoundList_extractAllSounds) {
CONVERT_EACH (SoundList)
autoSoundList result = Data_copy (me);
result -> classInfo = classCollection; // YUCK, in order to force automatic unpacking
CONVERT_EACH_END (U"dummy")
}
+/***** SOUNDSET *****/
+
+DIRECT (NEWMANY_SoundSet_extractAllSounds) {
+ CONVERT_EACH (SoundSet)
+ autoSoundSet result = Data_copy (me);
+ result -> classInfo = classCollection; // YUCK, in order to force automatic unpacking
+ CONVERT_EACH_END (U"dummy")
+}
+
+FORM (NEW2_SoundSet_Table_getRandomizedPatterns, U"SoundSet & Table: Get randomized patterns", nullptr) {
+ SENTENCE (columnName, U"Column name", U"")
+ NATURAL (numberOfPatterns, U"Number of patterns", U"1000")
+ NATURAL (inputSize, U"Input size (number of samples)", U"8000")
+ NATURAL (outputSize, U"Output size (number of classes)", U"5")
+ OK
+DO
+ FIND_TWO (SoundSet, Table)
+ autoPatternList inputs, outputs;
+ SoundSet_Table_getRandomizedPatterns (me, you, columnName, numberOfPatterns, inputSize, outputSize,
+ & inputs, & outputs);
+ praat_new (inputs.move(), U"inputs");
+ praat_new (outputs.move(), U"outputs");
+ END
+}
+
/***** STOP *****/
DIRECT (PLAY_stopPlayingSound) {
@@ -2112,7 +2146,7 @@ static int publishPlayedProc () {
/***** buttons *****/
void praat_Sound_init () {
- Thing_recognizeClassesByName (classSound, classLongSound, classSoundList, nullptr);
+ Thing_recognizeClassesByName (classSound, classLongSound, classSoundList, classSoundSet, nullptr);
Data_recognizeFileType (macSoundOrEmptyFileRecognizer);
Data_recognizeFileType (soundFileRecognizer);
@@ -2407,6 +2441,7 @@ void praat_Sound_init () {
praat_addAction1 (classSound, 0, U"Combine -", nullptr, 0, nullptr);
praat_addAction1 (classSound, 0, U"Combine to stereo", nullptr, 1, NEW1_Sounds_combineToStereo);
praat_addAction1 (classSound, 0, U"Combine into SoundList", nullptr, 1, NEW1_Sounds_combineIntoSoundList);
+ praat_addAction1 (classSound, 0, U"Combine into SoundSet", nullptr, 1, NEW1_Sounds_combineIntoSoundSet);
praat_addAction1 (classSound, 0, U"Concatenate", nullptr, 1, NEW1_Sounds_concatenate);
praat_addAction1 (classSound, 0, U"Concatenate recoverably", nullptr, 1, NEW2_Sounds_concatenateRecoverably);
praat_addAction1 (classSound, 0, U"Concatenate with overlap...", nullptr, 1, NEW1_Sounds_concatenateWithOverlap);
@@ -2428,7 +2463,10 @@ void praat_Sound_init () {
praat_addAction2 (classLongSound, 0, classSound, 0, U"Save as FLAC file...", nullptr, 0, SAVE_LongSound_Sound_saveAsFlacFile);
praat_addAction2 (classLongSound, 0, classSound, 0, U"Write to FLAC file...", U"*Save as FLAC file...", praat_DEPRECATED_2011, SAVE_LongSound_Sound_saveAsFlacFile);
- praat_addAction1 (classSoundList, 1, U"Extract all Sounds", nullptr, 0, NEWMANY_Extract_all_Sounds);
+ praat_addAction1 (classSoundList, 1, U"Extract all Sounds", nullptr, 0, NEWMANY_SoundList_extractAllSounds);
+
+ praat_addAction1 (classSoundSet, 1, U"Extract all Sounds", nullptr, 0, NEWMANY_SoundSet_extractAllSounds);
+ praat_addAction2 (classSoundSet, 1, classTable, 1, U"Get randomized patterns...", nullptr, 0, NEW2_SoundSet_Table_getRandomizedPatterns);
}
/* End of file praat_Sound.cpp */
=====================================
main/praat.plist
=====================================
@@ -492,6 +492,18 @@
<key>LSTypeIsPackage</key>
<integer>0</integer>
</dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>SoundSet</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Praat Sound set</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSTypeIsPackage</key>
+ <integer>0</integer>
+ </dict>
</array>
<key>CFBundleExecutable</key>
<string>Praat</string>
=====================================
melder/MAT.h
=====================================
@@ -138,6 +138,44 @@ inline autoMAT newMATmultiply (constMATVU const& x, double number) {
return result;
}
+struct TypeMATadd_MAT_VEC { constMATVU const& x; constVECVU const& y; };
+inline TypeMATadd_MAT_VEC operator+ (constMATVU const& x, constVECVU const& y) { return { x, y }; }
+#define GENERATE_ONE_TENSOR_FUNCTION(operator, op) \
+ inline void operator (MATVU const& target, TypeMATadd_MAT_VEC const& expr) noexcept { \
+ Melder_assert (expr.x.nrow == target.nrow); \
+ Melder_assert (expr.x.ncol == target.ncol); \
+ Melder_assert (expr.x.ncol == expr.y.size); \
+ for (integer irow = 1; irow <= expr.x.nrow; irow ++) \
+ for (integer icol = 1; icol <= expr.x.ncol; icol ++) \
+ target [irow] [icol] op expr.x [irow] [icol] + expr.y [icol]; \
+ }
+GENERATE_FIVE_TENSOR_FUNCTIONS
+#undef GENERATE_ONE_TENSOR_FUNCTION
+inline autoMAT newMATadd (constMATVU const& x, constVECVU const& y) {
+ autoMAT result = newMATraw (x.nrow, x.ncol);
+ result.all() <<= x + y;
+ return result;
+}
+
+struct TypeMATmultiply_MAT_VEC { constMATVU const& x; constVECVU const& y; };
+inline TypeMATmultiply_MAT_VEC operator* (constMATVU const& x, constVECVU const& y) { return { x, y }; }
+#define GENERATE_ONE_TENSOR_FUNCTION(operator, op) \
+ inline void operator (MATVU const& target, TypeMATmultiply_MAT_VEC const& expr) noexcept { \
+ Melder_assert (expr.x.nrow == target.nrow); \
+ Melder_assert (expr.x.ncol == target.ncol); \
+ Melder_assert (expr.x.ncol == expr.y.size); \
+ for (integer irow = 1; irow <= expr.x.nrow; irow ++) \
+ for (integer icol = 1; icol <= expr.x.ncol; icol ++) \
+ target [irow] [icol] op expr.x [irow] [icol] * expr.y [icol]; \
+ }
+GENERATE_FIVE_TENSOR_FUNCTIONS
+#undef GENERATE_ONE_TENSOR_FUNCTION
+inline autoMAT newMATmultiply (constMATVU const& x, constVECVU const& y) {
+ autoMAT result = newMATraw (x.nrow, x.ncol);
+ result.all() <<= x * y;
+ return result;
+}
+
struct TypeMATadd_MAT_MAT { constMATVU const& x; constMATVU const& y; };
inline TypeMATadd_MAT_MAT operator+ (constMATVU const& x, constMATVU const& y) { return { x, y }; }
#define GENERATE_ONE_TENSOR_FUNCTION(operator, op) \
@@ -178,6 +216,26 @@ inline autoMAT newMATsubtract (constMATVU const& x, constMATVU const& y) {
return result;
}
+struct TypeMATmultiply_MAT_MAT { constMATVU const& x; constMATVU const& y; };
+inline TypeMATmultiply_MAT_MAT operator* (constMATVU const& x, constMATVU const& y) { return { x, y }; }
+#define GENERATE_ONE_TENSOR_FUNCTION(operator, op) \
+ inline void operator (MATVU const& target, TypeMATmultiply_MAT_MAT const& expr) noexcept { \
+ Melder_assert (expr.x.nrow == target.nrow); \
+ Melder_assert (expr.x.ncol == target.ncol); \
+ Melder_assert (expr.x.nrow == expr.y.nrow); \
+ Melder_assert (expr.x.ncol == expr.y.ncol); \
+ for (integer irow = 1; irow <= expr.x.nrow; irow ++) \
+ for (integer icol = 1; icol <= expr.x.ncol; icol ++) \
+ target [irow] [icol] op expr.x [irow] [icol] * expr.y [irow] [icol]; \
+ }
+GENERATE_FIVE_TENSOR_FUNCTIONS
+#undef GENERATE_ONE_TENSOR_FUNCTION
+inline autoMAT newMATmultiply (constMATVU const& x, constMATVU const& y) {
+ autoMAT result = newMATraw (x.nrow, x.ncol);
+ result.all() <<= x * y;
+ return result;
+}
+
/*
Make the average of each column zero.
a[i][j] -= a[.][j]
=====================================
melder/MelderString.h
=====================================
@@ -2,7 +2,7 @@
#define _melder_string_h_
/* MelderString.h
*
- * Copyright (C) 1992-2018 Paul Boersma
+ * Copyright (C) 1992-2019 Paul Boersma
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,9 +18,14 @@
* along with this work. If not, see <http://www.gnu.org/licenses/>.
*/
-/********** STRINGS **********/
-
-/* These are functions for never having to check string boundaries again. */
+/*
+ Strings that:
+ - are null-terminated
+ - have O(1) access to their length
+ - grow as needed
+ - can be appended to without scanning for the final null character
+ - automatically convert numbers, objects, file names, vectors, and matrices to strings
+*/
typedef struct {
int64 length;
@@ -30,7 +35,7 @@ typedef struct {
typedef struct {
int64 length;
int64 bufferSize;
- char32 *string; // a growing buffer, rarely shrunk (can only be freed by MelderString32_free)
+ char32 *string; // a growing buffer, rarely shrunk (can only be freed by MelderString_free)
} MelderString;
void MelderString16_free (MelderString16 *me); // frees the buffer (and sets other attributes to zero)
@@ -42,8 +47,14 @@ void MelderString_ncopy (MelderString *me, conststring32 source, int64 n);
inline static void _recursiveTemplate_MelderString_append (MelderString *me, const MelderArg& arg) {
if (arg._arg) {
- const char32 *newEndOfStringLocation = stp32cpy (& my string [my length], arg._arg);
+ const char32 *newEndOfStringLocation = stp32cpy (& my string [my length], arg._arg); // this will append a null character
my length = newEndOfStringLocation - & my string [0];
+ } else {
+ /*
+ Append a null string: do nothing.
+ The result will be null-terminated if `me` was null-terminated to start with,
+ which is a required invariant.
+ */
}
}
template <typename... Args>
@@ -70,6 +81,7 @@ void MelderString_copy (MelderString *me, const MelderArg& first, Args... rest)
if (sizeNeeded > my bufferSize)
MelderString_expand (me, sizeNeeded);
my length = 0;
+ my string [0] = U'\0'; // maintain invariant
_recursiveTemplate_MelderString_append (me, first, rest...);
}
=====================================
melder/melder_strings.cpp
=====================================
@@ -111,7 +111,7 @@ void MelderString_empty (MelderString *me) {
}
int64 sizeNeeded = 1;
if (sizeNeeded > my bufferSize) MelderString_expand (me, sizeNeeded);
- my string [0] = '\0';
+ my string [0] = U'\0';
my length = 0;
}
@@ -124,7 +124,7 @@ void MelderString_ncopy (MelderString *me, conststring32 source, int64 n) {
int64 sizeNeeded = length + 1;
if (sizeNeeded > my bufferSize) MelderString_expand (me, sizeNeeded);
str32ncpy (my string, source, length);
- my string [length] = '\0';
+ my string [length] = U'\0';
my length = length;
}
=====================================
sys/Formula.cpp
=====================================
@@ -89,14 +89,15 @@ enum { NO_SYMBOL_,
/* Functions of 1 variable; if you add, update the #defines. */
#define LOW_FUNCTION_1 ABS_
ABS_, ROUND_, FLOOR_, CEILING_,
- RECTIFY_, VEC_RECTIFY_,
+ RECTIFY_, RECTIFY_H_, RECTIFY_HH_,
SQRT_, SIN_, COS_, TAN_, ARCSIN_, ARCCOS_, ARCTAN_, SINC_, SINCPI_,
EXP_, VEC_EXP_, MAT_EXP_,
SINH_, COSH_, TANH_, ARCSINH_, ARCCOSH_, ARCTANH_,
- SIGMOID_, VEC_SIGMOID_, VEC_SOFTMAX_,
+ SIGMOID_, VEC_SIGMOID_, SOFTMAX_H_, SOFTMAX_PER_ROW_HH_,
INV_SIGMOID_, ERF_, ERFC_, GAUSS_P_, GAUSS_Q_, INV_GAUSS_Q_,
RANDOM_BERNOULLI_, VEC_RANDOM_BERNOULLI_,
RANDOM_POISSON_, MAT_TRANSPOSE_,
+ SUM_PER_ROW_H_, SUM_PER_COLUMN_H_,
LOG2_, LN_, 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_,
@@ -218,14 +219,15 @@ static const conststring32 Formula_instructionNames [1 + highestSymbol] = { U"",
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"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"arcsinh", U"arccosh", U"arctanh",
- U"sigmoid", U"sigmoid#", U"softmax#",
+ 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"sumPerRow#", U"sumPerColumn#",
U"log2", U"ln", U"log10", U"lnGamma",
U"hertzToBark", U"barkToHertz", U"phonToDifferenceLimens", U"differenceLimensToPhon",
U"hertzToMel", U"melToHertz", U"hertzToSemitones", U"semitonesToHertz",
@@ -2638,6 +2640,26 @@ static void do_add () {
//x->which = Stackel_NUMERIC_MATRIX;
return;
}
+ if (y->which == Stackel_NUMERIC_VECTOR) {
+ /*
+ result## = x## + y#
+ i.e.
+ result## [i, j] = x## [i, j] + y# [j]
+ */
+ integer xnrow = x->numericMatrix.nrow, xncol = x->numericMatrix.ncol;
+ integer ysize = y->numericVector.size;
+ if (xncol != ysize)
+ Melder_throw (U"When adding a vector to a matrix, its size should be equal to the number of columns, instead of ", ysize, U" and ", xncol, U".");
+ if (x->owned) {
+ x->numericMatrix += y->numericVector;
+ } else {
+ // x does not have to be cleaned up, because it was not owned
+ x->numericMatrix = newMATadd (x->numericMatrix, y->numericVector). releaseToAmbiguousOwner();
+ x->owned = true;
+ }
+ //x->which = Stackel_NUMERIC_MATRIX;
+ return;
+ }
if (y->which == Stackel_NUMBER) {
/*
result## = x## + y
@@ -2800,15 +2822,20 @@ static void do_mul () {
/*
result.. = x.. * y..
*/
- Stackel y = pop, x = pop;
+ Stackel y = pop, x = topOfStack;
if (x->which == Stackel_NUMBER) {
- double xvalue = x->number;
if (y->which == Stackel_NUMBER) {
- /*
+ /*@praat
+ #
+ # result = x * y
+ #
+ x = 5
+ y = 6
result = x * y
- */
- double yvalue = y->number;
- pushNumber (xvalue * yvalue);
+ assert result = 30
+ @*/
+ x->number *= y->number;
+ //x->which = Stackel_NUMBER; // superfluous, as is cleaning up
return;
}
if (y->which == Stackel_NUMERIC_VECTOR) {
@@ -2816,19 +2843,30 @@ static void do_mul () {
result# = x * y#
*/
if (y->owned) {
- y->numericVector *= xvalue;
- x->which = Stackel_NUMERIC_VECTOR;
+ /*@praat
+ #
+ # result# = x * owned y#
+ #
+ result# = 5 * { 11, 13, 31 } ; numeric vector literals are owned
+ assert result# = { 55, 65, 155 }
+ @*/
+ y->numericVector *= x->number;
+ // x does not have to be cleaned up, because it was a number
moveNumericVector (y, x);
- w ++;
} else {
- integer ny = y->numericVector.size;
- autoVEC result { ny, kTensorInitializationType::RAW };
- for (integer i = 1; i <= ny; i ++) {
- double yvalue = y->numericVector [i];
- result [i] = xvalue * yvalue;
- }
- pushNumericVector (result.move());
+ /*@praat
+ #
+ # result# = x * unowned y#
+ #
+ y# = { 17, -11, 29 }
+ result# = 30 * y# ; numeric vector variables are not owned
+ assert result# = { 510, -330, 870 }
+ @*/
+ // x does not have to be cleaned up, because it was a number
+ x->numericVector = newVECmultiply (y->numericVector, x->number). releaseToAmbiguousOwner();
+ x->owned = true;
}
+ x->which = Stackel_NUMERIC_VECTOR;
return;
}
if (y->which == Stackel_NUMERIC_MATRIX) {
@@ -2836,39 +2874,159 @@ static void do_mul () {
result## = x * y##
*/
if (y->owned) {
- y->numericMatrix *= xvalue;
- x->which = Stackel_NUMERIC_MATRIX;
+ y->numericMatrix *= x->number;
+ // x does not have to be cleaned up, because it was a number
moveNumericMatrix (y, x);
- w ++;
} else {
- integer nrow = y->numericMatrix.nrow, ncol = y->numericMatrix.ncol;
- autoMAT result (nrow, ncol, kTensorInitializationType::RAW);
- for (integer irow = 1; irow <= nrow; irow ++) {
- for (integer icol = 1; icol <= ncol; icol ++) {
- double yvalue = y->numericMatrix [irow] [icol];
- result [irow] [icol] = xvalue * yvalue;
- }
- }
- pushNumericMatrix (result.move());
+ // x does not have to be cleaned up, because it was a number
+ x->numericMatrix = newMATmultiply (y->numericMatrix, x->number). releaseToAmbiguousOwner();
+ x->owned = true;
}
+ x->which = Stackel_NUMERIC_MATRIX;
return;
}
}
- if (x->which == Stackel_NUMERIC_VECTOR && y->which == Stackel_NUMERIC_VECTOR) {
- /*
- result# = x# * y#
- */
- integer nx = x->numericVector.size, ny = y->numericVector.size;
- if (nx != ny)
- Melder_throw (U"When multiplying vectors, their numbers of elements should be equal, instead of ", nx, U" and ", ny, U".");
- autoVEC result { nx, kTensorInitializationType::RAW };
- for (integer i = 1; i <= nx; i ++) {
- double xvalue = x->numericVector [i];
- double yvalue = y->numericVector [i];
- result [i] = xvalue * yvalue;
+ if (x->which == Stackel_NUMERIC_VECTOR) {
+ if (y->which == Stackel_NUMERIC_VECTOR) {
+ /*
+ result# = x# * y#
+ i.e.
+ result# [i] = x# [i] * y# [i]
+ */
+ integer nx = x->numericVector.size, ny = y->numericVector.size;
+ if (nx != ny) {
+ /*@praat
+ #
+ # Error: unequal sizes.
+ #
+ x# = { 11, 13, 17 }
+ y# = { 8, 90 }
+ asserterror When multiplying vectors, their numbers of elements should be equal, instead of 3 and 2.
+ result# = x# + y#
+ @*/
+ Melder_throw (U"When multiplying vectors, their numbers of elements should be equal, instead of ", nx, U" and ", ny, U".");
+ }
+ if (x -> owned) {
+ /*@praat
+ #
+ # result# = owned x# * y#
+ #
+ result# = { 11, 13, 17 } * { 44, 56, 67 } ; owned + owned
+ assert result# = { 484, 728, 1139 }
+ y# = { 3, 2, 89.5 }
+ result# = { 11, 13, 17 } * y# ; owned * unowned
+ assert result# = { 33, 26, 1521.5 }
+ @*/
+ x->numericVector *= y->numericVector;
+ } else if (y -> owned) {
+ /*@praat
+ #
+ # result# = unowned x# * owned y#
+ #
+ x# = { 14, -3, 6.25 }
+ result# = x# * { 55, 1, -89 }
+ assert result# = { 770, -3, -556.25 }
+ @*/
+ y->numericVector *= x->numericVector;
+ // x does not have to be cleaned up, because it was not owned
+ moveNumericVector (y, x);
+ } else {
+ /*@praat
+ #
+ # result# = unowned x# * unowned y#
+ #
+ x# = { 14, -33, 6.25 }
+ y# = { -33, 17, 9 }
+ result# = x# * y#
+ assert result# = { -462, -561, 56.25 }
+ @*/
+ // x does not have to be cleaned up, because it was not owned
+ x->numericVector = newVECmultiply (x->numericVector, y->numericVector). releaseToAmbiguousOwner();
+ x->owned = true;
+ }
+ //x->which = Stackel_NUMERIC_VECTOR; // superfluous
+ return;
+ }
+ if (y->which == Stackel_NUMBER) {
+ /*
+ result# = x# * y
+ i.e.
+ result# [i] = x# [i] * y
+ */
+ if (x->owned) {
+ x->numericVector *= y->number;
+ } else {
+ // x does not have to be cleaned up, because it was not owned
+ x->numericVector = newVECmultiply (x->numericVector, y->number). releaseToAmbiguousOwner();
+ x->owned = true;
+ }
+ //x->which = Stackel_NUMERIC_VECTOR; // superfluous
+ return;
+ }
+ }
+ if (x->which == Stackel_NUMERIC_MATRIX) {
+ if (y->which == Stackel_NUMERIC_MATRIX) {
+ /*
+ result## = x## * y##
+ i.e.
+ result## [i, j] = x## [i, j] * y## [i, j]
+ */
+ integer xnrow = x->numericMatrix.nrow, xncol = x->numericMatrix.ncol;
+ integer ynrow = y->numericMatrix.nrow, yncol = y->numericMatrix.ncol;
+ if (xnrow != ynrow)
+ Melder_throw (U"When multiplying matrices, their numbers of rows should be equal, instead of ", xnrow, U" and ", ynrow, U".");
+ if (xncol != yncol)
+ Melder_throw (U"When multiplying matrices, their numbers of columns should be equal, instead of ", xncol, U" and ", yncol, U".");
+ if (x->owned) {
+ x->numericMatrix *= y->numericMatrix;
+ } else if (y->owned) {
+ y->numericMatrix *= x->numericMatrix;
+ // x does not have to be cleaned up, because it was not owned
+ moveNumericMatrix (y, x);
+ } else {
+ // x does not have to be cleaned up, because it was not owned
+ x->numericMatrix = newMATmultiply (x->numericMatrix, y->numericMatrix). releaseToAmbiguousOwner();
+ x->owned = true;
+ }
+ //x->which = Stackel_NUMERIC_MATRIX;
+ return;
+ }
+ if (y->which == Stackel_NUMERIC_VECTOR) {
+ /*
+ result## = x## * y#
+ i.e.
+ result## [i, j] = x## [i, j] * y# [j]
+ */
+ integer xnrow = x->numericMatrix.nrow, xncol = x->numericMatrix.ncol;
+ integer ysize = y->numericVector.size;
+ if (xncol != ysize)
+ Melder_throw (U"When multiplying a matrix with a vector, the vector’s size should be equal to the matrix’s number of columns, instead of ", ysize, U" and ", xncol, U".");
+ if (x->owned) {
+ x->numericMatrix *= y->numericVector;
+ } else {
+ // x does not have to be cleaned up, because it was not owned
+ x->numericMatrix = newMATmultiply (x->numericMatrix, y->numericVector). releaseToAmbiguousOwner();
+ x->owned = true;
+ }
+ //x->which = Stackel_NUMERIC_MATRIX;
+ return;
+ }
+ if (y->which == Stackel_NUMBER) {
+ /*
+ result## = x## * y
+ i.e.
+ result## [i, j] = x## [i, j] * y
+ */
+ if (x->owned) {
+ x->numericMatrix *= y->number;
+ } else {
+ // x does not have to be cleaned up, because it was not owned
+ x->numericMatrix = newMATmultiply (x->numericMatrix, y->number). releaseToAmbiguousOwner();
+ x->owned = true;
+ }
+ //x->which = Stackel_NUMERIC_MATRIX; // superfluous
+ return;
}
- pushNumericVector (result.move());
- return;
}
Melder_throw (U"Cannot multiply (*) ", x->whichText(), U" by ", y->whichText(), U".");
}
@@ -2979,7 +3137,7 @@ static void do_functionvec_n_n (double (*f) (double)) {
U" requires a numeric vector argument, not ", x->whichText(), U".");
}
}
-static void do_softmax () {
+static void do_softmaxH () {
Stackel x = topOfStack;
if (x->which == Stackel_NUMERIC_VECTOR) {
if (! x->owned) {
@@ -3006,6 +3164,35 @@ static void do_softmax () {
U" requires a numeric vector argument, not ", x->whichText(), U".");
}
}
+static void do_softmaxPerRowHH () {
+ Stackel x = topOfStack;
+ if (x->which == Stackel_NUMERIC_MATRIX) {
+ if (! x->owned) {
+ x->numericMatrix = newMATcopy (x->numericMatrix). releaseToAmbiguousOwner(); // TODO: no need to copy
+ x->owned = true;
+ }
+ integer nrow = x->numericMatrix.nrow, ncol = x->numericMatrix.ncol;
+ for (integer irow = 1; irow <= nrow; irow ++) {
+ double maximum = -1e308;
+ for (integer icol = 1; icol <= ncol; icol ++) {
+ if (x->numericMatrix [irow] [icol] > maximum)
+ maximum = x->numericMatrix [irow] [icol];
+ }
+ for (integer icol = 1; icol <= ncol; icol ++)
+ x->numericMatrix [irow] [icol] -= maximum;
+ longdouble sum = 0.0;
+ for (integer icol = 1; icol <= ncol; icol ++) {
+ x->numericMatrix [irow] [icol] = exp (x->numericMatrix [irow] [icol]);
+ sum += x->numericMatrix [irow] [icol];
+ }
+ for (integer icol = 1; icol <= ncol; icol ++)
+ x->numericMatrix [irow] [icol] /= (double) sum;
+ }
+ } else {
+ Melder_throw (U"The function ", Formula_instructionNames [parse [programPointer]. symbol],
+ U" requires a numeric matrix argument, not ", x->whichText(), U".");
+ }
+}
static void do_abs () {
Stackel x = pop;
if (x->which == Stackel_NUMBER) {
@@ -3046,7 +3233,7 @@ static void do_rectify () {
Melder_throw (U"Cannot rectify ", x->whichText(), U".");
}
}
-static void do_VECrectify () {
+static void do_rectifyH () {
Stackel x = pop;
if (x->which == Stackel_NUMERIC_VECTOR) {
integer nelm = x->numericVector.size;
@@ -3060,6 +3247,33 @@ static void do_VECrectify () {
Melder_throw (U"Cannot rectify ", x->whichText(), U".");
}
}
+static void do_rectifyHH () {
+ 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 = newMATraw (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) {
@@ -3210,6 +3424,8 @@ static void do_sum () {
Stackel x = pop;
if (x->which == Stackel_NUMERIC_VECTOR) {
pushNumber (NUMsum (x->numericVector));
+ } else if (x->which == Stackel_NUMERIC_MATRIX) {
+ pushNumber (NUMsum (x->numericMatrix));
} else {
Melder_throw (U"Cannot compute the sum of ", x->whichText(), U".");
}
@@ -3218,6 +3434,8 @@ static void do_mean () {
Stackel x = pop;
if (x->which == Stackel_NUMERIC_VECTOR) {
pushNumber (NUMmean (x->numericVector));
+ //} else if (x->which == Stackel_NUMERIC_MATRIX) {
+ // pushNumber (NUMmean (x->numericMatrix));
} else {
Melder_throw (U"Cannot compute the mean of ", x->whichText(), U".");
}
@@ -5107,7 +5325,7 @@ static void do_MATmul_metal () {
MATVUmul_forceMetal_ (result.get(), x->numericMatrix, y->numericMatrix);
pushNumericMatrix (result.move());
} else {
- Melder_throw (U"The function \"mul##\" requires two matrices, not ", x->whichText(), U" and ", y->whichText(), U".");
+ Melder_throw (U"The function \"mul_metal##\" requires two matrices, not ", x->whichText(), U" and ", y->whichText(), U".");
}
}
static void do_MATmul_fast () {
@@ -5200,6 +5418,24 @@ static void do_MATtranspose () {
Melder_throw (U"The function \"transpose##\" requires a matrix, not ", x->whichText(), U".");
}
}
+static void do_sumPerRowH () {
+ Stackel x = pop;
+ if (x->which == Stackel_NUMERIC_MATRIX) {
+ autoVEC result = newVECsumPerRow (x->numericMatrix);
+ pushNumericVector (result.move());
+ } else {
+ Melder_throw (U"The function \"sumPerRow#\" requires a matrix, not ", x->whichText(), U".");
+ }
+}
+static void do_sumPerColumnH () {
+ Stackel x = pop;
+ if (x->which == Stackel_NUMERIC_MATRIX) {
+ autoVEC result = newVECsumPerColumn (x->numericMatrix);
+ pushNumericVector (result.move());
+ } else {
+ Melder_throw (U"The function \"sumPerColumn#\" requires a matrix, not ", x->whichText(), U".");
+ }
+}
static void do_VECrepeat () {
Stackel n = pop, x = pop;
if (x->which == Stackel_NUMERIC_VECTOR && n->which == Stackel_NUMBER) {
@@ -6299,7 +6535,8 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
} break; case FLOOR_: { do_floor ();
} break; case CEILING_: { do_ceiling ();
} break; case RECTIFY_: { do_rectify ();
-} break; case VEC_RECTIFY_: { do_VECrectify ();
+} break; case RECTIFY_H_: { do_rectifyH ();
+} break; case RECTIFY_HH_: { do_rectifyHH ();
} break; case SQRT_: { do_sqrt ();
} break; case SIN_: { do_sin ();
} break; case COS_: { do_cos ();
@@ -6320,7 +6557,8 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
} break; case ARCTANH_: { do_function_n_n (NUMarctanh);
} break; case SIGMOID_: { do_function_n_n (NUMsigmoid);
} break; case VEC_SIGMOID_: { do_functionvec_n_n (NUMsigmoid);
-} break; case VEC_SOFTMAX_: { do_softmax ();
+} break; case SOFTMAX_H_: { do_softmaxH ();
+} break; case SOFTMAX_PER_ROW_HH_: { do_softmaxPerRowHH ();
} break; case INV_SIGMOID_: { do_function_n_n (NUMinvSigmoid);
} break; case ERF_: { do_function_n_n (NUMerf);
} break; case ERFC_: { do_function_n_n (NUMerfcc);
@@ -6331,6 +6569,8 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
} break; case VEC_RANDOM_BERNOULLI_: { do_functionvec_n_n (NUMrandomBernoulli_real);
} break; case RANDOM_POISSON_: { do_function_n_n (NUMrandomPoisson);
} break; case MAT_TRANSPOSE_: { do_MATtranspose ();
+} break; case SUM_PER_ROW_H_: { do_sumPerRowH ();
+} break; case SUM_PER_COLUMN_H_: { do_sumPerColumnH ();
} break; case LOG2_: { do_log2 ();
} break; case LN_: { do_ln ();
} break; case LOG10_: { do_log10 ();
=====================================
sys/praat_version.h
=====================================
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.0.48
-#define PRAAT_VERSION_NUM 6048
+#define PRAAT_VERSION_STR 6.0.49
+#define PRAAT_VERSION_NUM 6049
#define PRAAT_YEAR 2019
-#define PRAAT_MONTH February
-#define PRAAT_DAY 17
+#define PRAAT_MONTH March
+#define PRAAT_DAY 2
=====================================
test/stat/Table_undefined.praat
=====================================
@@ -0,0 +1,6 @@
+Create Table with column names: "table", 1, "speaker"
+;Set string value: 1, "speaker", ""
+a$ = Get value: 1, "speaker"
+assert a$ = "" ; <<'a$'>>
+a = Get value: 1, "speaker"
+assert a = undefined ; 'a'
View it on GitLab: https://salsa.debian.org/med-team/praat/compare/f1500bb1a4da8e593215adea7e3c758a1c8893bd...ca3058bee548e61b0e25fe6fd205305cf0316bb9
--
View it on GitLab: https://salsa.debian.org/med-team/praat/compare/f1500bb1a4da8e593215adea7e3c758a1c8893bd...ca3058bee548e61b0e25fe6fd205305cf0316bb9
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/20190311/7d868dc1/attachment-0001.html>
More information about the debian-med-commit
mailing list