[med-svn] [praat] 01/10: Imported Upstream version 6.0.17
Rafael Laboissière
rlaboiss-guest at moszumanska.debian.org
Mon Jun 13 07:46:27 UTC 2016
This is an automated email from the git hooks/post-receive script.
rlaboiss-guest pushed a commit to branch master
in repository praat.
commit 8932ae14b9aeebbdd3264032163850ebf413919c
Author: Rafael Laboissiere <rafael at laboissiere.net>
Date: Fri May 6 10:07:58 2016 -0300
Imported Upstream version 6.0.17
---
FFNet/FFNet.cpp | 2 +-
LPC/manual_LPC.cpp | 6 +-
dwtools/CC.cpp | 13 +-
dwtools/DTW.cpp | 274 +++++++++++++++++------------
dwtools/DTW.h | 6 +-
dwtools/DTW_and_TextGrid.cpp | 6 +-
dwtools/DTW_def.h | 19 +-
dwtools/Sound_extensions.cpp | 6 +-
dwtools/Spectrogram_extensions.cpp | 2 +-
dwtools/SpeechSynthesizer.cpp | 191 +++++++++++++++-----
dwtools/SpeechSynthesizer_and_TextGrid.cpp | 49 +++---
dwtools/manual_dwtools.cpp | 8 +-
dwtools/praat_David_init.cpp | 100 +++++++----
fon/Pitch_Intensity.cpp | 15 ++
fon/Pitch_Intensity.h | 2 +
fon/TextGrid_Sound.cpp | 55 +++---
fon/TextGrid_def.h | 7 +
fon/manual_Script.cpp | 13 +-
fon/manual_tutorials.cpp | 9 +-
fon/praat_Fon.cpp | 13 ++
main/GNU_General_Public_License.txt | 2 +-
sys/Formula.cpp | 20 ++-
sys/GuiText.cpp | 2 +-
sys/Interpreter.cpp | 23 ++-
sys/abcio.cpp | 58 +++---
sys/praat_version.h | 8 +-
26 files changed, 568 insertions(+), 341 deletions(-)
diff --git a/FFNet/FFNet.cpp b/FFNet/FFNet.cpp
index 4197a68..5296936 100644
--- a/FFNet/FFNet.cpp
+++ b/FFNet/FFNet.cpp
@@ -67,7 +67,7 @@ Thing_implement (FFNet, Daata, 0);
static void FFNet_checkLayerNumber (FFNet me, long layer) {
if (layer < 1 || layer > my nLayers) {
if (layer == 0) {
- Melder_throw (U"A Layer number of 0 is not allowed.");
+ Melder_throw (U"A layer number of 0 is not allowed.");
} else if (layer < 0) {
Melder_throw (U"A negative layer number is not allowed.");
} else if (layer > my nLayers) {
diff --git a/LPC/manual_LPC.cpp b/LPC/manual_LPC.cpp
index 073e8d8..be1fe93 100644
--- a/LPC/manual_LPC.cpp
+++ b/LPC/manual_LPC.cpp
@@ -1,6 +1,6 @@
/* manual_LPC.cpp
*
- * Copyright (C) 1994-2014 David Weenink
+ * Copyright (C) 1994-2016 David Weenink
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -475,10 +475,10 @@ TAG (U"##Use filter at time (s)")
DEFINITION (U"determines which LPC frame will be chosen to inverse filter the sound. ")
MAN_END
-MAN_BEGIN (U"MFCC", U"djmw", 20141022)
+MAN_BEGIN (U"MFCC", U"djmw", 20160225)
INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.")
NORMAL (U"An object of type MFCC represents mel frequency cepstral coefficients "
- "as a function of time. The coefficients are represented in frames "
+ "as a function of time. The coefficients are represented in a number of frames centred at equally spaced times. "
"at constant sampling period.")
ENTRY (U"MFCC commands")
NORMAL (U"Creation:")
diff --git a/dwtools/CC.cpp b/dwtools/CC.cpp
index c5e4750..9ad4500 100644
--- a/dwtools/CC.cpp
+++ b/dwtools/CC.cpp
@@ -76,8 +76,17 @@ void CC_init (CC me, double tmin, double tmax, long nt, double dt, double t1, lo
autoMatrix CC_to_Matrix (CC me) {
try {
- autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, my maximumNumberOfCoefficients, my maximumNumberOfCoefficients, 1.0, 1.0);
-
+ // find number of coefficients by quering all frames.
+ // We cannot use maximumNumberOfCoefficiennts because this number is only used to calculate the inverse
+ long numberOfCoefficients = 0;
+ for (long i = 1; i <= my nx; i++) {
+ CC_Frame cf = & my frame[i];
+ if (cf -> numberOfCoefficients > numberOfCoefficients) {
+ numberOfCoefficients = cf -> numberOfCoefficients;
+ }
+ }
+ autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, numberOfCoefficients, numberOfCoefficients, 1.0, 1.0);
+
for (long i = 1; i <= my nx; i++) {
CC_Frame cf = & my frame[i];
for (long j = 1; j <= cf -> numberOfCoefficients; j++) {
diff --git a/dwtools/DTW.cpp b/dwtools/DTW.cpp
index 1a3fc66..fdc20e4 100644
--- a/dwtools/DTW.cpp
+++ b/dwtools/DTW.cpp
@@ -101,10 +101,10 @@ static void DTW_findPath_special (DTW me, int matchStart, int matchEnd, int slop
/*
The actual path will be interpolated as follows:
The distance matrix has cells of dimensions dx by dy.
- The optimal path connects these cells with one another in the following ways:
+ The optimal path connects these cells with one another in the following way:
In a diagonal ''path'' segment, i.e. when cells have no side in common,
- the interplated path runs from the lowerleft corner to the upperright corner.
+ the interpolated path runs from the lowerleft corner to the upperright corner.
If a path segment is horizontal or vertical the path also runs from lowerleft to upperright.
It is only when a horizontal and a vertical segment have a cell in common that we have to make
some adjustments to the path in the common cell.
@@ -133,46 +133,20 @@ static void DTW_findPath_special (DTW me, int matchStart, int matchEnd, int slop
/* DTW_getXTime (DTW me, (DTW_getYTime (DTW me, double tx)) == tx */
double DTW_getYTimeFromXTime (DTW me, double tx) {
- DTW_Path_Query thee = & my pathQuery;
-
+ // Catch cases where tier would give constant extrapolation
if (tx < my xmin) {
return my ymin - (my xmin - tx);
}
if (tx > my xmax) {
return my ymax + (tx - my xmax);
}
+ DTW_Path_Query thee = & my pathQuery;
+ return RealTier_getValueAtTime(thy yfromx.get(), tx);
- if (! NUMfpp) {
- NUMmachar ();
- }
- double eps = 3 * NUMfpp -> eps;
-
- /* Find in which column is tx */
-
- long ib, ie;
- long ix = (long) floor ( (tx - my x1) / my dx + 1.5);
- if (ix < 1) {
- ib = 1; ie = 2;
- } else if (ix > my nx) {
- ib = thy nxy - 1; ie = thy nxy;
- } else {
- ib = thy xindex[ix].ibegin; ie = thy xindex[ix].iend;
- }
- if (ie - ib > 1) {
- long it = ib + 1;
- while (tx - thy xytimes[it].x > eps) {
- it++;
- }
- ie = it; ib = it - 1;
- }
- double a = (thy xytimes[ib].y - thy xytimes[ie].y) / (thy xytimes[ib].x - thy xytimes[ie].x);
- double b = thy xytimes[ib].y - a * thy xytimes[ib].x;
- return a * tx + b;
}
double DTW_getXTimeFromYTime (DTW me, double ty) {
- DTW_Path_Query thee = & my pathQuery;
-
+ // Catch cases where tier would give constant extrapolation
if (ty < my ymin) {
return my ymin - (my ymin - ty);
}
@@ -180,32 +154,8 @@ double DTW_getXTimeFromYTime (DTW me, double ty) {
return my ymax + (ty - my ymax);
}
- if (! NUMfpp) {
- NUMmachar ();
- }
- double eps = 3 * NUMfpp -> eps;
-
- /* Find in which row is ty */
-
- long ib, ie;
- long iy = (long) floor ( (ty - my y1) / my dy + 1.5);
- if (iy < 1) {
- ib = 1; ie = 2;
- } else if (iy > my ny) {
- ib = thy nxy - 1; ie = thy nxy;
- } else {
- ib = thy yindex[iy].ibegin; ie = thy yindex[iy].iend;
- }
- if (ie - ib > 1) {
- long it = ib + 1;
- while (ty - thy xytimes[it].y > eps) {
- it++;
- }
- ie = it; ib = it - 1;
- }
- double a = (thy xytimes[ib].y - thy xytimes[ie].y) / (thy xytimes[ib].x - thy xytimes[ie].x);
- double b = thy xytimes[ib].y - a * thy xytimes[ib].x;
- return (ty - b) / a;
+ DTW_Path_Query thee = & my pathQuery;
+ return RealTier_getValueAtTime(thy xfromy.get(), ty);
}
void DTW_Path_Query_init (DTW_Path_Query me, long ny, long nx) {
@@ -213,56 +163,128 @@ void DTW_Path_Query_init (DTW_Path_Query me, long ny, long nx) {
my ny = ny;
my nx = nx;
my nxy = 2 * (ny > nx ? ny : nx) + 2; // maximum number of points
- my xytimes = NUMvector<structDTW_Path_xytime> (1, my nxy);
- my yindex = NUMvector<structDTW_Path_Index> (1, my ny);
- my xindex = NUMvector<structDTW_Path_Index> (1, my nx);
+ my xfromy = Thing_new (RealTier);
+ my yfromx = Thing_new (RealTier);
}
-static void DTW_Path_makeIndex (DTW me, int xory) {
- DTW_Path_Query thee = & my pathQuery;
- DTW_Path_Index index;
- double x1, dx;
- long nx;
-
- if (! NUMfpp) {
- NUMmachar ();
- }
- double eps = 3 * NUMfpp -> eps;
-
- if (xory == DTW_X) {
- index = thy xindex;
- nx = my nx;
- x1 = my x1;
- dx = my dx;
- } else {
- index = thy yindex;
- nx = my ny;
- x1 = my y1;
- dx = my dy;
- }
- double xy_x2 = xory == DTW_X ? thy xytimes[3].x : thy xytimes[3].y;
- long i = 3;
- for (long j = 1; j <= nx; j++) {
- double xlow = x1 + (j - 1 - 0.5) * dx;
- double xhigh = xlow + dx;
-
- if (xlow - xy_x2 > -eps && i < thy nxy) { // i.e. xlow >= xy_x2
- i++;
- xy_x2 = xory == DTW_X ? thy xytimes[i].x : thy xytimes[i].y;
+/* Recode the path from a chain of cells to a piecewise linear path. */
+void DTW_Path_recode (DTW me) {
+ try {
+ DTW_Path_Query thee = & my pathQuery;
+ long nxy; // current number of elements in recoded path
+ long nsc_x = 1; // current number of successive horizontal cells in the cells chain
+ long nsc_y = 1; // current number of successive vertical cells in the cells chain
+ long nd = 0; // current number of successive diagonal cells in the cells chain
+ bool yDirection = false; // previous segment in the original path was vertical
+ bool xDirection = false; // previous segment in the original path was horizontal
+ long ixp = 0, iyp = 0; // previous cell
+ struct structPoint {
+ double x,y;
+ };
+
+ /* 1. Starting point always at origin */
+ long nxymax = thy nx + thy ny + 2;
+ autoNUMvector<struct structPoint> xytimes (1, nxymax);
+ xytimes[1].x = my xmin;
+ xytimes[1].y = my ymin;
+ /* 2. next point lower left of first cell */
+ nsc_x = my path[1].x;
+ ixp = nsc_x - 1;
+ xytimes[2].x = my x1 + (nsc_x - 1 - 0.5) * my dx;
+ nsc_y = my path[1].y;
+ iyp = nsc_y - 1;
+ xytimes[2].y = my y1 + (nsc_y - 1 - 0.5) * my dy;
+ /* 3. follow all cells. implicit: my x1 - 0.5 * my dx > my xmin && my y1 - 0.5 * my dy > my ymin */
+ nxy = 2;
+ for (long j = 1; j <= my pathLength; j++) {
+ long index; // where are we in the new path?
+ long ix = my path[j].x, iy = my path[j].y;
+ double xright = my x1 + (ix - 1 + 0.5) * my dx;
+ double x, y, f, ytop = my y1 + (iy - 1 + 0.5) * my dy;
+
+ if (iy == iyp) { // horizontal path?
+ xDirection = true;
+ if (yDirection) { // we came from vertical direction?
+ // We came from a vertical direction so this is the second horizontal cell in a row.
+ // The statement after this "if" updates nsc_x to 2.
+ nsc_x = 1; yDirection = false;
+ }
+ nsc_x++;
+
+ if (nsc_y > 1 || nd > 1) {
+ // Previous segment was diagonal or vertical: modify intersection
+ // The vh intersection (x,y) = (nsc_x*dx, dy) * (nsc_y-1)/(nsc_x*nsc_y-1)
+ // A diagonal segment has nsc_y = 1.
+ f = (nsc_y - 1.0) / (nsc_x * nsc_y - 1);
+ x = xright - nsc_x * my dx + nsc_x * my dx * f;
+ y = ytop - my dy + my dy * f;
+ index = nxy - 1;
+ if (nsc_x == 2) {
+ index = nxy;
+ nxy++;
+ }
+ xytimes[index].x = x;
+ xytimes[index].y = y;
+ }
+ nd = 0;
+ } else if (ix == ixp) { // vertical
+ yDirection = true;
+ if (xDirection) {
+ nsc_y = 1; xDirection = false;
+ }
+ nsc_y++;
+
+ if (nsc_x > 1 || nd > 1) {
+ // The hv intersection (x,y) = (dx, dy*nsc_y ) * (nsc_x-1)/(nsc_x*nsc_y-1)
+ f = (nsc_x - 1.0) / (nsc_x * nsc_y - 1);
+ x = xright - my dx + my dx * f;
+ y = ytop - nsc_y * my dy + nsc_y * my dy * f;
+ index = nxy - 1;
+ if (nsc_y == 2) {
+ index = nxy;
+ nxy++;
+ }
+ xytimes[index].x = x;
+ xytimes[index].y = y;
+ }
+ nd = 0;
+ } else if (ix == (ixp + 1) && iy == (iyp + 1)) { // diagonal
+ nd++;
+ if (nd == 1) {
+ nxy++;
+ }
+ nsc_x = nsc_y = 1;
+ } else {
+ Melder_throw (U"The path goes back in time.");
+ }
+ // update
+ xytimes[nxy].x = xright;
+ xytimes[nxy].y = ytop;
+ ixp = ix; iyp = iy;
}
- index[j].ibegin = i - 1;
-
- while (xhigh - xy_x2 > eps && i < thy nxy) { // i.e. xhigh > xy_x2
- i++;
- xy_x2 = xory == DTW_X ? thy xytimes[i].x : thy xytimes[i].y;
+ if (my xmax > xytimes[nxy].x || my ymax > xytimes[nxy].y) {
+ nxy++;
+ xytimes[nxy].x = my xmax;
+ xytimes[nxy].y = my ymax;
}
-
- index[j].iend = i;
+ Melder_assert (nxy <= 2 * (my ny > my nx ? my ny : my nx) + 2);
+
+ thy nxy = nxy;
+ thy yfromx = RealTier_create (my xmin, my xmax);
+ thy xfromy = RealTier_create (my ymin, my ymax);
+ for (long i = 1; i <= nxy; i++) {
+ RealTier_addPoint (thy yfromx.get(), xytimes[i].x, xytimes[i].y);
+ RealTier_addPoint (thy xfromy.get(), xytimes[i].y, xytimes[i].x);
+ }
+ //DTW_Path_makeIndex (me, DTW_X);
+ //DTW_Path_makeIndex (me, DTW_Y);
+ } catch (MelderError) {
+ Melder_throw (me, U": not recoded.");
}
}
-/* Recode the path from a chain of cells to a piecewise linear path. */
+#if 0
void DTW_Path_recode (DTW me) {
DTW_Path_Query thee = & my pathQuery;
long nxy; // current number of elements in recoded path
@@ -367,6 +389,7 @@ void DTW_Path_recode (DTW me) {
DTW_Path_makeIndex (me, DTW_X);
DTW_Path_makeIndex (me, DTW_Y);
}
+#endif
void DTW_pathRemoveRedundantNodes (DTW me) {
long i = 1, skip = 0;
@@ -620,6 +643,14 @@ void DTW_paintDistances (DTW me, Graphics g, double xmin, double xmax, double ym
DTW_paintDistances_raw (me, g, xmin, xmax, ymin, ymax, minimum, maximum, garnish, 1);
}
+static double RealTier_getXAtIndex (RealTier me, long point) {
+ double x = NUMundefined;
+ if (point > 0 && point <= my points.size) {
+ x = my points.at [point] -> number;
+ }
+ return x;
+}
+
static void DTW_drawPath_raw (DTW me, Graphics g, double xmin, double xmax, double ymin,
double ymax, int garnish, int inset) {
DTW_Path_Query thee = & my pathQuery;
@@ -635,14 +666,17 @@ static void DTW_drawPath_raw (DTW me, Graphics g, double xmin, double xmax, doub
Graphics_setInner (g);
}
Graphics_setWindow (g, xmin, xmax, ymin, ymax);
-
- for (long i = 1; i < thy nxy; i++) {
- double x1, y1, x2, y2;
- if (NUMclipLineWithinRectangle (thy xytimes[i].x, thy xytimes[i].y,
- thy xytimes[i + 1].x, thy xytimes[i + 1].y,
- xmin, ymin, xmax, ymax, &x1, &y1, &x2, &y2)) {
- Graphics_line (g, x1, y1, x2, y2);
+ double x1 = RealTier_getXAtIndex (thy yfromx.get(), 1);
+ double y1 = RealTier_getValueAtIndex (thy yfromx.get(), 1);
+ for (long i = 2; i <= thy yfromx -> points.size; i++) {
+ double x2 = RealTier_getXAtIndex (thy yfromx.get(), i);
+ double y2 = RealTier_getValueAtIndex (thy yfromx.get(), i);
+ double xc1, yc1, xc2, yc2;
+ if (NUMclipLineWithinRectangle (x1, y1,x2, y2, xmin, ymin, xmax, ymax, &xc1, &yc1, &xc2, &yc2)) {
+ Graphics_line (g, xc1, yc1, xc2, yc2);
}
+ x1 = x2;
+ y1 = y2;
}
if (inset) {
@@ -659,8 +693,9 @@ void DTW_drawPath (DTW me, Graphics g, double xmin, double xmax, double ymin, do
DTW_drawPath_raw (me, g, xmin, xmax, ymin, ymax, garnish, 1);
}
-static void DTW_drawWarpX_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish, int inset) {
- double ty = DTW_getYTimeFromXTime (me, tx);
+static void DTW_drawWarp_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double t, int garnish, bool inset, bool warpX) {
+ double tx = warpX ? t : DTW_getXTimeFromYTime (me, t);
+ double ty = warpX ? DTW_getYTimeFromXTime (me, t): t;
int lineType = Graphics_inqLineType (g);
if (xmin >= xmax) {
@@ -675,7 +710,6 @@ static void DTW_drawWarpX_raw (DTW me, Graphics g, double xmin, double xmax, dou
}
Graphics_setWindow (g, xmin, xmax, ymin, ymax);
- ty = DTW_getYTimeFromXTime (me, tx);
Graphics_setLineType (g, Graphics_DOTTED);
if (ty <= ymax) {
Graphics_line (g, tx, ymin, tx, ty);
@@ -699,7 +733,11 @@ static void DTW_drawWarpX_raw (DTW me, Graphics g, double xmin, double xmax, dou
}
void DTW_drawWarpX (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish) {
- DTW_drawWarpX_raw (me, g, xmin, xmax, ymin, ymax, tx, garnish, 1);
+ DTW_drawWarp_raw (me, g, xmin, xmax, ymin, ymax, tx, garnish, true, true);
+}
+
+void DTW_drawWarpY (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double ty, int garnish) {
+ DTW_drawWarp_raw (me, g, xmin, xmax, ymin, ymax, ty, garnish, true, false);
}
static void DTW_and_Sounds_checkDomains (DTW me, Sound *y, Sound *x, double *xmin, double *xmax, double *ymin, double *ymax) {
@@ -1301,7 +1339,6 @@ void DTW_findPath_bandAndSlope (DTW me, double sakoeChibaBand, int localSlope, a
void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoMatrix *cummulativeDists) {
try {
double slopes[5] = { DTW_BIG, DTW_BIG, 3, 2, 1.5 };
- long pathIndex = my nx + my ny - 1; /* Maximum path length */
// if localSlope == 1 start of path is within 10% of minimum duration. Starts farther away
long delta_xy = (my nx < my ny ? my nx : my ny) / 10; // if localSlope == 1 start within 10% of
@@ -1330,7 +1367,9 @@ void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoM
// Make begin part of first column reachable
long rowto = delta_xy;
- if (localSlope != 1) rowto = (long) floor (slopes[localSlope]) + 1;
+ if (localSlope != 1) {
+ rowto = (long) floor (slopes[localSlope]) + 1;
+ }
for (long iy = 2; iy <= rowto; iy++) {
if (localSlope != 1) {
delta[iy][1] = delta[iy - 1][1] + my z[iy][1];
@@ -1341,7 +1380,9 @@ void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoM
}
// Make begin part of first row reachable
long colto = delta_xy;
- if (localSlope != 1) colto = (long) floor (slopes[localSlope]) + 1;
+ if (localSlope != 1) {
+ colto = (long) floor (slopes[localSlope]) + 1;
+ }
for (long ix = 2; ix <= colto; ix++) {
if (localSlope != 1) {
delta[1][ix] = delta[1][ix -1] + my z[1][ix];
@@ -1469,7 +1510,8 @@ void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoM
minimum = delta[iy = i][my nx];
}
}
-
+
+ long pathIndex = my nx + my ny - 1; /* Maximum path length */
my weightedDistance = minimum / (my nx + my ny);
my path[pathIndex].y = iy;
long ix = my path[pathIndex].x = my nx;
@@ -1493,7 +1535,7 @@ void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoM
my path[pathIndex].y = iy;
}
- my pathLength = my nx + my ny - pathIndex;
+ my pathLength = my nx + my ny - 1 - pathIndex + 1;
if (pathIndex > 1) {
for (long j = 1; j <= my pathLength; j++) {
my path[j] = my path[pathIndex++];
diff --git a/dwtools/DTW.h b/dwtools/DTW.h
index ddd84d2..ef4a037 100644
--- a/dwtools/DTW.h
+++ b/dwtools/DTW.h
@@ -75,11 +75,6 @@ void DTW_findPath (DTW me, int matchStart, int matchEnd, int slope); // deprecat
void DTW_Path_recode (DTW me);
-double DTW_getPathY (DTW me, double tx);
-/*
- Get the time Y-time that corresponds to time t (along X).
-*/
-
double DTW_getYTimeFromXTime (DTW me, double tx);
double DTW_getXTimeFromYTime (DTW me, double ty);
@@ -93,6 +88,7 @@ void DTW_drawPath (DTW me, Graphics g, double xmin, double xmax, double ymin,
double ymax, int garnish);
void DTW_drawWarpX (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish);
+void DTW_drawWarpY (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double ty, int garnish);
void DTW_pathRemoveRedundantNodes (DTW me);
diff --git a/dwtools/DTW_and_TextGrid.cpp b/dwtools/DTW_and_TextGrid.cpp
index c8025f8..e432ed0 100644
--- a/dwtools/DTW_and_TextGrid.cpp
+++ b/dwtools/DTW_and_TextGrid.cpp
@@ -193,7 +193,7 @@ autoTextTier DTW_and_TextTier_to_TextTier_old (DTW me, TextTier thee) {
for (long i = 1; i <= his points.size; i ++) {
TextPoint textpoint = his points.at [i];
- double time = DTW_getPathY (me, textpoint -> number);
+ double time = DTW_getYTimeFromXTime (me, textpoint -> number);
textpoint -> number = time;
}
return him;
@@ -214,9 +214,9 @@ autoIntervalTier DTW_and_IntervalTier_to_IntervalTier_old (DTW me, IntervalTier
for (long i = 1; i <= his intervals.size; i ++) {
TextInterval textinterval = his intervals.at [i];
- double xmin = DTW_getPathY (me, textinterval -> xmin);
+ double xmin = DTW_getYTimeFromXTime (me, textinterval -> xmin);
textinterval -> xmin = xmin;
- double xmax = DTW_getPathY (me, textinterval -> xmax);
+ double xmax = DTW_getYTimeFromXTime (me, textinterval -> xmax);
textinterval -> xmax = xmax;
}
return him;
diff --git a/dwtools/DTW_def.h b/dwtools/DTW_def.h
index 86bcf54..4380f4d 100644
--- a/dwtools/DTW_def.h
+++ b/dwtools/DTW_def.h
@@ -30,28 +30,13 @@ oo_DEFINE_STRUCT (DTW_Path)
oo_END_STRUCT (DTW_Path)
#undef ooSTRUCT
-#define ooSTRUCT DTW_Path_Index
-oo_DEFINE_STRUCT (DTW_Path_Index)
- oo_LONG (ibegin)
- oo_LONG (iend)
-oo_END_STRUCT (DTW_Path_Index)
-#undef ooSTRUCT
-
-#define ooSTRUCT DTW_Path_xytime
-oo_DEFINE_STRUCT (DTW_Path_xytime)
- oo_DOUBLE (x)
- oo_DOUBLE (y)
-oo_END_STRUCT (DTW_Path_xytime)
-#undef ooSTRUCT
-
#define ooSTRUCT DTW_Path_Query
oo_DEFINE_STRUCT (DTW_Path_Query)
oo_LONG (nx)
oo_LONG (ny)
oo_LONG (nxy)
- oo_STRUCT_VECTOR (DTW_Path_xytime, xytimes, nxy)
- oo_STRUCT_VECTOR (DTW_Path_Index, xindex, nx)
- oo_STRUCT_VECTOR (DTW_Path_Index, yindex, ny)
+ oo_AUTO_OBJECT (RealTier, 0, yfromx)
+ oo_AUTO_OBJECT (RealTier, 0, xfromy)
oo_END_STRUCT (DTW_Path_Query)
#undef ooSTRUCT
diff --git a/dwtools/Sound_extensions.cpp b/dwtools/Sound_extensions.cpp
index 24e5b65..d366f66 100644
--- a/dwtools/Sound_extensions.cpp
+++ b/dwtools/Sound_extensions.cpp
@@ -1307,7 +1307,8 @@ autoTextGrid Sound_to_TextGrid_detectSilences (Sound me, double minPitch, double
const char32 *silentLabel, const char32 *soundingLabel) {
try {
int subtractMeanPressure = 1;
- autoIntensity thee = Sound_to_Intensity (me, minPitch, timeStep, subtractMeanPressure);
+ autoSound filtered = Sound_filter_passHannBand (me, 80.0, 8000.0, 80.0);
+ autoIntensity thee = Sound_to_Intensity (filtered.get(), minPitch, timeStep, subtractMeanPressure);
autoTextGrid him = Intensity_to_TextGrid_detectSilences (thee.get(), silenceThreshold, minSilenceDuration, minSoundingDuration, silentLabel, soundingLabel);
return him;
} catch (MelderError) {
@@ -1398,8 +1399,7 @@ autoSound Sound_trimSilences (Sound me, double trimDuration, bool onlyAtStartAnd
}
const char32 *silentLabel = U"silent", *soundingLabel = U"sounding";
const char32 *copyLabel = U"";
- autoTextGrid tg = Sound_to_TextGrid_detectSilences (me, minPitch, timeStep, silenceThreshold,
- minSilenceDuration, minSoundingDuration, silentLabel, soundingLabel);
+ autoTextGrid tg = Sound_to_TextGrid_detectSilences (me, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, silentLabel, soundingLabel);
autoIntervalTier itg = Data_copy ((IntervalTier) tg -> tiers->at [1]);
IntervalTier tier = (IntervalTier) tg -> tiers->at [1];
for (long iint = 1; iint <= tier -> intervals.size; iint ++) {
diff --git a/dwtools/Spectrogram_extensions.cpp b/dwtools/Spectrogram_extensions.cpp
index 5450f99..13eac71 100644
--- a/dwtools/Spectrogram_extensions.cpp
+++ b/dwtools/Spectrogram_extensions.cpp
@@ -147,7 +147,7 @@ void BandFilterSpectrogram_into_CC (BandFilterSpectrogram me, CC thee, long numb
autoNUMvector<double> y (1, my ny);
numberOfCoefficients = numberOfCoefficients > my ny - 1 ? my ny - 1 : numberOfCoefficients;
Melder_assert (numberOfCoefficients > 0);
- // 20130220 new interpretation of maximumNumberOfCoefficients necessary for inverse transform
+ // 20130220 new interpretation of maximumNumberOfCoefficients: necessary for the inverse transform
for (long frame = 1; frame <= my nx; frame++) {
CC_Frame ccframe = (CC_Frame) & thy frame[frame];
for (long i = 1; i <= my ny; i++) {
diff --git a/dwtools/SpeechSynthesizer.cpp b/dwtools/SpeechSynthesizer.cpp
index 133ec04..3ce9225 100644
--- a/dwtools/SpeechSynthesizer.cpp
+++ b/dwtools/SpeechSynthesizer.cpp
@@ -298,8 +298,8 @@ void SpeechSynthesizer_setSpeechOutputSettings (SpeechSynthesizer me, double sam
}
void SpeechSynthesizer_playText (SpeechSynthesizer me, const char32 *text) {
- autoSound thee= SpeechSynthesizer_to_Sound (me, text, 0, 0);
- Sound_playPart (thee.get(), thy xmin, thy xmax, 0, 0);
+ autoSound thee = SpeechSynthesizer_to_Sound (me, text, nullptr, nullptr);
+ Sound_playPart (thee.get(), thy xmin, thy xmax, nullptr, nullptr);
}
static autoSound buffer_to_Sound (int *wav, long numberOfSamples, double samplingFrequency)
@@ -319,7 +319,7 @@ static autoSound buffer_to_Sound (int *wav, long numberOfSamples, double samplin
static void IntervalTier_addBoundaryUnsorted (IntervalTier me, long iinterval, double time, const char32 *newLabel, bool isNewleftLabel) {
if (time <= my xmin || time >= my xmax) {
- Melder_throw (U"Time is outside interval.");
+ Melder_throw (U"Time is outside interval domains.");
}
// Find interval to split
@@ -332,7 +332,7 @@ static void IntervalTier_addBoundaryUnsorted (IntervalTier me, long iinterval, d
ti -> xmax = time;
if (isNewleftLabel) TextInterval_setText (ti, newLabel);
- autoTextInterval ti_new = TextInterval_create (time, my xmax, ( ! isNewleftLabel ? newLabel : U"" ));
+ autoTextInterval ti_new = TextInterval_create (time, my xmax, (! isNewleftLabel ? newLabel : U"" ));
my intervals. addItem_unsorted_move (ti_new.move());
}
@@ -364,9 +364,104 @@ static void Table_setEventTypeString (Table me) {
}
static void MelderString_trimWhiteSpaceAtEnd (MelderString *me) {
- while (my length > 1 && (my string[my length - 1] == U' ' || my string[my length - 1] == U'\t'
- || my string[my length - 1] == U'\r' || my string[my length - 1] == U'\n')) {
- my string[my length - 1] = U'\0'; my length--;
+ while (my length > 1 && (my string [my length - 1] == U' ' || my string [my length - 1] == U'\t'
+ || my string [my length - 1] == U'\r' || my string [my length - 1] == U'\n'))
+ {
+ my string [my length - 1] = U'\0';
+ my length--;
+ }
+}
+
+static void IntervalTier_mergeSpecialIntervals (IntervalTier me) {
+ long intervalIndex = my intervals.size;
+ TextInterval right = my intervals.at [intervalIndex];
+ long labelLength_right = TextInterval_labelLength (right);
+ bool isEmptyInterval_right = labelLength_right == 0 || (labelLength_right == 1 && Melder_equ (right -> text, U"\001"));
+ while (intervalIndex > 1) {
+ TextInterval left = my intervals.at [intervalIndex - 1];
+ long labelLength_left = TextInterval_labelLength (left);
+ bool isEmptyInterval_left = labelLength_left == 0 || (labelLength_left == 1 && Melder_equ (left -> text, U"\001"));
+ if (isEmptyInterval_right && isEmptyInterval_left) {
+ // remove right interval and empty left interval
+ left -> xmax = right -> xmax;
+ TextInterval_setText (left, U"");
+ my intervals. removeItem (intervalIndex);
+ }
+ right = left;
+ isEmptyInterval_right = isEmptyInterval_left;
+ intervalIndex --;
+ }
+}
+
+/* insert boundary at time t and merge/delete intervals after this time */
+static void IntervalTier_insertBoundaryAndMergeIntervalsAfter (IntervalTier me, double t) {
+ if (t <= my xmin || t >= my xmax) {
+ return;
+ }
+
+ long intervalNumber = IntervalTier_timeToLowIndex (me, t);
+ while (my intervals.size > intervalNumber + 1) {
+ my intervals. removeItem (my intervals.size);
+ }
+ // there can be maximally one interval left to the right of intervalNumber
+ TextInterval ti = my intervals.at [intervalNumber];
+ if (ti -> xmin == t) { // if t happens to be on a boundary: remove the next interval if it exists
+ if (my intervals.size > intervalNumber) {
+ my intervals. removeItem (my intervals .size);
+ }
+ ti -> xmax = my xmax;
+ TextInterval_setText (ti, U"");
+ } else {
+ ti -> xmax = t;
+ TextInterval last = my intervals.at [my intervals.size];
+ last -> xmin = t;
+ last -> xmax = my xmax;
+ TextInterval_setText (last, U"");
+ }
+}
+
+
+static bool almost_equal (double t1, double t2) {
+ // the "=" sign is essential for a difference of zero if t1 == 0
+ return fabs (t1 - t2) <= 1e-12 * fabs (t1);
+}
+
+static void IntervalTier_insertEmptyIntervalsFromOtherTier (IntervalTier to, IntervalTier from) {
+ for (long iint = 1; iint <= from -> intervals.size; iint ++) {
+ TextInterval tifrom = from -> intervals.at [iint];
+ if (TextInterval_labelLength (tifrom) == 0) { // found empty interval
+ double t_left = tifrom -> xmin, t_right = tifrom -> xmax;
+ long intervalIndex_to = IntervalTier_timeToLowIndex (to, t_left);
+ if (intervalIndex_to > 0) { // insert to the right of intervalIndex_to
+ TextInterval tito = to -> intervals.at [intervalIndex_to];
+ if (! almost_equal (tito -> xmin, t_left)) { // not on the start boundary of the interval, it cannot be at xmax
+ autoTextInterval newInterval = TextInterval_create (t_left, tito -> xmax, U"");
+ tito -> xmax = t_left;
+ to -> intervals. addItem_move (newInterval.move());
+ }
+ }
+ intervalIndex_to = IntervalTier_timeToHighIndex (to, t_right);
+ TextInterval tito = to -> intervals.at [intervalIndex_to];
+ if (intervalIndex_to > 0) {
+ if (! almost_equal (t_right, tito -> xmax)) { // insert to the left of intervalIndex_to
+ autoTextInterval newInterval = TextInterval_create (tito -> xmin, t_right, U"");
+ tito -> xmin = t_right;
+ to -> intervals. addItem_move (newInterval.move());
+ }
+ }
+ }
+ }
+}
+
+static void IntervalTier_removeVeryShortIntervals (IntervalTier me) {
+ long iint = 1;
+ while (iint <= my intervals.size) {
+ TextInterval ti = my intervals.at [iint];
+ if (almost_equal (ti -> xmin, ti -> xmax)) {
+ my intervals.removeItem (iint);
+ } else {
+ iint ++;
+ }
}
}
@@ -384,13 +479,13 @@ static autoTextGrid Table_to_TextGrid (Table me, const char32 *text, double xmin
TextGrid_setIntervalText (thee.get(), 1, 1, text);
long p1c = 1, p1w = 1;
- double t1p = xmin;
+ double time_phon_p = xmin;
bool wordEnd = false;
autoMelderString mark;
- IntervalTier itc = (IntervalTier) thy tiers->at [2];
- IntervalTier itw = (IntervalTier) thy tiers->at [3];
- IntervalTier itp = (IntervalTier) thy tiers->at [4];
+ IntervalTier clauses = (IntervalTier) thy tiers->at [2];
+ IntervalTier words = (IntervalTier) thy tiers->at [3];
+ IntervalTier phonemes = (IntervalTier) thy tiers->at [4];
for (long i = 1; i <= numberOfRows; i++) {
double time = Table_getNumericValue_Assert (me, i, timeColumnIndex);
@@ -399,8 +494,8 @@ static autoTextGrid Table_to_TextGrid (Table me, const char32 *text, double xmin
if (type == espeakEVENT_SENTENCE) {
// Only insert a new boundary, no text
// text will be inserted at end sentence event
- if (time > xmin and time < xmax) {
- IntervalTier_addBoundaryUnsorted (itc, itc -> intervals.size, time, U"", true);
+ if (time > xmin && time < xmax) {
+ IntervalTier_addBoundaryUnsorted (clauses, clauses -> intervals.size, time, U"", true);
}
p1c = pos;
} else if (type == espeakEVENT_END) {
@@ -408,10 +503,10 @@ static autoTextGrid Table_to_TextGrid (Table me, const char32 *text, double xmin
length = pos - p1c + 1;
MelderString_ncopy (&mark, text + p1c - 1, length);
MelderString_trimWhiteSpaceAtEnd (& mark);
- if (time > xmin and time < xmax) {
- IntervalTier_addBoundaryUnsorted (itc, itc -> intervals.size, time, mark.string, true);
+ if (time > xmin && time < xmax) {
+ IntervalTier_addBoundaryUnsorted (clauses, clauses -> intervals.size, time, mark.string, true);
} else {
- TextGrid_setIntervalText (thee.get(), 2, itc -> intervals.size, mark.string);
+ TextGrid_setIntervalText (thee.get(), 2, clauses -> intervals.size, mark.string);
}
p1c = pos;
@@ -421,10 +516,10 @@ static autoTextGrid Table_to_TextGrid (Table me, const char32 *text, double xmin
length = pos - p1w + 1;
MelderString_ncopy (&mark, text + p1w - 1, length);
MelderString_trimWhiteSpaceAtEnd (& mark);
- if (time > xmin and time < xmax) {
- IntervalTier_addBoundaryUnsorted (itw, itw -> intervals.size, time, mark.string, true);
+ if (time > xmin && time < xmax) {
+ IntervalTier_addBoundaryUnsorted (words, words -> intervals.size, time, mark.string, true);
} else {
- TextGrid_setIntervalText (thee.get(), 3, itw -> intervals.size, mark.string);
+ TextGrid_setIntervalText (thee.get(), 3, words -> intervals.size, mark.string);
}
// now the next word event should not trigger setting the left interval text
wordEnd = false;
@@ -433,34 +528,47 @@ static autoTextGrid Table_to_TextGrid (Table me, const char32 *text, double xmin
if (pos < p1w) {
continue;
}
- if (time > xmin and time < xmax) {
+ if (time > xmin && time < xmax) {
length = pos - p1w;
- if (pos == textLength) length++;
+ if (pos == textLength) {
+ length++;
+ }
MelderString_ncopy (&mark, text + p1w - 1, length);
MelderString_trimWhiteSpaceAtEnd (& mark);
- IntervalTier_addBoundaryUnsorted (itw, itw -> intervals.size, time, ( wordEnd ? mark.string : U"" ), true);
+ IntervalTier_addBoundaryUnsorted (words, words -> intervals.size, time, ( wordEnd ? mark.string : U"" ), true);
}
wordEnd = true;
p1w = pos;
} else if (type == espeakEVENT_PHONEME) {
const char32 *id = Table_getStringValue_Assert (me, i, idColumnIndex);
- if (time > t1p) {
+ if (time > time_phon_p) {
// Insert new boudary and label interval with the id
// TODO: Translate the id to the correct notation
- TextInterval ti = itp -> intervals.at [itp -> intervals.size];
- if (time > ti -> xmin and time < ti -> xmax) {
- IntervalTier_addBoundaryUnsorted (itp, itp -> intervals.size, time, id, false);
+ TextInterval ti = phonemes -> intervals.at [phonemes -> intervals.size];
+ if (time > ti -> xmin && time < ti -> xmax) {
+ IntervalTier_addBoundaryUnsorted (phonemes, phonemes -> intervals.size, time, id, false);
}
} else {
// Just in case the phoneme starts at xmin we only need to set interval text
- TextGrid_setIntervalText (thee.get(), 4, itp -> intervals.size, id);
+ TextGrid_setIntervalText (thee.get(), 4, phonemes -> intervals.size, id);
}
- t1p = time;
+ time_phon_p = time;
}
}
- itc -> intervals. sort ();
- itw -> intervals. sort ();
- itp -> intervals. sort ();
+ clauses -> intervals. sort ();
+ words -> intervals. sort ();
+ phonemes -> intervals. sort ();
+
+ IntervalTier_mergeSpecialIntervals (phonemes); // Merge neighbouring empty U"" and U"\001" intervals
+
+ IntervalTier_removeVeryShortIntervals (words);
+ IntervalTier_removeVeryShortIntervals (clauses);
+
+ /* Use empty intervals in phoneme tier for more precision in the word tier */
+
+ IntervalTier_insertEmptyIntervalsFromOtherTier (words, phonemes);
+ IntervalTier_mergeSpecialIntervals (words); // Merge neighbouring empty U"" and U"\001" intervals
+
return thee;
} catch (MelderError) {
Melder_throw (U"TextGrid not created from Table with events.");
@@ -471,13 +579,13 @@ static void espeakdata_SetVoiceByName (const char *name, const char *variantName
{
espeak_VOICE voice_selector;
- memset(&voice_selector, 0, sizeof(voice_selector));
+ memset (& voice_selector, 0, sizeof voice_selector);
voice_selector.name = Melder_peek32to8 (Melder_cat (Melder_peek8to32 (name), U"+", Melder_peek8to32 (variantName))); // include variant name in voice stack ??
if (LoadVoice (name, 1)) {
- LoadVoice(variantName, 2);
- DoVoiceChange(voice);
- SetVoiceStack (&voice_selector, variantName);
+ LoadVoice (variantName, 2);
+ DoVoiceChange (voice);
+ SetVoiceStack (& voice_selector, variantName);
}
}
@@ -497,7 +605,7 @@ void SpeechSynthesizer_changeLanguageNameToCurrent (SpeechSynthesizer me) {
{ U"Lancashire", nullptr},
{ U"Macedonian-test", U"Macedonian"}, { U"Maltese-test", nullptr},
{ U"Nahuatl - classical", U"Nahuatl-classical"}, { U"Nepali-test", U"Nepali"}, { U"Northern-sotho", nullptr},
- { U"Punjabi-test", U"Punjab"},
+ { U"Punjabi-test", U"Punjabi"},
{ U"Russian_test", U"Russian"}, // yes, underscore
{ U"Setswana-test", nullptr}, { U"Sinhala", U"Sinhala-test"},
{ U"Spanish-latin-american", U"Spanish-latin-am"}, { U"Tatar-test", nullptr},
@@ -505,19 +613,18 @@ void SpeechSynthesizer_changeLanguageNameToCurrent (SpeechSynthesizer me) {
{ U"Welsh-test", U"Welsh"}, { U"Wolof-test", nullptr},
{nullptr,nullptr}};
long index = 0;
- const char32 *oldName;
- while (oldName = names[index].oldName) {
+ while (const char32 *oldName = names [index]. oldName) {
if (Melder_equ (oldName, my d_voiceLanguageName)) {
- if (names[index].currentName) {
- autostring32 newLabel = Melder_dup (names[index].currentName);
+ if (names [index]. currentName) {
+ autostring32 newLabel = Melder_dup (names [index]. currentName);
Melder_free (my d_voiceLanguageName);
my d_voiceLanguageName = newLabel.transfer();
break;
} else {
- Melder_throw (U"Language ", oldName, U" is not available anymore.");
+ Melder_throw (U"Language ", oldName, U" is not available any longer.");
}
}
- ++index;
+ ++ index;
}
} catch (MelderError) {
Melder_throw (U"Cannot change language name.");
diff --git a/dwtools/SpeechSynthesizer_and_TextGrid.cpp b/dwtools/SpeechSynthesizer_and_TextGrid.cpp
index 17a2bdb..4ffbcb4 100644
--- a/dwtools/SpeechSynthesizer_and_TextGrid.cpp
+++ b/dwtools/SpeechSynthesizer_and_TextGrid.cpp
@@ -39,7 +39,7 @@ static autoTable IntervalTiers_to_Table_textAlignmentment (IntervalTier target,
autoSound SpeechSynthesizer_and_TextInterval_to_Sound (SpeechSynthesizer me, TextInterval thee, autoTextGrid *p_tg)
{
try {
- if (! thy text || thy text[0] == '\0') {
+ if (! thy text || thy text[0] == U'\0') {
Melder_throw (U"No text in TextInterval.");
}
autoSound him = SpeechSynthesizer_to_Sound (me, thy text, p_tg, nullptr);
@@ -465,13 +465,12 @@ autoTextGrid TextGrid_and_IntervalTier_patch (TextGrid me, IntervalTier thee, co
}
// We assume that the Sound and the SpeechSynthesizer have the same samplingFrequency
-// schakel waarschuwingen over stiltedetectie uit
autoTextGrid SpeechSynthesizer_and_Sound_and_TextInterval_align (SpeechSynthesizer me, Sound thee, TextInterval him, double silenceThreshold, double minSilenceDuration, double minSoundingDuration) {
try {
if (thy xmin != his xmin || thy xmax != his xmax) {
Melder_throw (U"Domains of Sound and TextGrid must be equal.");
}
- if (fabs (1.0 / thy dx - my d_samplingFrequency) > NUMfpp -> eps) {
+ if (fabs (1.0 / thy dx - my d_samplingFrequency) > 1e-9) {
Melder_throw (U"The sampling frequencies of the SpeechSynthesizer and the Sound must be equal.");
}
long numberOfTokens = Melder_countTokens (his text);
@@ -481,8 +480,7 @@ autoTextGrid SpeechSynthesizer_and_Sound_and_TextInterval_align (SpeechSynthesiz
// Remove silent intervals from start and end of sounds
double minPitch = 200.0, timeStep = 0.005, precision = thy dx;
double t1_thee, t2_thee;
- autoSound s_thee = Sound_trimSilencesAtStartAndEnd (thee, 0.0, minPitch, timeStep,
- silenceThreshold, minSilenceDuration, minSoundingDuration, & t1_thee, & t2_thee);
+ autoSound s_thee = Sound_trimSilencesAtStartAndEnd (thee, 0.0, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, & t1_thee, & t2_thee);
double s_thee_duration = s_thee -> xmax - s_thee -> xmin;
bool hasSilence_thee = fabs (t1_thee - thy xmin) > precision || fabs (t2_thee - thy xmax) > precision;
@@ -494,42 +492,39 @@ autoTextGrid SpeechSynthesizer_and_Sound_and_TextInterval_align (SpeechSynthesiz
my d_wordsPerMinute = (long) floor (0.5 * (wordsPerMinute_rawTokens + wordsPerMinute_rawText));
}
autoTextGrid tg2;
- autoSound s2 = SpeechSynthesizer_and_TextInterval_to_Sound (me, him, & tg2);
+ autoSound synth = SpeechSynthesizer_and_TextInterval_to_Sound (me, him, & tg2);
autoTextGrid silentTextGrid;
/*
* For the synthesizer the silence threshold has to be < -30 dB, otherwise fricatives will not
- * be found as sounding! This is ok since silences are almost at zero amplitudes
+ * be found as sounding! This is ok since silences are almost at zero amplitudes for synthesized sounds.
* We also have to decrease the minimum silence and minimum sounding duration to catch, for example,
- * the final plosive "t" from the word "text"
+ * the final plosive "t" from the synthesized sound "text"
*
*/
- double s2_silenceThreshold = -40.0, s2_minSilenceDuration = 0.05, s2_minSoundingDuration = 0.05;
- double t1_s2, t2_s2;
- autoSound s_s2 = Sound_trimSilencesAtStartAndEnd (s2.get(), 0.0, minPitch, timeStep,
- s2_silenceThreshold, s2_minSilenceDuration, s2_minSoundingDuration, & t1_s2, & t2_s2);
- double s_s2_duration = s_s2 -> xmax - s_s2 -> xmin;
- bool hasSilence_s2 = fabs (t1_s2 - s2 -> xmin) > precision || fabs (t2_s2 - s2 -> xmax) > precision;
- if (hasSilence_s2) {
- silentTextGrid = TextGrid_extractPart (tg2.get(), t1_s2, t2_s2, true);
+ double synth_silenceThreshold = -40.0, synth_minSilenceDuration = 0.05, synth_minSoundingDuration = 0.05;
+ double t1_synth, t2_synth;
+ autoSound synth_trimmed = Sound_trimSilencesAtStartAndEnd (synth.get(), 0.0, minPitch, timeStep,
+ synth_silenceThreshold, synth_minSilenceDuration, synth_minSoundingDuration, & t1_synth, & t2_synth);
+ double synth_trimmed_duration = synth_trimmed -> xmax - synth_trimmed -> xmin;
+ bool hasSilence_synth = fabs (t1_synth - synth -> xmin) > precision || fabs (t2_synth - synth -> xmax) > precision;
+ if (hasSilence_synth) {
+ silentTextGrid = TextGrid_extractPart (tg2.get(), t1_synth, t2_synth, true);
}
double analysisWidth = 0.02, dt = 0.005, band = 0.0;
// compare the durations of the two sounds to get an indication of the slope constraint of the DTW
- double slope = s_thee_duration / s_s2_duration;
- slope = ( slope > 1.0 ? slope : 1.0 / slope );
- int constraint = ( slope < 1.5 ? 4.0 : slope < 2.0 ? 3.0 : slope < 3.0 ? 2.0 : 1.0 );
+ double slope = s_thee_duration / synth_trimmed_duration;
+ slope = (slope > 1.0 ? slope : 1.0 / slope);
+ int constraint = (slope < 1.5 ? 4 : slope < 2.0 ? 3 : slope < 3.0 ? 2 : 1);
//autoMFCC m1 = Sound_to_MFCC ((hasSilence_thee ? s_thee.get() : thee),
// numberOfCoefficients, analysisWidth, dt, f1_mel, fmax_mel, df_mel);
- //autoMFCC m2 = Sound_to_MFCC ((hasSilence_s2 ? s_s2.get() : s2.get()),
+ //autoMFCC m2 = Sound_to_MFCC ((hasSilence_synth ? synth_trimmed.get() : synth.get()),
// numberOfCoefficients, analysisWidth, dt, f1_mel, fmax_mel, df_mel);
//double wc = 1, wle = 0, wr = 0, wer = 0, dtr = 0;
//int matchStart = 1, matchEnd = 1, constraint = 4; // no 1/3 1/2 2/3
//autoDTW dtw = CCs_to_DTW (m1.get(), m2.get(), wc, wle, wr, wer, dtr, matchStart, matchEnd, constraint);
- autoDTW dtw = Sounds_to_DTW (
- ( hasSilence_thee ? s_thee.get() : thee ),
- ( hasSilence_s2 ? s_s2.get() : s2.get() ),
+ autoDTW dtw = Sounds_to_DTW ((hasSilence_thee ? s_thee.get() : thee), (hasSilence_synth ? synth_trimmed.get() : synth.get()),
analysisWidth, dt, band, constraint);
- autoTextGrid result = DTW_and_TextGrid_to_TextGrid (dtw.get(),
- ( hasSilence_s2 ? silentTextGrid.get() : tg2.get() ), precision);
+ autoTextGrid result = DTW_and_TextGrid_to_TextGrid (dtw.get(), (hasSilence_synth ? silentTextGrid.get() : tg2.get()), precision);
if (hasSilence_thee) {
if (t1_thee > thy xmin) {
TextGrid_setEarlierStartTime (result.get(), thy xmin, U"", U"");
@@ -720,8 +715,8 @@ autoTable IntervalTiers_to_Table_textAlignmentment (IntervalTier target, Interva
for (long i = 2; i <= pathLength; i++) {
structPairOfInteger p = edit -> warpingPath -> path[i];
structPairOfInteger p1 = edit -> warpingPath -> path[i - 1];
- double targetStart = NUMundefined, targetEnd = NUMundefined;
- double sourceStart = NUMundefined, sourceEnd = NUMundefined;
+ double targetStart = NUMundefined, targetEnd = NUMundefined;
+ double sourceStart = NUMundefined, sourceEnd = NUMundefined;
const char32 * targetText = U"", *sourceText = U"";
long targetInterval = p.y > 1 ? targetOrigin[p.y - 1] : 0;
long sourceInterval = p.x > 1 ? sourceOrigin[p.x - 1] : 0;
diff --git a/dwtools/manual_dwtools.cpp b/dwtools/manual_dwtools.cpp
index fb5f199..d7b775a 100644
--- a/dwtools/manual_dwtools.cpp
+++ b/dwtools/manual_dwtools.cpp
@@ -3783,13 +3783,15 @@ DEFINITION (U"determines the label for a silent interval in the TextGrid.") \
TAG (U"##Sounding interval label") \
DEFINITION (U"determines the label for a sounding interval in the TextGrid.")
-MAN_BEGIN (U"Sound: To TextGrid (silences)...", U"djmw", 20061205)
+MAN_BEGIN (U"Sound: To TextGrid (silences)...", U"djmw", 20160406)
INTRO (U"A command that creates a @TextGrid in which the silent and sounding intervals of the selected @Sound are marked.")
ENTRY (U"Settings")
xxx_to_TextGrid_detectSilences_COMMON_PARAMETERS_HELP
ENTRY (U"Algorithm")
-NORMAL (U"First the intensity is determined according to the @@Sound: To Intensity...@ command. "
- "Next the silent and sounding intervas are determined as in the @@Intensity: To TextGrid (silences)...@ command.")
+NORMAL (U"First a copy of the sound is @@Sound: Filter (pass Hann band)...|bandpass filtered@ between 80 and 8000 Hz to "
+ "remove especially the low frequency noise that can have a significant influence on the intensity measurement but does not "
+ "really contribute to the sound. Next the @@Sound: To Intensity...|intensity of the filtered sound@ is determined. "
+ "Finally the silent and sounding intervals are determined @@Intensity: To TextGrid (silences)...|from the intensity curve at .")
MAN_END
MAN_BEGIN (U"Intensity: To TextGrid (silences)...", U"djmw", 20061201)
diff --git a/dwtools/praat_David_init.cpp b/dwtools/praat_David_init.cpp
index 015dc10..3c11cbc 100644
--- a/dwtools/praat_David_init.cpp
+++ b/dwtools/praat_David_init.cpp
@@ -2009,6 +2009,29 @@ DO
}
END
+
+FORM (DTW_drawWarpY, U"DTW: Draw warp (y)", U"DTW: Draw warp (y)...")
+ REAL (U"left Horizontal range", U"0.0")
+ REAL (U"right Horizontal range", U"0.0")
+ REAL (U"left Vertical range", U"0.0")
+ REAL (U"right Vertical range", U"0.0")
+ REAL (U"Time (s)", U"0.1")
+ BOOLEAN (U"Garnish", false);
+ OK
+DO
+ autoPraatPicture picture;
+ LOOP {
+ iam (DTW);
+ DTW_drawWarpY (me, GRAPHICS,
+ GET_REAL (U"left Horizontal range"),
+ GET_REAL (U"right Horizontal range"),
+ GET_REAL (U"left Vertical range"),
+ GET_REAL (U"right Vertical range"),
+ GET_REAL (U"Time"),
+ GET_INTEGER (U"Garnish"));
+ }
+END
+
DIRECT (DTW_getStartTimeX)
LOOP {
iam (DTW);
@@ -2138,7 +2161,7 @@ FORM (DTW_getPathY, U"DTW: Get time along path", U"DTW: Get time along path...")
DO
LOOP {
iam (DTW);
- Melder_information (DTW_getPathY (me, GET_REAL (U"Time")));
+ Melder_information (DTW_getYTimeFromXTime (me, GET_REAL (U"Time")));
}
END
@@ -2149,7 +2172,7 @@ DO
double time = GET_REAL (U"Time at x");
LOOP {
iam (DTW);
- Melder_information (DTW_getYTimeFromXTime (me, time), U" s (= y time at z time ", time, U")");
+ Melder_information (DTW_getYTimeFromXTime (me, time), U" s (= y time at x time ", time, U")");
}
END
@@ -6821,7 +6844,7 @@ DO
iam (SpeechSynthesizer);
autoTextGrid tg;
autoTable t;
- autoSound thee = SpeechSynthesizer_to_Sound (me, text, ( createTextGrid ? & tg : nullptr ), ( Melder_debug == -2 ? & t : nullptr ));
+ autoSound thee = SpeechSynthesizer_to_Sound (me, text, (createTextGrid ? & tg : nullptr), (Melder_debug == -2 ? & t : nullptr ));
praat_new (thee.move(), my name);
if (createTextGrid) {
praat_new (tg.move(), my name);
@@ -8540,22 +8563,22 @@ static autoDaata cmuAudioFileRecognizer (int nread, const char *header, MelderFi
}
void praat_CC_init (ClassInfo klas) {
- praat_addAction1 (klas, 1, U"Paint...", 0, 1, DO_CC_paint);
- praat_addAction1 (klas, 1, U"Draw...", 0, 1, DO_CC_drawC0);
- praat_addAction1 (klas, 1, QUERY_BUTTON, 0, 0, 0);
+ praat_addAction1 (klas, 1, U"Paint...", nullptr, 1, DO_CC_paint);
+ praat_addAction1 (klas, 1, U"Draw...", nullptr, 1, DO_CC_drawC0);
+ praat_addAction1 (klas, 1, QUERY_BUTTON, nullptr, 0, 0);
praat_TimeFrameSampled_query_init (klas);
- praat_addAction1 (klas, 1, U"Get number of coefficients...", 0, 1, DO_CC_getNumberOfCoefficients);
- praat_addAction1 (klas, 1, U"Get value in frame...", 0, 1, DO_CC_getValueInFrame);
- praat_addAction1 (klas, 1, U"Get c0 value in frame...", 0, 1, DO_CC_getC0ValueInFrame);
- praat_addAction1 (klas, 1, U"Get value...", 0, praat_HIDDEN + praat_DEPTH_1, DO_CC_getValue);
- praat_addAction1 (klas, 0, U"To Matrix", 0, 0, DO_CC_to_Matrix);
- praat_addAction1 (klas, 2, U"To DTW...", 0, 0, DO_CCs_to_DTW);
+ praat_addAction1 (klas, 1, U"Get number of coefficients...", nullptr, 1, DO_CC_getNumberOfCoefficients);
+ praat_addAction1 (klas, 1, U"Get value in frame...", nullptr, 1, DO_CC_getValueInFrame);
+ praat_addAction1 (klas, 1, U"Get c0 value in frame...", nullptr, 1, DO_CC_getC0ValueInFrame);
+ praat_addAction1 (klas, 1, U"Get value...", nullptr, praat_HIDDEN + praat_DEPTH_1, DO_CC_getValue);
+ praat_addAction1 (klas, 0, U"To Matrix", nullptr, 0, DO_CC_to_Matrix);
+ praat_addAction1 (klas, 2, U"To DTW...", nullptr, 0, DO_CCs_to_DTW);
}
static void praat_Eigen_Matrix_project (ClassInfo klase, ClassInfo klasm); // deprecated 2014
static void praat_Eigen_Matrix_project (ClassInfo klase, ClassInfo klasm) {
- praat_addAction2 (klase, 1, klasm, 1, U"Project...", 0, praat_HIDDEN, DO_Eigen_and_Matrix_projectColumns);
- praat_addAction2 (klase, 1, klasm, 1, U"To Matrix (project columns)...", 0, praat_HIDDEN, DO_Eigen_and_Matrix_projectColumns);
+ praat_addAction2 (klase, 1, klasm, 1, U"Project...", nullptr, praat_HIDDEN, DO_Eigen_and_Matrix_projectColumns);
+ praat_addAction2 (klase, 1, klasm, 1, U"To Matrix (project columns)...", nullptr, praat_HIDDEN, DO_Eigen_and_Matrix_projectColumns);
}
static void praat_Eigen_Spectrogram_project (ClassInfo klase, ClassInfo klasm);
@@ -8601,44 +8624,44 @@ static void praat_BandFilterSpectrogram_draw_init (ClassInfo klas) {
void praat_Matrixft_query_init (ClassInfo klas);
void praat_Matrixft_query_init (ClassInfo klas) {
praat_TimeFrameSampled_query_init (klas);
- praat_addAction1 (klas, 1, U"Get time from column...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getXofColumn);
- praat_addAction1 (klas, 1, U"-- frequencies --", 0, praat_DEPTH_1, 0);
- praat_addAction1 (klas, 1, U"Get lowest frequency", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getLowestFrequency);
- praat_addAction1 (klas, 1, U"Get highest frequency", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getHighestFrequency);
- praat_addAction1 (klas, 1, U"Get number of frequencies", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getNumberOfFrequencies);
- praat_addAction1 (klas, 1, U"Get frequency distance", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getFrequencyDistance);
- praat_addAction1 (klas, 1, U"Get frequency from row...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getFrequencyOfRow);
- praat_addAction1 (klas, 1, U"-- get value --", 0, praat_DEPTH_1, 0);
- praat_addAction1 (klas, 1, U"Get value in cell...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getValueInCell);
+ praat_addAction1 (klas, 1, U"Get time from column...", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getXofColumn);
+ praat_addAction1 (klas, 1, U"-- frequencies --", nullptr, praat_DEPTH_1, 0);
+ praat_addAction1 (klas, 1, U"Get lowest frequency", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getLowestFrequency);
+ praat_addAction1 (klas, 1, U"Get highest frequency", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getHighestFrequency);
+ praat_addAction1 (klas, 1, U"Get number of frequencies", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getNumberOfFrequencies);
+ praat_addAction1 (klas, 1, U"Get frequency distance", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getFrequencyDistance);
+ praat_addAction1 (klas, 1, U"Get frequency from row...", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getFrequencyOfRow);
+ praat_addAction1 (klas, 1, U"-- get value --", nullptr, praat_DEPTH_1, 0);
+ praat_addAction1 (klas, 1, U"Get value in cell...", nullptr, praat_DEPTH_1, DO_BandFilterSpectrogram_getValueInCell);
}
void praat_Matrixtype_query_init (ClassInfo klas);
void praat_Matrixtype_query_init (ClassInfo klas) {
praat_TimeFrameSampled_query_init (klas);
- praat_addAction1 (klas, 1, U"Get time from column...", 0, praat_DEPTH_1, DO_FilterBank_getXofColumn);
- praat_addAction1 (klas, 1, U"-- frequencies --", 0, praat_DEPTH_1, 0);
- praat_addAction1 (klas, 1, U"Get lowest frequency", 0, praat_DEPTH_1, DO_FilterBank_getLowestFrequency);
- praat_addAction1 (klas, 1, U"Get highest frequency", 0, praat_DEPTH_1, DO_FilterBank_getHighestFrequency);
- praat_addAction1 (klas, 1, U"Get number of frequencies", 0, praat_DEPTH_1, DO_FilterBank_getNumberOfFrequencies);
- praat_addAction1 (klas, 1, U"Get frequency distance", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyDistance);
- praat_addAction1 (klas, 1, U"Get frequency from row...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyOfRow);
- praat_addAction1 (klas, 1, U"-- get value --", 0, praat_DEPTH_1, 0);
- praat_addAction1 (klas, 1, U"Get value in cell...", 0, praat_DEPTH_1, DO_FilterBank_getValueInCell);
+ praat_addAction1 (klas, 1, U"Get time from column...", nullptr, praat_DEPTH_1, DO_FilterBank_getXofColumn);
+ praat_addAction1 (klas, 1, U"-- frequencies --", nullptr, praat_DEPTH_1, 0);
+ praat_addAction1 (klas, 1, U"Get lowest frequency", nullptr, praat_DEPTH_1, DO_FilterBank_getLowestFrequency);
+ praat_addAction1 (klas, 1, U"Get highest frequency", nullptr, praat_DEPTH_1, DO_FilterBank_getHighestFrequency);
+ praat_addAction1 (klas, 1, U"Get number of frequencies", nullptr, praat_DEPTH_1, DO_FilterBank_getNumberOfFrequencies);
+ praat_addAction1 (klas, 1, U"Get frequency distance", nullptr, praat_DEPTH_1, DO_FilterBank_getFrequencyDistance);
+ praat_addAction1 (klas, 1, U"Get frequency from row...", nullptr, praat_DEPTH_1, DO_FilterBank_getFrequencyOfRow);
+ praat_addAction1 (klas, 1, U"-- get value --", nullptr, praat_DEPTH_1, 0);
+ praat_addAction1 (klas, 1, U"Get value in cell...", nullptr, praat_DEPTH_1, DO_FilterBank_getValueInCell);
}
static void praat_FilterBank_query_init (ClassInfo klas);
static void praat_FilterBank_query_init (ClassInfo klas) {
- praat_addAction1 (klas, 0, QUERY_BUTTON, 0, 0, 0);
+ praat_addAction1 (klas, 0, QUERY_BUTTON, nullptr, 0, 0);
praat_Matrixtype_query_init (klas);
- praat_addAction1 (klas, 0, U"-- frequency scales --", 0, praat_DEPTH_1, 0);
- praat_addAction1 (klas, 1, U"Get frequency in Hertz...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyInHertz);
- praat_addAction1 (klas, 1, U"Get frequency in Bark...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyInBark);
- praat_addAction1 (klas, 1, U"Get frequency in mel...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyInMel);
+ praat_addAction1 (klas, 0, U"-- frequency scales --", nullptr, praat_DEPTH_1, 0);
+ praat_addAction1 (klas, 1, U"Get frequency in Hertz...", nullptr, praat_DEPTH_1, DO_FilterBank_getFrequencyInHertz);
+ praat_addAction1 (klas, 1, U"Get frequency in Bark...", nullptr, praat_DEPTH_1, DO_FilterBank_getFrequencyInBark);
+ praat_addAction1 (klas, 1, U"Get frequency in mel...", nullptr, praat_DEPTH_1, DO_FilterBank_getFrequencyInMel);
}
static void praat_FilterBank_modify_init (ClassInfo klas);
static void praat_FilterBank_modify_init (ClassInfo klas) {
- // praat_addAction1 (klas, 0, MODIFY_BUTTON, 0, 0, 0);
+ // praat_addAction1 (klas, 0, MODIFY_BUTTON, nullptr, 0, 0);
praat_addAction1 (klas, 0, U"Equalize intensities...", nullptr, praat_DEPTH_1, DO_FilterBank_equalizeIntensities);
}
@@ -9064,6 +9087,7 @@ void praat_uvafon_David_init () {
praat_addAction1 (classDTW, 0, U"Draw path...", nullptr, 1, DO_DTW_drawPath);
praat_addAction1 (classDTW, 0, U"Paint distances...", nullptr, 1, DO_DTW_paintDistances);
praat_addAction1 (classDTW, 0, U"Draw warp (x)...", nullptr, 1, DO_DTW_drawWarpX);
+ praat_addAction1 (classDTW, 0, U"Draw warp (y)...", nullptr, 1, DO_DTW_drawWarpY);
praat_addAction1 (classDTW, 0, QUERY_BUTTON, nullptr, 0, 0);
praat_addAction1 (classDTW, 1, U"Query time domains", nullptr, 1, 0);
praat_addAction1 (classDTW, 1, U"Get start time (x)", nullptr, 2, DO_DTW_getStartTimeX);
diff --git a/fon/Pitch_Intensity.cpp b/fon/Pitch_Intensity.cpp
index 68d9f29..ab3175b 100644
--- a/fon/Pitch_Intensity.cpp
+++ b/fon/Pitch_Intensity.cpp
@@ -73,6 +73,21 @@ void Pitch_Intensity_draw (Pitch pitch, Intensity intensity, Graphics g,
}
}
+double Pitch_Intensity_getMean (Pitch thee, Intensity me) {
+ long numberOfValidLocalMeasurements = 0;
+ double sumOfLocalValues = 0.0;
+ for (long iframe = 1; iframe <= my nx; iframe ++) {
+ double t = Sampled_indexToX (me, iframe);
+ bool localMeasurentIsValid = Pitch_isVoiced_t (thee, t);
+ if (localMeasurentIsValid) {
+ double localValue = my z [1] [iframe];
+ sumOfLocalValues += localValue;
+ numberOfValidLocalMeasurements += 1;
+ }
+ }
+ return numberOfValidLocalMeasurements > 0 ? sumOfLocalValues / numberOfValidLocalMeasurements : NUMundefined;
+}
+
double Pitch_Intensity_getMeanAbsoluteSlope (Pitch thee, Intensity me) {
long numberOfValidLocalMeasurements = 0;
double sumOfLocalAbsoluteSlopes = 0.0;
diff --git a/fon/Pitch_Intensity.h b/fon/Pitch_Intensity.h
index dedc5c8..b6b91ae 100644
--- a/fon/Pitch_Intensity.h
+++ b/fon/Pitch_Intensity.h
@@ -24,6 +24,8 @@
void Pitch_Intensity_draw (Pitch pitch, Intensity intensity, Graphics g,
double f1, double f2, double s1, double s2, bool garnish, int connect);
+double Pitch_Intensity_getMean (Pitch thee, Intensity me);
+
double Pitch_Intensity_getMeanAbsoluteSlope (Pitch pitch, Intensity intensity);
/* End of file Pitch_Intensity.h */
diff --git a/fon/TextGrid_Sound.cpp b/fon/TextGrid_Sound.cpp
index 9e4529a..6d7f4e1 100644
--- a/fon/TextGrid_Sound.cpp
+++ b/fon/TextGrid_Sound.cpp
@@ -25,16 +25,19 @@
static bool IntervalTier_check (IntervalTier me) {
for (long iinterval = 1; iinterval <= my intervals.size; iinterval ++) {
TextInterval interval = my intervals.at [iinterval];
- if (interval -> xmin >= interval -> xmax)
+ if (interval -> xmin >= interval -> xmax) {
+ Melder_casual (U"Interval ", iinterval, U" starts at ", interval -> xmin,
+ U" but ends at ", interval -> xmax, U" seconds.");
return false;
+ }
}
if (my intervals.size < 2) return true;
for (long iinterval = 1; iinterval < my intervals.size; iinterval ++) {
TextInterval thisInterval = my intervals.at [iinterval];
TextInterval nextInterval = my intervals.at [iinterval + 1];
if (thisInterval -> xmax != nextInterval -> xmin) {
- //Melder_casual (U"Interval ", iinterval, U" ends at ", thisInterval -> xmax,
- // U" but the next interval starts at ", nextInterval -> xmin, U" seconds.");
+ Melder_casual (U"Interval ", iinterval, U" ends at ", thisInterval -> xmax,
+ U" but the next interval starts at ", nextInterval -> xmin, U" seconds.");
return false;
}
}
@@ -163,32 +166,28 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
double silenceThreshold = -35.0, minSilenceDuration = 0.1, minSoundingDuration = 0.1;
autoTextGrid analysis;
if (! Melder_equ (interval -> text, U"")) {
- try {
- analysis = SpeechSynthesizer_and_Sound_and_TextInterval_align
- (synthesizer.get(), part.get(), interval, silenceThreshold, minSilenceDuration, minSoundingDuration);
- } catch (MelderError) {
- Melder_clearError (); // ignore all error messages from DTW and the like
- }
+ analysis = SpeechSynthesizer_and_Sound_and_TextInterval_align
+ (synthesizer.get(), part.get(), interval, silenceThreshold, minSilenceDuration, minSoundingDuration);
}
if (analysis) {
/*
* Clean up the analysis.
*/
- Melder_assert (analysis -> xmin == interval -> xmin);
+ Melder_assert (fabs (analysis -> xmin - interval -> xmin) < 1e-12);
if (analysis -> xmax != interval -> xmax) {
- analysis -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [1]) -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [2]) -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [3]) -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [4]) -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [1]) -> intervals.at [((IntervalTier) analysis -> tiers->at [1]) -> intervals.size] -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [2]) -> intervals.at [((IntervalTier) analysis -> tiers->at [2]) -> intervals.size] -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [3]) -> intervals.at [((IntervalTier) analysis -> tiers->at [3]) -> intervals.size] -> xmax = interval -> xmax;
- ((IntervalTier) analysis -> tiers->at [4]) -> intervals.at [((IntervalTier) analysis -> tiers->at [4]) -> intervals.size] -> xmax = interval -> xmax;
//Melder_fatal (U"Analysis ends at ", analysis -> xmax, U" but interval at ", interval -> xmax, U"seconds.");
+ analysis -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (1) -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (2) -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (3) -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (4) -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (1) -> intervals.at [analysis -> intervalTier_cast (1) -> intervals.size] -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (2) -> intervals.at [analysis -> intervalTier_cast (2) -> intervals.size] -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (3) -> intervals.at [analysis -> intervalTier_cast (3) -> intervals.size] -> xmax = interval -> xmax;
+ analysis -> intervalTier_cast (4) -> intervals.at [analysis -> intervalTier_cast (4) -> intervals.size] -> xmax = interval -> xmax;
}
Melder_assert (analysis -> tiers->size == 4);
- Thing_cast (IntervalTier, analysisWordTier, analysis -> tiers->at [3]);
+ IntervalTier analysisWordTier = analysis -> intervalTier_cast (3);
if (! IntervalTier_check (analysisWordTier))
Melder_throw (U"Analysis word tier out of order.");
IntervalTier_removeEmptyIntervals (analysisWordTier, nullptr);
@@ -202,7 +201,7 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
Melder_fatal (U"analysis ends at ", analysis -> xmax, U", but last interval at ", lastInterval -> xmax, U" seconds");
if (! IntervalTier_check (analysisWordTier))
Melder_throw (U"Analysis word tier out of order (2).");
- Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers->at [4]);
+ IntervalTier analysisPhonemeTier = analysis -> intervalTier_cast (4);
if (! IntervalTier_check (analysisPhonemeTier))
Melder_throw (U"Analysis phoneme tier out of order.");
IntervalTier_removeEmptyIntervals (analysisPhonemeTier, analysisWordTier);
@@ -228,7 +227,7 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
autoMelderString newWordTierName;
MelderString_copy (& newWordTierName, headTier -> name, U"/word");
for (long itier = 1; itier <= my tiers->size; itier ++) {
- IntervalTier tier = static_cast <IntervalTier> (my tiers->at [itier]);
+ Function tier = my tiers->at [itier];
if (Melder_equ (newWordTierName.string, tier -> name)) {
if (tier -> classInfo != classIntervalTier)
Melder_throw (U"A tier with the prospective word tier name (", tier -> name, U") already exists, but it is not an interval tier."
@@ -254,7 +253,7 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
long wordIntervalNumber = IntervalTier_hasTime (wordTier, interval -> xmin);
Melder_assert (wordIntervalNumber != 0);
if (analysis) {
- Thing_cast (IntervalTier, analysisWordTier, analysis -> tiers->at [3]);
+ IntervalTier analysisWordTier = analysis -> intervalTier_cast (3);
if (! IntervalTier_check (analysisWordTier))
Melder_throw (U"Analysis word tier out of order (3).");
if (! IntervalTier_check (wordTier))
@@ -290,7 +289,7 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
autoMelderString newPhonemeTierName;
MelderString_copy (& newPhonemeTierName, headTier -> name, U"/phon");
for (long itier = 1; itier <= my tiers->size; itier ++) {
- IntervalTier tier = (IntervalTier) my tiers->at [itier];
+ Function tier = my tiers->at [itier];
if (Melder_equ (newPhonemeTierName.string, tier -> name)) {
if (tier -> classInfo != classIntervalTier)
Melder_throw (U"A tier with the prospective phoneme tier name (", tier -> name, U") already exists, but it is not an interval tier."
@@ -306,7 +305,7 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
phonemeTierNumber = wordTierNumber ? wordTierNumber + 1 : tierNumber + 1);
}
Melder_assert (phonemeTierNumber >= 1 && phonemeTierNumber <= my tiers->size);
- phonemeTier = static_cast <IntervalTier> (my tiers->at [phonemeTierNumber]);
+ phonemeTier = my intervalTier_cast (phonemeTierNumber);
/*
* Make sure that the phoneme tier has boundaries at the edges of the interval.
*/
@@ -317,7 +316,7 @@ void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierN
long phonemeIntervalNumber = IntervalTier_hasTime (phonemeTier, interval -> xmin);
Melder_assert (phonemeIntervalNumber != 0);
if (analysis.get()) {
- Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers->at [4]);
+ IntervalTier analysisPhonemeTier = analysis -> intervalTier_cast (4);
for (long ianalysisInterval = 1; ianalysisInterval <= analysisPhonemeTier -> intervals.size; ianalysisInterval ++) {
TextInterval analysisInterval = analysisPhonemeTier -> intervals.at [ianalysisInterval];
TextInterval phonemeInterval = nullptr;
@@ -394,7 +393,7 @@ void TextGrid_Sound_draw (TextGrid me, Sound sound, Graphics g, double tmin, dou
if (intmin >= intmax) continue;
if (showBoundaries && intmin > tmin && intmin < tmax) {
Graphics_setLineType (g, Graphics_DOTTED);
- Graphics_line (g, intmin, -1.0, intmin, 1.0); /* In sound part. */
+ Graphics_line (g, intmin, -1.0, intmin, 1.0); // in sound part
Graphics_setLineType (g, Graphics_DRAWN);
}
/* Draw left boundary. */
@@ -415,7 +414,7 @@ void TextGrid_Sound_draw (TextGrid me, Sound sound, Graphics g, double tmin, dou
if (t > tmin && t < tmax) {
if (showBoundaries) {
Graphics_setLineType (g, Graphics_DOTTED);
- Graphics_line (g, t, -1.0, t, 1.0); /* In sound part. */
+ Graphics_line (g, t, -1.0, t, 1.0); // in sound part
Graphics_setLineType (g, Graphics_DRAWN);
}
Graphics_line (g, t, ymin, t, 0.8 * ymin + 0.2 * ymax);
diff --git a/fon/TextGrid_def.h b/fon/TextGrid_def.h
index 1a2c097..ce02807 100644
--- a/fon/TextGrid_def.h
+++ b/fon/TextGrid_def.h
@@ -91,6 +91,13 @@ oo_DEFINE_CLASS (TextGrid, Function)
override;
void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto)
override;
+
+ IntervalTier intervalTier_cast (int32 tierNumber) {
+ return static_cast <IntervalTier> (our tiers -> at [tierNumber]);
+ }
+ TextTier textTier_cast (int32 tierNumber) {
+ return static_cast <TextTier> (our tiers -> at [tierNumber]);
+ }
#endif
oo_END_CLASS (TextGrid)
diff --git a/fon/manual_Script.cpp b/fon/manual_Script.cpp
index dd162f8..ed33de6 100644
--- a/fon/manual_Script.cpp
+++ b/fon/manual_Script.cpp
@@ -1382,7 +1382,7 @@ LIST_ITEM1 (U"@@Scripting 5.2. Expressions@ (numeric, string)")
LIST_ITEM1 (U"@@Scripting 5.3. Jumps@ (if, then, elsif, else, endif)")
LIST_ITEM1 (U"@@Scripting 5.4. Loops@ (for/endfor, while/endwhile, repeat/until)")
LIST_ITEM1 (U"@@Scripting 5.5. Procedures@ (\\@ , procedure)")
-LIST_ITEM1 (U"@@Scripting 5.6. Arrays")
+LIST_ITEM1 (U"@@Scripting 5.6. Arrays and dictionaries")
LIST_ITEM1 (U"@@Scripting 5.7. Including other scripts")
LIST_ITEM1 (U"@@Scripting 5.8. Quitting@ (exitScript)")
LIST_ITEM (U"@@Scripting 6. Communication outside the script")
@@ -2217,7 +2217,7 @@ CODE (U"#for i from 1 to n")
CODE (U"#endfor")
MAN_END
-MAN_BEGIN (U"Scripting 5. Language elements reference", U"ppgb", 20130421)
+MAN_BEGIN (U"Scripting 5. Language elements reference", U"ppgb", 20160405)
NORMAL (U"In a Praat script, you can use variables, expressions, and functions, of numeric as well as string type, "
"and most of the control structures known from other procedural computer languages. "
"The way the distinction between numbers and strings is made, may remind you of the programming language Basic.")
@@ -2226,7 +2226,7 @@ LIST_ITEM (U"@@Scripting 5.2. Expressions@ (numeric, string)")
LIST_ITEM (U"@@Scripting 5.3. Jumps@ (if, then, elsif, else, endif)")
LIST_ITEM (U"@@Scripting 5.4. Loops@ (for/endfor, while/endwhile, repeat/until)")
LIST_ITEM (U"@@Scripting 5.5. Procedures@ (\\@ , procedure)")
-LIST_ITEM (U"@@Scripting 5.6. Arrays@")
+LIST_ITEM (U"@@Scripting 5.6. Arrays and dictionaries@")
LIST_ITEM (U"@@Scripting 5.7. Including other scripts@")
LIST_ITEM (U"@@Scripting 5.8. Quitting@ (exit)")
MAN_END
@@ -2650,7 +2650,7 @@ CODE (U"#endproc")
NORMAL (U"However, this uses variable substitution, a trick better avoided.")
MAN_END
-MAN_BEGIN (U"Scripting 5.6. Arrays", U"ppgb", 20140111)
+MAN_BEGIN (U"Scripting 5.6. Arrays and dictionaries", U"ppgb", 20160405)
NORMAL (U"You can use arrays of numeric and string variables:")
CODE (U"#for i #from 1 #to 5")
CODE1 (U"square [i] = i * i")
@@ -2664,6 +2664,11 @@ CODE (U"#for i #from 1 #to 5")
CODE1 (U"#appendInfoLine: \"The square of \", i, \" is \", square [i]")
CODE (U"#endfor")
NORMAL (U"You can use any number of variables in a script, but you can also use Matrix or Sound objects for arrays.")
+NORMAL (U"In the examples above, the %index into the array was always a number. "
+ " A %hash or %dictionary is an array variable where the index is a string:")
+CODE (U"age [\"John\"] = 36")
+CODE (U"age [\"Babs\"] = 39")
+CODE (U"#writeInfoLine: \"John is \", age [\"John\"], \" years old.\"")
MAN_END
MAN_BEGIN (U"Scripting 5.7. Including other scripts", U"ppgb", 20140111)
diff --git a/fon/manual_tutorials.cpp b/fon/manual_tutorials.cpp
index d4d40a2..16f6716 100644
--- a/fon/manual_tutorials.cpp
+++ b/fon/manual_tutorials.cpp
@@ -23,10 +23,15 @@
void manual_tutorials_init (ManPages me);
void manual_tutorials_init (ManPages me) {
-MAN_BEGIN (U"What's new?", U"ppgb", 20160323)
+MAN_BEGIN (U"What's new?", U"ppgb", 20160421)
INTRO (U"Latest changes in Praat.")
//LIST_ITEM (U"• Manual page about @@drawing a vowel triangle at .")
+NORMAL (U"##6.0.17# (21 April 2016)")
+LIST_ITEM (U"• TextGrid window: better automatic alignment.")
+NORMAL (U"##6.0.16# (5 April 2016)")
+LIST_ITEM (U"• Scripting: \"hashes\": variables can now be indexed with strings rather than only with numbers.")
+LIST_ITEM (U"• TextGrid window: fewer out-of-order messages in automatic alignment.")
NORMAL (U"##6.0.15# (21 March 2016)")
LIST_ITEM (U"• TextGrid window: removed a bug whereby Praat could do automatic alignment only on sounds sampled at 44.1 kHz.")
LIST_ITEM (U"• TextGrid window: improved the location of the final boundary in automatic alignment.")
@@ -569,7 +574,7 @@ LIST_ITEM (U"• Scripting: support for arrays with multiple indexes.")
LIST_ITEM (U"• Linux: made spectrogram drawing compatible with Ubuntu 10.10.")
LIST_ITEM (U"• Linux: made sound more easily available on Ubuntu 10.10.")
NORMAL (U"##5.2.01# (4 November 2010)")
-LIST_ITEM (U"• Scripting: support for numeric @@Scripting 5.6. Arrays|arrays at .")
+LIST_ITEM (U"• Scripting: support for numeric @@Scripting 5.6. Arrays and dictionaries|arrays at .")
MAN_END
MAN_BEGIN (U"What was new in 5.2?", U"ppgb", 20101029)
diff --git a/fon/praat_Fon.cpp b/fon/praat_Fon.cpp
index 4c5f22c..f64333e 100644
--- a/fon/praat_Fon.cpp
+++ b/fon/praat_Fon.cpp
@@ -1870,6 +1870,18 @@ DO
GET_REAL (U"From intensity"), GET_REAL (U"To intensity"), GET_INTEGER (U"Garnish"), 1);
END2 }
+DIRECT2 (Pitch_Intensity_getMean) {
+ Pitch pitch = nullptr;
+ Intensity intensity = nullptr;
+ LOOP {
+ if (CLASS == classPitch) pitch = (Pitch) OBJECT;
+ if (CLASS == classIntensity) intensity = (Intensity) OBJECT;
+ if (pitch && intensity) break; // OPTIMIZE
+ }
+ double value = Pitch_Intensity_getMean (pitch, intensity);
+ Melder_informationReal (value, U"dB");
+END2 }
+
DIRECT2 (Pitch_Intensity_getMeanAbsoluteSlope) {
Pitch pitch = nullptr;
Intensity intensity = nullptr;
@@ -7216,6 +7228,7 @@ praat_addAction1 (classTransition, 0, U"Cast", nullptr, 0, nullptr);
praat_addAction2 (classIntensity, 1, classPitch, 1, U"Draw", nullptr, 0, nullptr);
praat_addAction2 (classIntensity, 1, classPitch, 1, U"Draw (phonetogram)...", nullptr, 0, DO_Pitch_Intensity_draw);
praat_addAction2 (classIntensity, 1, classPitch, 1, U"Speckle (phonetogram)...", nullptr, praat_HIDDEN, DO_Pitch_Intensity_speckle); /* grandfathered 2005 */
+ praat_addAction2 (classIntensity, 1, classPitch, 1, U"Get mean", nullptr, 1, DO_Pitch_Intensity_getMean);
praat_addAction2 (classIntensity, 1, classPitch, 1, U"Get mean absolute slope", nullptr, 1, DO_Pitch_Intensity_getMeanAbsoluteSlope);
praat_addAction2 (classIntensity, 1, classPointProcess, 1, U"To IntensityTier", nullptr, 0, DO_Intensity_PointProcess_to_IntensityTier);
praat_addAction2 (classIntensityTier, 1, classPointProcess, 1, U"To IntensityTier", nullptr, 0, DO_IntensityTier_PointProcess_to_IntensityTier);
diff --git a/main/GNU_General_Public_License.txt b/main/GNU_General_Public_License.txt
index c92e00f..1e12414 100644
--- a/main/GNU_General_Public_License.txt
+++ b/main/GNU_General_Public_License.txt
@@ -3,7 +3,7 @@ GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/sys/Formula.cpp b/sys/Formula.cpp
index caf3ba9..77f0cfb 100644
--- a/sys/Formula.cpp
+++ b/sys/Formula.cpp
@@ -3053,9 +3053,13 @@ static void do_indexedNumericVariable () {
w -= nindex;
for (int iindex = 1; iindex <= nindex; iindex ++) {
Stackel index = & theStack [w + iindex];
- if (index -> which != Stackel_NUMBER)
- Melder_throw (U"In indexed variables, the index has to be a number, not ", Stackel_whichText (index), U".");
- MelderString_append (& totalVariableName, index -> number, iindex == nindex ? U"]" : U",");
+ if (index -> which == Stackel_NUMBER) {
+ MelderString_append (& totalVariableName, index -> number, iindex == nindex ? U"]" : U",");
+ } else if (index -> which == Stackel_STRING) {
+ MelderString_append (& totalVariableName, U"\"", index -> string, U"\"", iindex == nindex ? U"]" : U",");
+ } else {
+ Melder_throw (U"In indexed variables, the index has to be a number or a string, not ", Stackel_whichText (index), U".");
+ }
}
InterpreterVariable var = Interpreter_hasVariable (theInterpreter, totalVariableName.string);
if (! var)
@@ -3074,9 +3078,13 @@ static void do_indexedStringVariable () {
w -= nindex;
for (int iindex = 1; iindex <= nindex; iindex ++) {
Stackel index = & theStack [w + iindex];
- if (index -> which != Stackel_NUMBER)
- Melder_throw (U"In indexed variables, the index has to be a number, not ", Stackel_whichText (index), U".");
- MelderString_append (& totalVariableName, index -> number, iindex == nindex ? U"]" : U",");
+ if (index -> which == Stackel_NUMBER) {
+ MelderString_append (& totalVariableName, index -> number, iindex == nindex ? U"]" : U",");
+ } else if (index -> which == Stackel_STRING) {
+ MelderString_append (& totalVariableName, U"\"", index -> string, U"\"", iindex == nindex ? U"]" : U",");
+ } else {
+ Melder_throw (U"In indexed variables, the index has to be a number or a string, not ", Stackel_whichText (index), U".");
+ }
}
InterpreterVariable var = Interpreter_hasVariable (theInterpreter, totalVariableName.string);
if (! var)
diff --git a/sys/GuiText.cpp b/sys/GuiText.cpp
index 5e68952..2ce127e 100644
--- a/sys/GuiText.cpp
+++ b/sys/GuiText.cpp
@@ -464,7 +464,7 @@ static void NativeText_getText (GuiObject widget, char32 *buffer, long length) {
buffer [j] = U'\0';
DisposeHandle (han);
}
- buffer [length] = L'\0'; // superfluous?
+ buffer [length] = U'\0'; // superfluous?
}
#endif
diff --git a/sys/Interpreter.cpp b/sys/Interpreter.cpp
index be3d2dd..78ed773 100644
--- a/sys/Interpreter.cpp
+++ b/sys/Interpreter.cpp
@@ -1555,9 +1555,15 @@ void Interpreter_run (Interpreter me, char32 *text) {
}
if (*p == U'\n' || *p == U'\0')
Melder_throw (U"Missing closing bracket (]) in indexed variable.");
- double numericIndexValue;
- Interpreter_numericExpression (me, index.string, & numericIndexValue);
- MelderString_append (& indexedVariableName, numericIndexValue);
+ struct Formula_Result result;
+ Interpreter_anyExpression (me, index.string, & result);
+ if (result.expressionType == kFormula_EXPRESSION_TYPE_NUMERIC) {
+ double numericIndexValue = result.result.numericResult;
+ MelderString_append (& indexedVariableName, numericIndexValue);
+ } else if (result.expressionType == kFormula_EXPRESSION_TYPE_STRING) {
+ MelderString_append (& indexedVariableName, U"\"", result.result.stringResult, U"\"");
+ Melder_free (result.result.stringResult);
+ }
MelderString_appendCharacter (& indexedVariableName, *p);
if (*p == U']') {
break;
@@ -1694,8 +1700,15 @@ void Interpreter_run (Interpreter me, char32 *text) {
}
if (*p == U'\n' || *p == U'\0')
Melder_throw (U"Missing closing bracket (]) in indexed variable.");
- Interpreter_numericExpression (me, index.string, & value);
- MelderString_append (& indexedVariableName, value);
+ struct Formula_Result result;
+ Interpreter_anyExpression (me, index.string, & result);
+ if (result.expressionType == kFormula_EXPRESSION_TYPE_NUMERIC) {
+ double numericIndexValue = result.result.numericResult;
+ MelderString_append (& indexedVariableName, numericIndexValue);
+ } else if (result.expressionType == kFormula_EXPRESSION_TYPE_STRING) {
+ MelderString_append (& indexedVariableName, U"\"", result.result.stringResult, U"\"");
+ Melder_free (result.result.stringResult);
+ }
MelderString_appendCharacter (& indexedVariableName, *p);
if (*p == ']') {
break;
diff --git a/sys/abcio.cpp b/sys/abcio.cpp
index 722eff1..5fa06e0 100644
--- a/sys/abcio.cpp
+++ b/sys/abcio.cpp
@@ -492,9 +492,9 @@ void texputw4 (MelderFile file, const char32 *s, const char32 *s1, const char32
MelderFile_write (file, file -> verbose ? U" = \"" : U"\"");
if (s) {
char32 c;
- while ((c = *s ++) != '\0') {
+ while ((c = *s ++) != U'\0') {
MelderFile_writeCharacter (file, c);
- if (c == '\"') MelderFile_writeCharacter (file, c); // double any internal quotes
+ if (c == U'\"') MelderFile_writeCharacter (file, c); // double any internal quotes
}
}
MelderFile_write (file, file -> verbose ? U"\" " : U"\"");
@@ -756,7 +756,7 @@ int16 bingeti2LE (FILE *f) {
}
}
-uint16_t bingetu2 (FILE *f) {
+uint16 bingetu2 (FILE *f) {
try {
if (binario_16bitBE && Melder_debug != 18) {
uint16 s;
@@ -774,7 +774,7 @@ uint16_t bingetu2 (FILE *f) {
}
}
-uint16_t bingetu2LE (FILE *f) {
+uint16 bingetu2LE (FILE *f) {
try {
if (binario_16bitLE && Melder_debug != 18) {
uint16 s;
@@ -1261,7 +1261,7 @@ void binputr4 (double x, FILE *f) {
int sign, exponent;
double fMantissa, fsMantissa;
uint32 mantissa;
- if (x < 0.0) { sign = 0x0100; x *= -1; }
+ if (x < 0.0) { sign = 0x0100; x *= -1.0; }
else sign = 0;
if (x == 0.0) { exponent = 0; mantissa = 0; }
else {
@@ -1277,7 +1277,7 @@ void binputr4 (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 24);
fsMantissa = floor (fMantissa);
- mantissa = (uint32_t) fsMantissa & 0x007FFFFF;
+ mantissa = (uint32) fsMantissa & 0x007FFFFF;
}
}
bytes [0] = (uint8) (exponent >> 1); // truncate: bits 2 through 9 (bit 9 is the sign bit)
@@ -1301,7 +1301,7 @@ void binputr4LE (double x, FILE *f) {
int sign, exponent;
double fMantissa, fsMantissa;
uint32 mantissa;
- if (x < 0.0) { sign = 0x0100; x *= -1; }
+ if (x < 0.0) { sign = 0x0100; x *= -1.0; }
else sign = 0;
if (x == 0.0) { exponent = 0; mantissa = 0; }
else {
@@ -1317,7 +1317,7 @@ void binputr4LE (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 24);
fsMantissa = floor (fMantissa);
- mantissa = (uint32_t) fsMantissa & 0x007FFFFF;
+ mantissa = (uint32) fsMantissa & 0x007FFFFF;
}
}
bytes [3] = (uint8) (exponent >> 1);
@@ -1340,7 +1340,7 @@ void binputr8 (double x, FILE *f) {
int sign, exponent;
double fMantissa, fsMantissa;
uint32 highMantissa, lowMantissa;
- if (x < 0.0) { sign = 0x0800; x *= -1; }
+ if (x < 0.0) { sign = 0x0800; x *= -1.0; }
else sign = 0;
if (x == 0.0) { exponent = 0; highMantissa = 0; lowMantissa = 0; }
else {
@@ -1356,10 +1356,10 @@ void binputr8 (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 21);
fsMantissa = floor (fMantissa);
- highMantissa = (uint32_t) fsMantissa & 0x000FFFFF;
+ highMantissa = (uint32) fsMantissa & 0x000FFFFF;
fMantissa = ldexp (fMantissa - fsMantissa, 32);
fsMantissa = floor (fMantissa);
- lowMantissa = (uint32_t) fsMantissa;
+ lowMantissa = (uint32) fsMantissa;
}
}
bytes [0] = (uint8) (exponent >> 4);
@@ -1384,7 +1384,7 @@ void binputr10 (double x, FILE *f) {
int sign, exponent; // these should be uint16_t, but frexp() expects an int
double fMantissa, fsMantissa;
uint32_t highMantissa, lowMantissa;
- if (x < 0.0) { sign = 0x8000; x *= -1; }
+ if (x < 0.0) { sign = 0x8000; x *= -1.0; }
else sign = 0;
if (x == 0.0) { exponent = 0; highMantissa = 0; lowMantissa = 0; }
else {
@@ -1400,10 +1400,10 @@ void binputr10 (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 32);
fsMantissa = floor (fMantissa);
- highMantissa = (uint32_t) fsMantissa;
+ highMantissa = (uint32) fsMantissa;
fMantissa = ldexp (fMantissa - fsMantissa, 32);
fsMantissa = floor (fMantissa);
- lowMantissa = (uint32_t) fsMantissa;
+ lowMantissa = (uint32) fsMantissa;
}
}
bytes [0] = (uint8) (exponent >> 8);
@@ -1516,14 +1516,14 @@ char32 * bingetw1 (FILE *f) {
length = bingetu1 (f);
result.reset (Melder_malloc (char32, (int64) length + 1));
for (unsigned short i = 0; i < length; i ++) {
- uint16 kar = bingetu2 (f);
- if ((kar & 0xF800) == 0xD800) {
- if (kar > 0xDBFF)
+ char32 kar = bingetu2 (f);
+ if ((kar & 0x00F800) == 0x00D800) {
+ if (kar > 0x00DBFF)
Melder_throw (U"Incorrect Unicode value (first surrogate member ", kar, U").");
- uint16 kar2 = bingetu2 (f);
- if (kar2 < 0xDC00 || kar2 > 0xDFFF)
+ char32 kar2 = bingetu2 (f);
+ if (kar2 < 0x00DC00 || kar2 > 0x00DFFF)
Melder_throw (U"Incorrect Unicode value (second surrogate member ", kar2, U").");
- result [i] = (((kar & 0x3FF) << 10) | (kar2 & 0x3FF)) + 0x10000;
+ result [i] = (((kar & 0x0003FF) << 10) | (kar2 & 0x0003FF)) + 0x010000;
} else {
result [i] = kar;
}
@@ -1593,15 +1593,15 @@ char32 * bingetw4 (FILE *f) {
*/
length = bingetu4 (f);
result.reset (Melder_malloc (char32, (int64) length + 1));
- for (uint32_t i = 0; i < length; i ++) {
- uint16_t kar = bingetu2 (f);
- if ((kar & 0xF800) == 0xD800) {
- if (kar > 0xDBFF)
+ for (uint32 i = 0; i < length; i ++) {
+ char32 kar = bingetu2 (f);
+ if ((kar & 0x00F800) == 0x00D800) {
+ if (kar > 0x00DBFF)
Melder_throw (U"Incorrect Unicode value (first surrogate member ", kar, U").");
- uint16_t kar2 = bingetu2 (f);
- if (kar2 < 0xDC00 || kar2 > 0xDFFF)
+ char32 kar2 = bingetu2 (f);
+ if (kar2 < 0x00DC00 || kar2 > 0x00DFFF)
Melder_throw (U"Incorrect Unicode value (second surrogate member ", kar2, U").");
- result [i] = (((kar & 0x3FF) << 10) | (kar2 & 0x3FF)) + 0x10000;
+ result [i] = (((kar & 0x0003FF) << 10) | (kar2 & 0x0003FF)) + 0x010000;
} else {
result [i] = kar;
}
@@ -1611,11 +1611,11 @@ char32 * bingetw4 (FILE *f) {
* ASCII
*/
result.reset (Melder_malloc (char32, (int64) length + 1));
- for (uint32_t i = 0; i < length; i ++) {
+ for (uint32 i = 0; i < length; i ++) {
result [i] = bingetu1 (f);
}
}
- result [length] = L'\0';
+ result [length] = U'\0';
return result.transfer();
} catch (MelderError) {
Melder_throw (U"Text not read from a binary file.");
diff --git a/sys/praat_version.h b/sys/praat_version.h
index a77724e..1223757 100644
--- a/sys/praat_version.h
+++ b/sys/praat_version.h
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.0.15
-#define PRAAT_VERSION_NUM 6015
+#define PRAAT_VERSION_STR 6.0.17
+#define PRAAT_VERSION_NUM 6017
#define PRAAT_YEAR 2016
-#define PRAAT_MONTH March
-#define PRAAT_DAY 23
+#define PRAAT_MONTH April
+#define PRAAT_DAY 21
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/praat.git
More information about the debian-med-commit
mailing list