[med-svn] [Git][med-team/praat][master] 4 commits: New upstream version 6.2.09

Rafael Laboissière (@rafael) gitlab at salsa.debian.org
Mon Feb 21 08:18:12 GMT 2022



Rafael Laboissière pushed to branch master at Debian Med / praat


Commits:
39360082 by Rafael Laboissière at 2022-02-19T05:00:03-03:00
New upstream version 6.2.09
- - - - -
5afce189 by Rafael Laboissière at 2022-02-19T05:02:53-03:00
Merge tag 'upstream/6.2.09'

Upstream version 6.2.09

- - - - -
7c779834 by Rafael Laboissière at 2022-02-19T05:10:44-03:00
d/What_s_new_.html: Update upstream changelog

Gbp-Dch: Ignore

- - - - -
28d11a36 by Rafael Laboissière at 2022-02-19T05:12:10-03:00
d/changelog: Add entry for release 6.2.09-1

Gbp-Dch: Ignore

- - - - -


14 changed files:

- debian/What_s_new_.html
- debian/changelog
- dwtools/ConstantQSpectrograms.cpp
- dwtools/ConstantQSpectrograms.h
- dwtools/MultiSampledSpectrogram.cpp
- dwtools/MultiSampledSpectrogram.h
- dwtools/Sound_and_MultiSampledSpectrogram.cpp
- dwtools/Spectrum_and_MultiSampledSpectrogram.cpp
- dwtools/praat_MultiSampledSpectrogram.cpp
- fon/manual_tutorials.cpp
- melder/melder_audio.cpp
- sys/Graphics.cpp
- sys/Graphics_enums.h
- sys/praat_version.h


Changes:

=====================================
debian/What_s_new_.html
=====================================
@@ -7,6 +7,18 @@ What's new?
 <p>
 Latest changes in Praat.</p>
 <p>
+<b>6.2.09</b> (15 February 2022)</p>
+<ul>
+<li>
+ Windows: support for a screen resolution of 204 dpi.
+</ul>
+<p>
+<b>6.2.08</b> (5 February 2022)</p>
+<ul>
+<li>
+ Mac: more checks on audio devices when playing sounds.
+</ul>
+<p>
 <b>6.2.07</b> (28 January 2022)</p>
 <ul>
 <li>
@@ -110,7 +122,7 @@ What used to be new?</h3>
 </ul>
 <hr>
 <address>
-	<p>© ppgb, January 28, 2022</p>
+	<p>© ppgb, February 15, 2022</p>
 </address>
 </body>
 </html>


=====================================
debian/changelog
=====================================
@@ -1,3 +1,9 @@
+praat (6.2.09-1) unstable; urgency=medium
+
+  * New upstream version 6.2.09
+
+ -- Rafael Laboissière <rafael at debian.org>  Sat, 19 Feb 2022 05:10:50 -0300
+
 praat (6.2.07-1) unstable; urgency=medium
 
   * New upstream version 6.2.07


=====================================
dwtools/ConstantQSpectrograms.cpp
=====================================
@@ -1,6 +1,6 @@
 /* ConstantQLog2FSpectrogram.cpp
  * 
- * Copyright (C) 2021 David Weenink
+ * Copyright (C) 2021-2022 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
@@ -43,14 +43,14 @@ double structConstantQLog2FSpectrogram :: v_hertzToMyFrequencyUnit (double f_hz)
 
 autoConstantQLog2FSpectrogram ConstantQLog2FSpectrogram_create (double tmin, double tmax, double f1, double fmax, integer numberOfBinsPerOctave, double frequencyResolutionInBins) {
 	try {
-		const double dy = 1.0 / numberOfBinsPerOctave;
+		autoConstantQLog2FSpectrogram me = Thing_new (ConstantQLog2FSpectrogram);
+		const double log2_dy = 1.0 / numberOfBinsPerOctave;
 		const integer numberOfBins = Melder_iroundDown (log2 (fmax / f1) * numberOfBinsPerOctave);
 		Melder_require (numberOfBins > 1,
 			U"The number of bins should be larger than 1.");
-		const double log2_f1 = log2 (f1);
-		const double ymin = log2_f1 - 0.5 * dy, ymax = log2 (fmax);		
-		autoConstantQLog2FSpectrogram me = Thing_new (ConstantQLog2FSpectrogram);
-		MultiSampledSpectrogram_init (me.get(), tmin, tmax, ymin, ymax, numberOfBins, dy, log2_f1, frequencyResolutionInBins);
+		const double log2_ymin = log2 (f1);
+		const double log2_f1 = log2_ymin + 0.5 * log2_dy, log2_ymax = log2 (fmax);		
+		MultiSampledSpectrogram_init (me.get(), tmin, tmax, log2_ymin, log2_ymax, numberOfBins, log2_dy, log2_f1, frequencyResolutionInBins);
 		return me;
 	} catch (MelderError) {
 		Melder_throw (U"Could not create ConstantQLog2FSpectrogram.");
@@ -64,17 +64,26 @@ double ConstantQLog2FSpectrogram_getQualityFactor (ConstantQLog2FSpectrogram me)
 
 static void MultiSampledSpectrogram_setFrequencyTicks (MultiSampledSpectrogram me, Graphics g, double fmin, double fmax, double df) {
 	double f = fmin;
-	while (f <= my v_myFrequencyUnitToHertz (fmax) ) {
-		if (f >= fmin) {
-			const double f_hz = my v_myFrequencyUnitToHertz (f);
-			conststring32 f_string = Melder_fixed (f_hz, 1);
-			Graphics_markLeft (g, f, false, true, false, f_string);
-		}
+	while (f <= fmax) {
+		const double f_hz = my v_myFrequencyUnitToHertz (f);
+		conststring32 f_string = Melder_fixed (f_hz, 1);
+		Graphics_markLeft (g, f, false, true, false, f_string);
 		f += df;
 	}
 }
-void ConstantQLog2FSpectrogram_paint (ConstantQLog2FSpectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double dBRange, bool garnish) {
+
+void ConstantQLog2FSpectrogram_paint (ConstantQLog2FSpectrogram me, Graphics g, double tmin, double tmax, double fmin_hz, double fmax_hz, double dBRange, bool garnish) {
 	Graphics_setInner (g);
+	double fmin, fmax;	
+	if (fmin_hz == 0.0 && fmax_hz == 0.0) {
+		fmin = my xmin;
+		fmax = my xmax;
+	} else {
+		fmin = ( fmin_hz > 0.0 ? my v_hertzToMyFrequencyUnit (fmin_hz) : my xmin );
+		fmax = ( fmax_hz > 0.0 ? my v_hertzToMyFrequencyUnit (fmax_hz) : my xmin );
+	}
+	if (! Function_intersectRangeWithDomain (me, & fmin, & fmax))
+		return;
 	MultiSampledSpectrogram_paintInside (me, g, tmin, tmax, fmin, fmax, dBRange);
 	Graphics_unsetInner (g);
 	if (garnish) {
@@ -129,7 +138,10 @@ void structGaborSpectrogram :: v_info () {
 	MelderInfo_writeLine (U"Frequency resolution in bins: ", frequencyResolutionInBins);
 }
 
-void GaborSpectrogram_paint (ConstantQLog2FSpectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double dBRange, bool garnish) {
+void GaborSpectrogram_paint (GaborSpectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double dBRange, bool garnish) {
+	Function_bidirectionalAutowindow (me, & fmin, & fmax);
+	if (! Function_intersectRangeWithDomain (me, & fmin, & fmax))
+		return;
 	Graphics_setInner (g);
 	MultiSampledSpectrogram_paintInside (me, g, tmin, tmax, fmin, fmax, dBRange);
 	Graphics_unsetInner (g);
@@ -138,7 +150,7 @@ void GaborSpectrogram_paint (ConstantQLog2FSpectrogram me, Graphics g, double tm
 		Graphics_textBottom (g, true, U"Time (s)");
 		Graphics_marksBottom (g, 2, true, true, false);
 		Graphics_inqWindow (g, & tmin, & tmax, & fmin, & fmax);
-		MultiSampledSpectrogram_setFrequencyTicks (me, g, fmin, fmax, 1000.0);
+		Graphics_marksLeft (g, 2, true, true, false);
 		Graphics_textLeft (g, true, U"Frequency (Hz)");
 	}
 }


=====================================
dwtools/ConstantQSpectrograms.h
=====================================
@@ -2,7 +2,7 @@
 #define _ConstantQSpectrograms_h_
 /* ConstantQSpectrograms.h
  * 
- * Copyright (C) 2021 David Weenink
+ * Copyright (C) 2021-2022 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
@@ -55,7 +55,7 @@ Thing_define (GaborSpectrogram, MultiSampledSpectrogram) {
 		override { return f; }
 };
 
-void GaborSpectrogram_paint (ConstantQLog2FSpectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double dBRange, bool garnish);
+void GaborSpectrogram_paint (GaborSpectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double dBRange, bool garnish);
 
 autoGaborSpectrogram GaborSpectrogram_create (double tmin, double tmax, double fmax, double frequencyResolution, double df);
 


=====================================
dwtools/MultiSampledSpectrogram.cpp
=====================================
@@ -1,6 +1,6 @@
 /* MultiSampledSpectrogram.cpp
  * 
- * Copyright (C) 2021 David Weenink
+ * Copyright (C) 2021-2022 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
@@ -200,39 +200,23 @@ integer MultiSampledSpectrogram_getNumberOfFrames (MultiSampledSpectrogram me) {
 	return numberOfFrames;
 }
 
-void MultiSampledSpectrogram_checkFrequencyRange (MultiSampledSpectrogram me, double *fmin, double *fmax) {
-	if (*fmax <= *fmin) {
-		*fmin = my v_myFrequencyUnitToHertz (my xmin);
-		*fmax = my v_myFrequencyUnitToHertz (my xmax);
-		return;
-	}
-	/*
-		fmin <= 0 is a problem for log-based scales. In this case we take the xmin value as the minimum.
-	*/
-	if (*fmin <= 0.0 && ! isdefined (my v_hertzToMyFrequencyUnit (*fmin))) {
-		if (*fmax <= my v_myFrequencyUnitToHertz (my xmin))
-			*fmin = 0.99 * *fmax; // some positive value will do
-		else
-			*fmin = my v_myFrequencyUnitToHertz (my xmin);
-	}
-}
-
 void MultiSampledSpectrogram_paintInside (MultiSampledSpectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double dBRange) {
 	integer itmin, itmax, ifmin, ifmax;
 	if (tmax <= tmin) {
 		tmin = my tmin;
 		tmax = my tmax;
 	}
-	MultiSampledSpectrogram_checkFrequencyRange (me, & fmin, & fmax);
-	fmin = my v_hertzToMyFrequencyUnit (fmin);
-	fmax = my v_hertzToMyFrequencyUnit (fmax);
+	if (fmax <= fmin) {
+		fmax = my xmax;
+		fmin = my xmin;
+	}
 	if (Sampled_getWindowSamples (me, fmin, fmax, & ifmin, & ifmax) == 0)
 		return;
-	const integer maximumNumberOfFrames = Sampled_getWindowSamples (my frequencyBins.at [ifmax], tmin, tmax, & itmin, & itmax);
-	if (maximumNumberOfFrames == 0)
+	const integer maximumNumberOfTimeFrames = Sampled_getWindowSamples (my frequencyBins.at [ifmax], tmin, tmax, & itmin, & itmax);
+	if (maximumNumberOfTimeFrames == 0)
 		return;	
 	Graphics_setWindow (g, tmin, tmax, fmin, fmax);
-	autoMAT p = raw_MAT (1, maximumNumberOfFrames);	
+	autoMAT p = raw_MAT (1, maximumNumberOfTimeFrames);	
 	/*
 		Find maximum power. No need for logarithm in the test
 	*/
@@ -274,5 +258,4 @@ void MultiSampledSpectrogram_paintInside (MultiSampledSpectrogram me, Graphics g
 	}
 }
 
-
 /* End of file  MultiSampledSpectrogram.cpp */


=====================================
dwtools/MultiSampledSpectrogram.h
=====================================
@@ -2,7 +2,7 @@
 #define _MultiSampledSpectrogram_h_
 /* MultiSampledSpectrogram.h
  * 
- * Copyright (C) 2021 David Weenink
+ * Copyright (C) 2021-2022 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
@@ -19,13 +19,14 @@
  */
 
 #include "AnalyticSound.h"
-#include "Function.h"
 #include "Graphics.h"
-#include "Sampled.h"
-#include "Sound.h"
-#include "Matrix.h"
 #include "MultiSampledSpectrogram_def.h"
-#include "Vector.h"
+
+/*
+	A MultiSampledSpectrogram is a spectrogram that is evenly sampled in the frequency domain (on some possibly non-linear frequency scale).
+	Each "sample" is a FrequencyBin with real and imaginary values.
+	The original sound can be reconstructed from the data in the frequncy bins.
+*/
 
 void FrequencyBin_init (FrequencyBin me, double xmin, double xmax, integer nx, double dx, double x1);
 


=====================================
dwtools/Sound_and_MultiSampledSpectrogram.cpp
=====================================
@@ -1,6 +1,6 @@
 /* Sound_and_MultiSampledSpectrogram.cpp
  * 
- * Copyright (C) 2021 David Weenink
+ * Copyright (C) 2021-2022 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
@@ -27,12 +27,12 @@ autoConstantQLog2FSpectrogram Sound_to_ConstantQLog2FSpectrogram (Sound me, doub
 	kSound_windowShape filterShape) {
 	try {
 		const double nyquistFrequency = 0.5 / my dx;
-		if (fmax <= 0.0)
+		if (fmax <= 0.0 || fmax > nyquistFrequency)
 			fmax = nyquistFrequency;
-		Melder_require (fmax  <= nyquistFrequency,
-			U"The maximum frequency should not exceed the nyquist frequency (", nyquistFrequency, U" Hz).");
 		Melder_require (lowestFrequency < fmax,
 			U"The lowest frequency should be smaller than the maximum frequency (", fmax, U" Hz).");
+		Melder_require (frequencyResolutionInBins > 0.0,
+			U"The frequency resolution should be larger than zero.");
 		Melder_clipLeft (1.0, & timeOversamplingFactor);
 		autoConstantQLog2FSpectrogram thee = ConstantQLog2FSpectrogram_create (my xmin, my xmax,
 			lowestFrequency, fmax, numberOfBinsPerOctave, frequencyResolutionInBins);
@@ -49,12 +49,16 @@ autoGaborSpectrogram Sound_to_GaborSpectrogram (Sound me, double fmax, double fi
 {
 	try {
 		const double nyquistFrequency = 0.5 / my dx;
-		if (fmax <= 0.0)
+		bool resample = true;
+		if (fmax <= 0.0 || fmax > nyquistFrequency) {
 			fmax = nyquistFrequency;
-		Melder_require (fmax  <= nyquistFrequency,
-			U"The maximum frequency should not exceed the nyquist frequency (", nyquistFrequency, U" Hz).");
+			resample = false;
+		}
 		autoGaborSpectrogram thee = GaborSpectrogram_create (my xmin, my xmax, fmax, filterBandwidth, frequencyStep);
-		autoSpectrum him = Sound_and_MultiSampledSpectrogram_to_Spectrum (me, thee.get());
+		autoSound resampled;
+		if (resample)
+			resampled = Sound_resample (me, 2.0 * fmax, 50);
+		autoSpectrum him = Sound_to_Spectrum ((resampled ? resampled.get() : me), true);
 		Spectrum_into_MultiSampledSpectrogram (him.get(), thee.get(), timeOversamplingFactor, filterShape);
 		return thee;
 	} catch (MelderError) {


=====================================
dwtools/Spectrum_and_MultiSampledSpectrogram.cpp
=====================================
@@ -1,6 +1,6 @@
 /* Spectrum_and_MultiSampledSpectrogram.cpp
  * 
- * Copyright (C) 2021 David Weenink
+ * Copyright (C) 2021-2022 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
@@ -40,12 +40,12 @@ static void windowShape_VEC_preallocated (VEC const& target, kSound_windowShape
 		} break; case kSound_windowShape::HANNING: {
 			for (integer i = 1; i <= n; i ++) {
 				const double phase = (double) (i - 0.5) / n;
-				target [i] = 0.5 * (1.0 - cos (2.0 * NUMpi * phase));
+				target [i] = 0.5 * (1.0 - cos (NUM2pi * phase));
 			}
 		} break; case kSound_windowShape::HAMMING: {
 			for (integer i = 1; i <= n; i ++) { 
 				const double phase = (double) (i - 0.5) / n;
-				target [i] = 0.54 - 0.46 * cos (2.0 * NUMpi * phase);
+				target [i] = 0.54 - 0.46 * cos (NUM2pi * phase);
 			}
 		} break; case kSound_windowShape::GAUSSIAN_1: {
 			const double edge = exp (-3.0), onebyedge1 = 1.0 / (1.0 - edge);   // -0.5..+0.5
@@ -78,18 +78,18 @@ static void windowShape_VEC_preallocated (VEC const& target, kSound_windowShape
 				target [i] = (exp (-300.0 * phase * phase) - edge) * onebyedge1;
 			}
 		} break; case kSound_windowShape::KAISER_1: {
-			const double factor = 1.0 / NUMbessel_i0_f (2 * NUMpi);
+			const double factor = 1.0 / NUMbessel_i0_f (NUM2pi);
 			for (integer i = 1; i <= n; i ++) { 
 				const double phase = 2.0 * ((double) i - imid) / n;   // -1..+1
 				const double root = 1.0 - phase * phase;
-				target [i] = ( root <= 0.0 ? 0.0 : factor * NUMbessel_i0_f (2.0 * NUMpi * sqrt (root)) );
+				target [i] = ( root <= 0.0 ? 0.0 : factor * NUMbessel_i0_f (NUM2pi * sqrt (root)) );
 			}
 		} break; case kSound_windowShape::KAISER_2: {
-			const double factor = 1.0 / NUMbessel_i0_f (2 * NUMpi * NUMpi + 0.5);
+			const double factor = 1.0 / NUMbessel_i0_f (NUM2pi * NUMpi + 0.5);
 			for (integer i = 1; i <= n; i ++) { 
 				const double phase = 2.0 * ((double) i - imid) / n;   // -1..+1
 				const double root = 1.0 - phase * phase;
-				target [i] = ( root <= 0.0 ? 0.0 : factor * NUMbessel_i0_f ((2.0 * NUMpi * NUMpi + 0.5) * sqrt (root)) ); 
+				target [i] = ( root <= 0.0 ? 0.0 : factor * NUMbessel_i0_f ((NUM2pi * NUMpi + 0.5) * sqrt (root)) ); 
 			}
 		} break; default: {
 			target  <<=  1.0;
@@ -122,6 +122,7 @@ void Spectrum_into_MultiSampledSpectrogram (Spectrum me, MultiSampledSpectrogram
 	kSound_windowShape filterShape) 
 {
 	try {
+		enum frequencyBinPosition { DC_BIN, NORMAL_BIN, NYQUIST_BIN };
 		const integer maximumFilterSize = 2 * my nx;
 		autoVEC filterWindow = raw_VEC (maximumFilterSize);
 		for (integer ifreq = 1; ifreq <= thy nx; ifreq ++) {
@@ -139,7 +140,7 @@ void Spectrum_into_MultiSampledSpectrogram (Spectrum me, MultiSampledSpectrogram
 			MultiSampledSpectrogram_getFrequencyBand (thee, ifreq, & spectrum_fmin, & spectrum_fmax);
 			double window_fmin = spectrum_fmin, window_fmax = spectrum_fmax;
 			
-			auto toFrequencyBin = [&] (int partOfSpectrum) -> autoFrequencyBin {
+			auto toFrequencyBin = [&] (enum frequencyBinPosition partOfSpectrum) -> autoFrequencyBin {
 				integer window_imin = 0, window_imax = 0;
 				integer spectrum_imin, spectrum_imax;
 				const integer numberOfSamplesFromSpectrum = Sampled_getWindowSamples (me, spectrum_fmin, spectrum_fmax, 
@@ -162,8 +163,8 @@ void Spectrum_into_MultiSampledSpectrogram (Spectrum me, MultiSampledSpectrogram
 					& window_imin, & window_imax);
 				const integer filter_imin = window_imin - spectrum_imin + 1;
 				const integer filter_imax = window_imax - spectrum_imin + 1;
-				window_imax = ( partOfSpectrum == 1 ? filterWindow.size : 
-					( partOfSpectrum == 2 ? window_imax_previous : numberToBeWindowed ) );
+				window_imax = ( partOfSpectrum == NORMAL_BIN ? filterWindow.size : 
+					( partOfSpectrum == DC_BIN ? window_imax_previous : numberToBeWindowed ) );
 				window_imin = window_imax - numberToBeWindowed + 1;
 				window_imax_previous = window_imax;
 				filter -> z.part (1, 2, filter_imin, filter_imax)  *=  
@@ -172,7 +173,7 @@ void Spectrum_into_MultiSampledSpectrogram (Spectrum me, MultiSampledSpectrogram
 				return result;
 			};
 			
-			thy frequencyBins.addItem_move (toFrequencyBin (1).move());
+			thy frequencyBins.addItem_move (toFrequencyBin (NORMAL_BIN).move());
 			if (ifreq == 1) {
 				/*
 					Fill with values from 0 Hz to the mid of the first window
@@ -181,7 +182,7 @@ void Spectrum_into_MultiSampledSpectrogram (Spectrum me, MultiSampledSpectrogram
 				spectrum_fmax = 0.5 * (spectrum_fmin + spectrum_fmax);
 				spectrum_fmin = 0.0;
 				window_fmax = spectrum_fmax;
-				thy zeroBin = toFrequencyBin (2).move();
+				thy zeroBin = toFrequencyBin (DC_BIN).move();
 			}
 			if (ifreq == thy nx) {
 				/*
@@ -191,7 +192,7 @@ void Spectrum_into_MultiSampledSpectrogram (Spectrum me, MultiSampledSpectrogram
 				spectrum_fmin = 0.5 * (spectrum_fmin + spectrum_fmax);
 				window_fmin = spectrum_fmin;
 				spectrum_fmax = thy v_myFrequencyUnitToHertz (thy xmax);
-				thy nyquistBin = toFrequencyBin (3).move();
+				thy nyquistBin = toFrequencyBin (NYQUIST_BIN).move();
 			}
 		}
 		Melder_assert (thy frequencyBins.size == thy nx); // maintain invariant
@@ -207,7 +208,8 @@ autoSpectrum MultiSampledSpectrogram_to_Spectrum (MultiSampledSpectrogram me) {
 		const double samplingFrequency = 2.0 * nyquistFrequency;
 		const integer numberOfSamples = duration * samplingFrequency;
 		const integer numberOfFFTSamples = Melder_clippedLeft (2_integer, Melder_iroundUpToPowerOfTwo (numberOfSamples));   // TODO: explain the edge case
-		autoSpectrum thee = Spectrum_create (nyquistFrequency, numberOfFFTSamples / 2 + 1);
+		const integer numberOfSpectralValues = numberOfFFTSamples / 2 + 1;
+		autoSpectrum thee = Spectrum_create (nyquistFrequency, numberOfSpectralValues);
 		for (integer ifreq = 1; ifreq <= my nx; ifreq ++) {
 			const FrequencyBin frequencyBin = my frequencyBins.at [ifreq];			
 			double flow, fhigh;
@@ -231,6 +233,10 @@ autoSpectrum MultiSampledSpectrogram_to_Spectrum (MultiSampledSpectrogram me) {
 				fillSpectrumPart (my nyquistBin.get());
 			}
 		}
+		/*
+			Make sure the imaginary part of the last spectral value is zero.
+		*/
+		thy z [2] [numberOfSpectralValues] = 0.0;
 		return thee;
 	} catch (MelderError) {
 		Melder_throw (me, U": cannot convert to Spectrum.");


=====================================
dwtools/praat_MultiSampledSpectrogram.cpp
=====================================
@@ -87,6 +87,12 @@ DO
 	CONVERT_EACH_TO_ONE_END (my name.get(), U"_",frequencyBinNumber)
 }
 
+DIRECT (CONVERT_EACH_TO_ONE__MultiSampledSpectrogram_to_Spectrum) {
+	CONVERT_EACH_TO_ONE (MultiSampledSpectrogram)
+		autoSpectrum result = MultiSampledSpectrogram_to_Spectrum (me);
+	CONVERT_EACH_TO_ONE_END (my name.get())
+}
+
 FORM (CONVERT_EACH_TO_ONE__ConstantQLog2FSpectrogram_translateSpectrum, U"", nullptr) {
 	REAL (fromTime, U"From time", U"0.0")
 	REAL (toTime, U"To time", U"0.0 (= all)")
@@ -131,7 +137,7 @@ FORM (GRAPHICS_EACH__GaborSpectrogram_paint, U"GaborSpectrogram: Paint", nullptr
 	BOOLEAN (garnish, U"Garnish", true);
 	OK
 DO
-	GRAPHICS_EACH (ConstantQLog2FSpectrogram)
+	GRAPHICS_EACH (GaborSpectrogram)
 		GaborSpectrogram_paint (me, GRAPHICS, xmin, xmax, ymin, ymax, dBRange, garnish);
 	GRAPHICS_EACH_END
 }
@@ -161,6 +167,8 @@ void praat_MultiSampledSpectrograms_generics (ClassInfo klas) {
 			CONVERT_EACH_TO_ONE__MultiSampledSpectrogram_to_Sound);
 	praat_addAction1 (klas, 0, U"To Sound (frequencyBin)...", nullptr, 0,
 			CONVERT_EACH_TO_ONE__MultiSampledSpectrogram_to_Sound_frequencyBin);
+	praat_addAction1 (klas, 0, U"To Spectrum", nullptr, 0,
+			CONVERT_EACH_TO_ONE__MultiSampledSpectrogram_to_Spectrum);
 }
 
 void praat_MultiSampledSpectrogram_init ();


=====================================
fon/manual_tutorials.cpp
=====================================
@@ -22,11 +22,15 @@
 void manual_tutorials_init (ManPages me);
 void manual_tutorials_init (ManPages me) {
 
-MAN_BEGIN (U"What's new?", U"ppgb", 20220128)
+MAN_BEGIN (U"What's new?", U"ppgb", 20220215)
 INTRO (U"Latest changes in Praat.")
+NORMAL (U"##6.2.09# (15 February 2022)")
+LIST_ITEM (U"• Windows: support for a screen resolution of 204 dpi.")
+NORMAL (U"##6.2.08# (5 February 2022)")
+LIST_ITEM (U"• Mac: more checks on audio devices when playing sounds.")
 NORMAL (U"##6.2.07# (28 January 2022)")
 LIST_ITEM (U"• Prevented a rare crash in the TextGrid window.")
-LIST_ITEM (U"• Windows: corrected a bug introduced 6.2.04 by which some file names were unreadable.")
+LIST_ITEM (U"• Windows: corrected a bug introduced in 6.2.04 by which some file names were unreadable.")
 NORMAL (U"##6.2.06# (20 January 2022)")
 LIST_ITEM (U"• Mac: prevent Demo window from hanging on copy or paste.")
 NORMAL (U"##6.2.05# (5 January 2022)")


=====================================
melder/melder_audio.cpp
=====================================
@@ -399,8 +399,8 @@ static bool workProc (void *closure) {
 //Melder_casual (U"workProc ", n);
 	if (my usePortAudio) {
 		#if defined (linux)
-			double timeElapsed = Melder_clock () - theStartingTime - Pa_GetStreamInfo (my stream) -> outputLatency;
-			integer samplesPlayed = timeElapsed * my sampleRate;
+			const double timeElapsed = Melder_clock () - theStartingTime - Pa_GetStreamInfo (my stream) -> outputLatency;
+			const integer samplesPlayed = timeElapsed * my sampleRate;
 			if (my callback && ! my callback (my closure, samplesPlayed)) {
 				my volatile_interrupted = 1;
 				return flush ();
@@ -425,7 +425,7 @@ static bool workProc (void *closure) {
 				But then we also have to use paComplete in the stream callback.
 			*/
 		#else
-			double timeElapsed = Melder_clock () - theStartingTime - Pa_GetStreamInfo (my stream) -> outputLatency;
+			const double timeElapsed = Melder_clock () - theStartingTime - Pa_GetStreamInfo (my stream) -> outputLatency;
 			my samplesPlayed = (integer) floor (timeElapsed * my sampleRate);
 			if (my supports_paComplete && Pa_IsStreamActive (my stream)) {
 				if (my callback && ! my callback (my closure, my samplesPlayed)) {
@@ -452,7 +452,7 @@ static bool workProc (void *closure) {
 			pa_usec_t diff_usec = 0;
 			if (my pulseAudio.startTime.tv_usec != 0) {
 				diff_usec = pa_timeval_age (& my pulseAudio.startTime);
-				double timeElapsed = diff_usec / 1000000.0;
+				const double timeElapsed = diff_usec / 1000000.0;
 				samplesPlayed = timeElapsed * my sampleRate;
 			}
 			pa_threaded_mainloop_unlock (my pulseAudio.mainloop);
@@ -1000,7 +1000,8 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 			OSStatus err = noErr;
 			AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
 			err = AudioObjectAddPropertyListener ( kAudioObjectSystemObject, & audioDevicesAddress, theCoreaudioPropertyListener, NULL);
-			if (err) Melder_casual (U"error on AudioObjectAddPropertyListener");
+			if (err)
+				Melder_casual (U"error on AudioObjectAddPropertyListener");
 			inited = true;
 		}
 	}
@@ -1010,7 +1011,8 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 	#ifdef _WIN32
 		bool wasPlaying = MelderAudio_isPlaying;
 	#endif
-	if (MelderAudio_isPlaying) MelderAudio_stopPlaying (MelderAudio_IMPLICIT);   // otherwise, keep "explicitStop" tag
+	if (MelderAudio_isPlaying)
+		MelderAudio_stopPlaying (MelderAudio_IMPLICIT);   // otherwise, keep "explicitStop" tag
 	#ifdef HAVE_PULSEAUDIO
 		if (my usePulseAudio && my pulseAudio.mainloop) {
 			pulseAudio_cleanup ();
@@ -1064,16 +1066,18 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 		my supports_paComplete = Pa_GetHostApiInfo (Pa_GetDefaultHostApi ()) -> type != paDirectSound &&false;
 		PaStreamParameters outputParameters = { 0 };
 		outputParameters. device = Pa_GetDefaultOutputDevice ();
+		if (outputParameters. device == paNoDevice)
+			Melder_throw (U"PortAudio sees no default output device.\nCannot play sound.");
 		const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo (outputParameters. device);
+		if (! deviceInfo)
+			Melder_throw (U"PortAudio finds no info for device ", outputParameters. device, U".\nCannot play sound.");
 		//Melder_casual (U"MelderAudio_play16: ", Melder_peek8to32 (deviceInfo -> name));
 		trace (U"the device can handle ", deviceInfo -> maxOutputChannels, U" channels");
-		if (my numberOfChannels > deviceInfo -> maxOutputChannels) {
-			my numberOfChannels = deviceInfo -> maxOutputChannels;
-		}
+		Melder_clipRight (& my numberOfChannels, integer (deviceInfo -> maxOutputChannels));
 		if (numberOfChannels > my numberOfChannels) {
 			/*
-			 * Redistribute the in channels over the out channels.
-			 */
+				Redistribute the in channels over the out channels.
+			*/
 			if (numberOfChannels == 4 && my numberOfChannels == 2) {   // a common case
 				int16 *in = & my playBuffer [0], *out = & my playBuffer [0];
 				for (integer isamp = 1; isamp <= numberOfSamples; isamp ++) {
@@ -1099,7 +1103,7 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 		}
 		outputParameters. channelCount = my numberOfChannels;
 		outputParameters. sampleFormat = paInt16;
-		if (deviceInfo) outputParameters. suggestedLatency = deviceInfo -> defaultLowOutputLatency;
+		outputParameters. suggestedLatency = deviceInfo -> defaultLowOutputLatency;
 		outputParameters. hostApiSpecificStreamInfo = nullptr;
 		err = Pa_OpenStream (& my stream, nullptr, & outputParameters, my sampleRate, paFramesPerBufferUnspecified,
 			paDitherOff, thePaStreamCallback, me);
@@ -1107,24 +1111,25 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 			Melder_throw (U"PortAudio cannot open sound output: ", Melder_peek8to32 (Pa_GetErrorText (err)), U".");
 		theStartingTime = Melder_clock ();
 		err = Pa_StartStream (my stream);
-		if (err) Melder_throw (U"PortAudio cannot start sound output: ", Melder_peek8to32 (Pa_GetErrorText (err)), U".");
+		if (err)
+			Melder_throw (U"PortAudio cannot start sound output: ", Melder_peek8to32 (Pa_GetErrorText (err)), U".");
 		my paStartingTime = Pa_GetStreamTime (my stream);
 		if (my asynchronicity <= kMelder_asynchronicityLevel::INTERRUPTABLE) {
 			for (;;) {
 				#if defined (linux)
 					/*
-					 * This is how PortAudio was designed to work.
-					 */
+						This is how PortAudio was designed to work.
+					*/
 					if (my samplesLeft == 0) {
 						my samplesPlayed = my numberOfSamples;
 						break;
 					}
 				#else
 					/*
-					 * A version that doesn't trust that the stream callback will complete.
-					 */
-					double timeElapsed = Melder_clock () - theStartingTime - Pa_GetStreamInfo (my stream) -> outputLatency;
-					integer samplesPlayed = (integer) floor (timeElapsed * my sampleRate);
+						A version that doesn't trust that the stream callback will complete.
+					*/
+					const double timeElapsed = Melder_clock () - theStartingTime - Pa_GetStreamInfo (my stream) -> outputLatency;
+					const integer samplesPlayed = (integer) floor (timeElapsed * my sampleRate);
 					if (samplesPlayed >= my numberOfSamples + my sampleRate / 20) {
 						my samplesPlayed = my numberOfSamples;
 						break;
@@ -1135,9 +1140,9 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 					! my callback (my closure, my samplesPlayed))
 					interrupted = true;
 				/*
-				 * Safe operation: only listen to key-down events.
-				 * Do this on the lowest level that will work.
-				 */
+					Safe operation: only listen to key-down events.
+					Do this on the lowest level that will work.
+				*/
 				if (my asynchronicity == kMelder_asynchronicityLevel::INTERRUPTABLE && ! interrupted) {
 					#if gtk
 						// TODO: implement a reaction to the Escape key
@@ -1147,12 +1152,12 @@ void MelderAudio_play16 (int16 *buffer, integer sampleRate, integer numberOfSamp
 						EventRecord event;
 						if (EventAvail (keyDownMask, & event)) {
 							/*
-							* Remove the event, even if it was a different key.
-							* Otherwise, the key will block the future availability of the Escape key.
+								Remove the event, even if it was a different key.
+								Otherwise, the key will block the future availability of the Escape key.
 							*/
 							FlushEvents (keyDownMask, 0);
 							/*
-							* Catch Escape and Command-period.
+								Catch Escape and Command-period.
 							*/
 							if ((event. message & charCodeMask) == 27 ||
 								((event. modifiers & cmdKey) && (event. message & charCodeMask) == '.'))


=====================================
sys/Graphics.cpp
=====================================
@@ -83,6 +83,8 @@ void Graphics_init (Graphics me, int resolution) {
 		my resolutionNumber = kGraphics_resolution::DPI_180;
 	} else if (resolution == 200) {
 		my resolutionNumber = kGraphics_resolution::DPI_200;
+	} else if (resolution == 204) {
+		my resolutionNumber = kGraphics_resolution::DPI_204;
 	} else if (resolution == 300) {
 		my resolutionNumber = kGraphics_resolution::DPI_300;
 	} else if (resolution == 360) {


=====================================
sys/Graphics_enums.h
=====================================
@@ -1,6 +1,6 @@
 /* Graphics_enums.h
  *
- * Copyright (C) 1992-2007,2013-2019 Paul Boersma
+ * Copyright (C) 1992-2007,2013-2019,2022 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
@@ -48,13 +48,14 @@ enums_begin (kGraphics_resolution, 0)
 	enums_add (kGraphics_resolution, 4, DPI_150, U"150 dpi")
 	enums_add (kGraphics_resolution, 5, DPI_180, U"180 dpi")
 	enums_add (kGraphics_resolution, 6, DPI_200, U"200 dpi")
-	enums_add (kGraphics_resolution, 7, DPI_300, U"300 dpi")
-	enums_add (kGraphics_resolution, 8, DPI_360, U"360 dpi")
-	enums_add (kGraphics_resolution, 9, DPI_600, U"600 dpi")
-	enums_add (kGraphics_resolution, 10, DPI_720, U"720 dpi")
-	enums_add (kGraphics_resolution, 11, DPI_900, U"900 dpi")
-	enums_add (kGraphics_resolution, 12, DPI_1200, U"1200 dpi")
-enums_end (kGraphics_resolution, 12, DPI_100)
+	enums_add (kGraphics_resolution, 7, DPI_204, U"204 dpi")
+	enums_add (kGraphics_resolution, 8, DPI_300, U"300 dpi")
+	enums_add (kGraphics_resolution, 9, DPI_360, U"360 dpi")
+	enums_add (kGraphics_resolution, 10, DPI_600, U"600 dpi")
+	enums_add (kGraphics_resolution, 11, DPI_720, U"720 dpi")
+	enums_add (kGraphics_resolution, 12, DPI_900, U"900 dpi")
+	enums_add (kGraphics_resolution, 13, DPI_1200, U"1200 dpi")
+enums_end (kGraphics_resolution, 13, DPI_100)
 
 enums_begin (kGraphics_colourScale, 0)
 	enums_add (kGraphics_colourScale, 0, GREY, U"grey")


=====================================
sys/praat_version.h
=====================================
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.2.07
-#define PRAAT_VERSION_NUM 6207
+#define PRAAT_VERSION_STR 6.2.09
+#define PRAAT_VERSION_NUM 6209
 #define PRAAT_YEAR 2022
-#define PRAAT_MONTH January
-#define PRAAT_DAY 28
+#define PRAAT_MONTH February
+#define PRAAT_DAY 15



View it on GitLab: https://salsa.debian.org/med-team/praat/-/compare/cb9fab1f8ac93d3d38fc53eef24b3c906546ae00...28d11a363cb039a78aed8456fe9005e46a9f69af

-- 
View it on GitLab: https://salsa.debian.org/med-team/praat/-/compare/cb9fab1f8ac93d3d38fc53eef24b3c906546ae00...28d11a363cb039a78aed8456fe9005e46a9f69af
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/20220221/8dde98fe/attachment-0001.htm>


More information about the debian-med-commit mailing list