Exemple #1
0
const char * Melder8_integer (int64 value) {
	if (++ ibuffer == NUMBER_OF_BUFFERS) ibuffer = 0;
	if (sizeof (long) == 8) {
		int n = snprintf (buffers8 [ibuffer], MAXIMUM_NUMERIC_STRING_LENGTH + 1, "%ld", (long) value);   // cast to identical type, to make compiler happy
		Melder_assert (n > 0);
		Melder_assert (n <= MAXIMUM_NUMERIC_STRING_LENGTH);
	} else if (sizeof (long long) == 8) {
		/*
		 * There are buggy platforms (namely 32-bit Mingw on Windows XP) that support long long and %lld but that convert
		 * the argument to a 32-bit long.
		 * There are also buggy platforms (namely 32-bit gcc on Linux) that support long long and %I64d but that convert
		 * the argument to a 32-bit long.
		 */
		static const char *formatString = nullptr;
		if (! formatString) {
			char tryBuffer [MAXIMUM_NUMERIC_STRING_LENGTH + 1];
			formatString = "%lld";
			sprintf (tryBuffer, formatString, 1000000000000LL);
			if (! strequ (tryBuffer, "1000000000000")) {
				formatString = "%I64d";
				sprintf (tryBuffer, formatString, 1000000000000LL);
				if (! strequ (tryBuffer, "1000000000000")) {
					Melder_fatal (U"Found no way to print 64-bit integers on this machine.");
				}
			}
		}
		int n = snprintf (buffers8 [ibuffer], MAXIMUM_NUMERIC_STRING_LENGTH + 1, formatString, value);
		Melder_assert (n > 0);
		Melder_assert (n <= MAXIMUM_NUMERIC_STRING_LENGTH);
	} else {
		Melder_fatal (U"Neither long nor long long is 8 bytes on this machine.");
	}
	return buffers8 [ibuffer];
}
void * Melder_realloc_f (void *ptr, long size) {
	void *result;
	if (size <= 0)
		Melder_fatal ("(Melder_realloc_f:) Can never allocate %ld bytes.", size);
	result = realloc (ptr, size);   /* Will not show in the statistics... */
	if (result == NULL) {
		if (theRainyDayFund != NULL) free (theRainyDayFund);
		result = realloc (ptr, size);
		if (result != NULL) {
			Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal ("Out of memory. Could not extend room to %ld bytes.", size);
		}
	}
	if (ptr == NULL) {   /* Is it like malloc? */
		totalNumberOfAllocations += 1;
		totalAllocationSize += size;
	} else if (result != ptr) {   /* Did realloc do a malloc-and-free? */
		totalNumberOfAllocations += 1;
		totalAllocationSize += size;
		totalNumberOfDeallocations += 1;
		totalNumberOfMovingReallocs += 1;
	} else {
		totalNumberOfReallocsInSitu += 1;
	}
	return result;
}
Exemple #3
0
void * Melder_realloc_f (void *ptr, int64 size) {
	void *result;
	if (size <= 0)
		Melder_fatal (U"(Melder_realloc_f:) Can never allocate ", Melder_bigInteger (size), U" bytes.");
	if (sizeof (size_t) < 8 && size > SIZE_MAX)
		Melder_fatal (U"(Melder_realloc_f:) Can never allocate ", Melder_bigInteger (size), U" bytes.");
	result = realloc (ptr, (size_t) size);   // will not show in the statistics...
	if (result == NULL) {
		if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
		result = realloc (ptr, (size_t) size);
		if (result != NULL) {
			Melder_flushError (U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal (U"Out of memory. Could not extend room to ", Melder_bigInteger (size), U" bytes.");
		}
	}
	if (ptr == NULL) {   // is it like malloc?
		totalNumberOfAllocations += 1;
		totalAllocationSize += size;
	} else if (result != ptr) {   // did realloc do a malloc-and-free?
		totalNumberOfAllocations += 1;
		totalAllocationSize += size;
		totalNumberOfDeallocations += 1;
		totalNumberOfMovingReallocs += 1;
	} else {
		totalNumberOfReallocsInSitu += 1;
	}
	return result;
}
Exemple #4
0
void * _Thing_check (I, void *klas, const char *fileName, int line) {
	Thing me = (structThing*)void_me;   /* NOT the macro `iam (Thing);' because that would be recursive. */
	if (! me) Melder_fatal ("(_Thing_check:) NULL object passed to a function\n"
		"in file %.100s at line %d.", fileName, line);
	Thing_Table table = my methods;
	while (table != klas && table != NULL) table = table -> _parent;
	if (! table)
		Melder_fatal ("(_Thing_check:) Object of wrong class (%.50s) passed to a function\n"
				"in file %.100s at line %d.", Melder_peekWcsToUtf8 (our _className), fileName, line);
	return me;
}
void * _Melder_malloc_f (unsigned long size) {
	if (size <= 0)
		Melder_fatal ("(Melder_malloc_f:) Can never allocate %ld bytes.", size);
	void *result = malloc (size);
	if (result == NULL) {
		if (theRainyDayFund != NULL) free (theRainyDayFund);
		result = malloc (size);
		if (result != NULL) {
			Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal ("Out of memory: there is not enough room for another %ld bytes.", size);
		}
	}
	totalNumberOfAllocations += 1;
	totalAllocationSize += size;
	return result;
}
Exemple #6
0
void * _Melder_malloc_f (int64 size) {
	if (size <= 0)
		Melder_fatal (U"(Melder_malloc_f:) Can never allocate ", Melder_bigInteger (size), U" bytes.");
	if (sizeof (size_t) < 8 && size > SIZE_MAX)
		Melder_fatal (U"(Melder_malloc_f:) Can never allocate ", Melder_bigInteger (size), U" bytes.");
	void *result = malloc ((size_t) size);
	if (result == NULL) {
		if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
		result = malloc ((size_t) size);
		if (result != NULL) {
			Melder_flushError (U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal (U"Out of memory: there is not enough room for another %s bytes.", Melder_bigInteger (size));
		}
	}
	totalNumberOfAllocations += 1;
	totalAllocationSize += size;
	return result;
}
void * _Melder_calloc_f (long nelem, long elsize) {
	void *result;
	if (nelem <= 0)
		Melder_fatal ("(Melder_calloc_f:) Can never allocate %ld elements.", nelem);
	if (elsize <= 0)
		Melder_fatal ("(Melder_calloc_f:) Can never allocate elements whose size is %ld bytes.", elsize);
	result = calloc (nelem, elsize);
	if (result == NULL) {
		if (theRainyDayFund != NULL) free (theRainyDayFund);
		result = calloc (nelem, elsize);
		if (result != NULL) {
			Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal ("Out of memory: there is not enough room for %ld more elements whose sizes are %ld bytes each.", nelem, elsize);
		}
	}
	totalNumberOfAllocations += 1;
	totalAllocationSize += nelem * elsize;
	return result;
}
Exemple #8
0
char32 * Melder_dup_f (const char32 *string /* cattable */) {
	if (! string) return NULL;
	int64 size = (int64) str32len (string) + 1;
	if (sizeof (size_t) < 8 && size > SIZE_MAX / sizeof (char32))
		Melder_fatal (U"(Melder_dup_f:) Can never allocate ", Melder_bigInteger (size), U" characters.");
	char32 *result = (char32 *) malloc ((size_t) size * sizeof (char32));
	if (result == NULL) {
		if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
		result = (char32 *) malloc ((size_t) size * sizeof (char32));
		if (result != NULL) {
			Melder_flushError (U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal (U"Out of memory: there is not enough room to duplicate a text of ", Melder_bigInteger (size - 1), U" characters.");
		}
	}
	str32cpy (result, string);
	totalNumberOfAllocations += 1;
	totalAllocationSize += size * (int64) sizeof (char32);
	return result;
}
Exemple #9
0
char * Melder_strdup_f (const char *string) {
	if (! string) return nullptr;
	int64 size = (int64) strlen (string) + 1;
	if (sizeof (size_t) < 8 && size > SIZE_MAX)
		Melder_fatal (U"(Melder_strdup_f:) Can never allocate ", Melder_bigInteger (size), U" bytes.");
	char *result = (char *) malloc ((size_t) size);
	if (! result) {
		if (theRainyDayFund) { free (theRainyDayFund); theRainyDayFund = nullptr; }
		result = (char *) malloc ((size_t) size * sizeof (char));
		if (result) {
			Melder_flushError (U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal (U"Out of memory: there is not enough room to duplicate a text of ", Melder_bigInteger (size - 1), U" characters.");
		}
	}
	strcpy (result, string);
	totalNumberOfAllocations += 1;
	totalAllocationSize += size;
	return result;
}
Exemple #10
0
void * _Thing_check (Thing me, ClassInfo klas, const char *fileName, int line) {
	if (! me)
		Melder_fatal (U"(_Thing_check:)"
			U" null object passed to a function\n"
			U"in file ", Melder_peek8to32 (fileName),
			U" at line ", line,
			U"."
		);
	ClassInfo classInfo = my classInfo;
	while (classInfo != klas && classInfo) classInfo = classInfo -> parent;
	if (! classInfo)
		Melder_fatal (U"(_Thing_check:)"
			U" Object of wrong class (", my classInfo -> className,
			U") passed to a function\n"
			U"in file ", Melder_peek8to32 (fileName),
			U" at line ", line,
			U"."
		);
	return me;
}
Exemple #11
0
void * _Melder_calloc_f (int64 nelem, int64 elsize) {
	if (nelem <= 0)
		Melder_fatal (U"(Melder_calloc_f:) Can never allocate ", Melder_bigInteger (nelem), U" elements.");
	if (elsize <= 0)
		Melder_fatal (U"(Melder_calloc_f:) Can never allocate elements whose size is ", Melder_bigInteger (elsize), U" bytes.");
	if ((uint64_t) nelem > SIZE_MAX / (uint64_t) elsize)
		Melder_fatal (U"(Melder_calloc_f:) Can never allocate ", Melder_bigInteger (nelem), U" elements whose sizes are ", Melder_bigInteger (elsize), U" bytes each.");
	void *result = calloc ((size_t) nelem, (size_t) elsize);
	if (result == NULL) {
		if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
		result = calloc ((size_t) nelem, (size_t) elsize);
		if (result != NULL) {
			Melder_flushError (U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal (U"Out of memory: there is not enough room for ", Melder_bigInteger (nelem),
				U" more elements whose sizes are ", Melder_bigInteger (elsize), U" bytes each.");
		}
	}
	totalNumberOfAllocations += 1;
	totalAllocationSize += nelem * elsize;
	return result;
}
Exemple #12
0
void Graphics_init (Graphics me, int resolution) {
	my resolution = resolution;
	if (resolution == 96) {
		my resolutionNumber = kGraphics_resolution_96;
	} else if (resolution == 100) {
		my resolutionNumber = kGraphics_resolution_100;
	} else if (resolution == 180) {
		my resolutionNumber = kGraphics_resolution_180;
	} else if (resolution == 200) {
		my resolutionNumber = kGraphics_resolution_200;
	} else if (resolution == 300) {
		my resolutionNumber = kGraphics_resolution_300;
	} else if (resolution == 360) {
		my resolutionNumber = kGraphics_resolution_360;
	} else if (resolution == 600) {
		my resolutionNumber = kGraphics_resolution_600;
	} else if (resolution == 720) {
		my resolutionNumber = kGraphics_resolution_720;
	} else if (resolution == 1200) {
		my resolutionNumber = kGraphics_resolution_1200;
	} else {
		Melder_fatal (U"Unsupported resolution ", resolution, U" dpi.");
	}
	my d_x1DC = my d_x1DCmin = 0;	my d_x2DC = my d_x2DCmax = 32767;
	my d_y1DC = my d_y1DCmin = 0;	my d_y2DC = my d_y2DCmax = 32767;
	my d_x1WC = my d_x1NDC = my d_x1wNDC = 0.0;
	my d_x2WC = my d_x2NDC = my d_x2wNDC = 1.0;
	my d_y1WC = my d_y1NDC = my d_y1wNDC = 0.0;
	my d_y2WC = my d_y2NDC = my d_y2wNDC = 1.0;
	widgetToWindowCoordinates (me);
	computeTrafo (me);
	my lineWidth = 1.0;
	my arrowSize = 1.0;
	my speckleSize = 1.0;
	my font = kGraphics_font_HELVETICA;
	my fontSize = 10;
	my fontStyle = Graphics_NORMAL;
	my record = nullptr;
	my irecord = my nrecord = 0;
	my percentSignIsItalic = 1;
	my numberSignIsBold = 1;
	my circumflexIsSuperscript = 1;
	my underscoreIsSubscript = 1;
	my dollarSignIsCode = 0;
	my atSignIsLink = 0;
}
wchar_t * Melder_wcsdup_f (const wchar_t *string) {
	if (! string) return NULL;
	long size = wcslen (string) + 1;
	wchar_t *result = (wchar_t *) malloc (size * sizeof (wchar_t));
	if (result == NULL) {
		if (theRainyDayFund != NULL) free (theRainyDayFund);
		result = (wchar_t *) malloc (size * sizeof (wchar_t));
		if (result != NULL) {
			Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
		} else {
			Melder_fatal ("Out of memory: there is not enough room to duplicate a text of %ld characters.", size - 1);
		}
	}
	wcscpy (result, string);
	totalNumberOfAllocations += 1;
	totalAllocationSize += size * sizeof (wchar_t);
	return result;
}
Exemple #14
0
void TimeSoundEditor_init (TimeSoundEditor me, const char32 *title, Function data, Sampled sound, bool ownSound) {
	my d_ownSound = ownSound;
	if (sound) {
		if (ownSound) {
			Melder_assert (Thing_isa (sound, classSound));
			my d_sound.data = Data_copy ((Sound) sound).releaseToAmbiguousOwner();   // deep copy; ownership transferred
			Matrix_getWindowExtrema (my d_sound.data, 1, my d_sound.data -> nx, 1, my d_sound.data -> ny, & my d_sound.minimum, & my d_sound.maximum);
		} else if (Thing_isa (sound, classSound)) {
			my d_sound.data = (Sound) sound;   // reference copy; ownership not transferred
			Matrix_getWindowExtrema (my d_sound.data, 1, my d_sound.data -> nx, 1, my d_sound.data -> ny, & my d_sound.minimum, & my d_sound.maximum);
		} else if (Thing_isa (sound, classLongSound)) {
			my d_longSound.data = (LongSound) sound;
			my d_sound.minimum = -1.0, my d_sound.maximum = 1.0;
		} else {
			Melder_fatal (U"Invalid sound class in TimeSoundEditor::init.");
		}
	}
	FunctionEditor_init (me, title, data);
}
Exemple #15
0
Sound Sounds_crossCorrelate (Sound me, Sound thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) {
	try {
		if (my ny > 1 && thy ny > 1 && my ny != thy ny)
			Melder_throw (U"The numbers of channels of the two sounds have to be equal or 1.");
		if (my dx != thy dx)
			Melder_throw (U"The sampling frequencies of the two sounds have to be equal.");
		long numberOfChannels = my ny > thy ny ? my ny : thy ny;
		long n1 = my nx, n2 = thy nx;
		long n3 = n1 + n2 - 1, nfft = 1;
		while (nfft < n3) nfft *= 2;
		autoNUMvector <double> data1 (1, nfft);
		autoNUMvector <double> data2 (1, nfft);
		double my_xlast = my x1 + (n1 - 1) * my dx;
		autoSound him = Sound_create (numberOfChannels, thy xmin - my xmax, thy xmax - my xmin, n3, my dx, thy x1 - my_xlast);
		for (long channel = 1; channel <= numberOfChannels; channel ++) {
			double *a = my z [my ny == 1 ? 1 : channel];
			for (long i = n1; i > 0; i --) data1 [i] = a [i];
			for (long i = n1 + 1; i <= nfft; i ++) data1 [i] = 0.0;
			a = thy z [thy ny == 1 ? 1 : channel];
			for (long i = n2; i > 0; i --) data2 [i] = a [i];
			for (long i = n2 + 1; i <= nfft; i ++) data2 [i] = 0.0;
			NUMrealft (data1.peek(), nfft, 1);
			NUMrealft (data2.peek(), nfft, 1);
			data2 [1] *= data1 [1];
			data2 [2] *= data1 [2];
			for (long i = 3; i <= nfft; i += 2) {
				double temp = data1 [i] * data2 [i] + data1 [i + 1] * data2 [i + 1];   // reverse me by taking the conjugate of data1
				data2 [i + 1] = data1 [i] * data2 [i + 1] - data1 [i + 1] * data2 [i];   // reverse me by taking the conjugate of data1
				data2 [i] = temp;
			}
			NUMrealft (data2.peek(), nfft, -1);
			a = him -> z [channel];
			for (long i = 1; i < n1; i ++) {
				a [i] = data2 [i + (nfft - (n1 - 1))];   // data for the first part ("negative lags") is at the end of data2
			}
			for (long i = 1; i <= n2; i ++) {
				a [i + (n1 - 1)] = data2 [i];   // data for the second part ("positive lags") is at the beginning of data2
			}
		}
		switch (signalOutsideTimeDomain) {
			case kSounds_convolve_signalOutsideTimeDomain_ZERO: {
				// do nothing
			} break;
			case kSounds_convolve_signalOutsideTimeDomain_SIMILAR: {
				for (long channel = 1; channel <= numberOfChannels; channel ++) {
					double *a = his z [channel];
					double edge = n1 < n2 ? n1 : n2;
					for (long i = 1; i < edge; i ++) {
						double factor = edge / i;
						a [i] *= factor;
						a [n3 + 1 - i] *= factor;
					}
				}
			} break;
			//case kSounds_convolve_signalOutsideTimeDomain_PERIODIC: {
				// do nothing
			//} break;
			default: Melder_fatal (U"Sounds_crossCorrelate: unimplemented outside-time-domain strategy ", signalOutsideTimeDomain);
		}
		switch (scaling) {
			case kSounds_convolve_scaling_INTEGRAL: {
				Vector_multiplyByScalar (him.peek(), my dx / nfft);
			} break;
			case kSounds_convolve_scaling_SUM: {
				Vector_multiplyByScalar (him.peek(), 1.0 / nfft);
			} break;
			case kSounds_convolve_scaling_NORMALIZE: {
				double normalizationFactor = Matrix_getNorm (me) * Matrix_getNorm (thee);
				if (normalizationFactor != 0.0) {
					Vector_multiplyByScalar (him.peek(), 1.0 / nfft / normalizationFactor);
				}
			} break;
			case kSounds_convolve_scaling_PEAK_099: {
				Vector_scale (him.peek(), 0.99);
			} break;
			default: Melder_fatal (U"Sounds_crossCorrelate: unimplemented scaling ", scaling);
		}
		return him.transfer();
	} catch (MelderError) {
		Melder_throw (me, U" & ", thee, U": not cross-correlated.");
	}
}
Exemple #16
0
static void _Thing_addOneReadableClass (ClassInfo readableClass) {
	if (++ theNumberOfReadableClasses > 1000)
		Melder_fatal (U"(Thing_recognizeClassesByName:) Too many (1001) readable classes.");
	theReadableClasses [theNumberOfReadableClasses] = readableClass;
	readableClass -> sequentialUniqueIdOfReadableClass = theNumberOfReadableClasses;
}
Exemple #17
0
int _Melder_assert (const char *condition, const char *fileName, int lineNumber) {
	return Melder_fatal ("Assertion failed in file \"%s\" at line %d:\n   %s\n",
		fileName, lineNumber, condition);
}
Exemple #18
0
bool Thing_isa (Thing me, ClassInfo klas) {
	if (! me) Melder_fatal (U"(Thing_isa:) Found null object.");
	return Thing_isSubclass (my classInfo, klas);
}
Exemple #19
0
static void _Thing_addOneReadableClass (Thing_Table readableClass) {
	if (++ numberOfReadableClasses > 1000)
		Melder_fatal ("(Thing_recognizeClassesByName:) Too many (1001) readable classes.");
	readableClasses [numberOfReadableClasses] = readableClass;
	readableClass -> sequentialUniqueIdOfReadableClass = numberOfReadableClasses;
}
PointProcess Sound_Pitch_to_PointProcess_cc (Sound sound, Pitch pitch) {
	PointProcess point = PointProcess_create (sound -> xmin, sound -> xmax, 10);
	double t = pitch -> xmin;
	double addedRight = -1e300;
	double globalPeak = Vector_getAbsoluteExtremum (sound, sound -> xmin, sound -> xmax, 0), peak;
	
	/*
	 * Cycle over all voiced intervals.
	 */
	for (;;) {
		double tleft, tright, tmiddle, f0middle, tmax, tsave;
		if (! Pitch_getVoicedIntervalAfter (pitch, t, & tleft, & tright)) break;
		/*
		 * Go to the middle of the voice stretch.
		 */
		tmiddle = (tleft + tright) / 2;
		if (! Melder_progress1 ((tmiddle - sound -> xmin) / (sound -> xmax - sound -> xmin), L"Sound & Pitch to PointProcess"))
			goto end;
		f0middle = Pitch_getValueAtTime (pitch, tmiddle, kPitch_unit_HERTZ, Pitch_LINEAR);

		/*
		 * Our first point is near this middle.
		 */
		if (f0middle == NUMundefined) {
			Melder_fatal ("Sound_Pitch_to_PointProcess_cc: tleft %ls, tright %ls, f0middle %ls",
				Melder_double (tleft), Melder_double (tright), Melder_double (f0middle));
		}
		tmax = Sound_findExtremum (sound, tmiddle - 0.5 / f0middle, tmiddle + 0.5 / f0middle, TRUE, TRUE);
		Melder_assert (NUMdefined (tmax));
		if (! PointProcess_addPoint (point, tmax)) goto end;

		tsave = tmax;
		for (;;) {
			double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation;
			if (f0 == NUMundefined) break;
			correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax - 1.25 / f0, tmax - 0.8 / f0, & tmax, & peak);
			if (correlation == -1) /*break*/ tmax -= 1.0 / f0;   /* This one period will drop out. */
			if (tmax < tleft) {
				if (correlation > 0.7 && peak > 0.023333 * globalPeak && tmax - addedRight > 0.8 / f0)
					if (! PointProcess_addPoint (point, tmax)) goto end;
				break;
			}
			if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) {
				if (tmax - addedRight > 0.8 / f0)   /* Do not fill in a short originally unvoiced interval twice. */
					if (! PointProcess_addPoint (point, tmax)) goto end;
			}
		}
		tmax = tsave;
		for (;;) {
			double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation;
			if (f0 == NUMundefined) break;
			correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax + 0.8 / f0, tmax + 1.25 / f0, & tmax, & peak);
			if (correlation == -1) /*break*/ tmax += 1.0 / f0;
			if (tmax > tright) {
				if (correlation > 0.7 && peak > 0.023333 * globalPeak) {
					if (! PointProcess_addPoint (point, tmax)) goto end;
					addedRight = tmax;
				}
				break;
			}
			if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) {
				if (! PointProcess_addPoint (point, tmax)) goto end;
				addedRight = tmax;
			}
		}
		t = tright;
	}
end:
	Melder_progress1 (1.0, NULL);
	iferror forget (point);
	return point;
}
Exemple #21
0
int Thing_member (I, void *klas) {
	Thing me = (structThing*)void_me;
	if (! me) Melder_fatal ("(Thing_member:) Found NULL object.");
	return Thing_subclass (my methods, klas);
}
Exemple #22
0
void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierNumber, long intervalNumber, const char32 *languageName, bool includeWords, bool includePhonemes) {
	try {
		IntervalTier headTier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		if (intervalNumber < 1 || intervalNumber > headTier -> intervals.size)
			Melder_throw (U"Interval ", intervalNumber, U" does not exist.");
		TextInterval interval = headTier -> intervals.at [intervalNumber];
		if (! includeWords && ! includePhonemes)
			Melder_throw (U"Nothing to be done, because you asked neither for word alignment nor for phoneme alignment.");
		if (str32str (headTier -> name, U"/") )
			Melder_throw (U"The current tier already has a slash (\"/\") in its name. Cannot create a word or phoneme tier from it.");
		autoSound part =
			anySound -> classInfo == classLongSound ? 
				LongSound_extractPart (static_cast <LongSound> (anySound), interval -> xmin, interval -> xmax, true) :
				Sound_extractPart (static_cast <Sound> (anySound), interval -> xmin, interval -> xmax, kSound_windowShape_RECTANGULAR, 1.0, true);
		autoSpeechSynthesizer synthesizer = SpeechSynthesizer_create (languageName, U"default");
		double silenceThreshold = -35, 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
			}
		}
		if (analysis) {
			/*
			 * Clean up the analysis.
			 */
			Melder_assert (analysis -> xmin == interval -> xmin);
			Melder_assert (analysis -> xmax == interval -> xmax);
			Melder_assert (analysis -> tiers->size == 4);
			Thing_cast (IntervalTier, analysisWordTier, analysis -> tiers->at [3]);
			if (! IntervalTier_check (analysisWordTier))
				Melder_throw (U"Analysis word tier out of order.");
			IntervalTier_removeEmptyIntervals (analysisWordTier, nullptr);
			Melder_assert (analysisWordTier -> xmax == analysis -> xmax);
			Melder_assert (analysisWordTier -> intervals.size >= 1);
			TextInterval firstInterval = analysisWordTier -> intervals.at [1];
			TextInterval lastInterval = analysisWordTier -> intervals.at [analysisWordTier -> intervals.size];
			firstInterval -> xmin = analysis -> xmin;
			lastInterval  -> xmax = analysis -> xmax;
			if (lastInterval -> xmax != analysis -> xmax)
				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]);
			if (! IntervalTier_check (analysisPhonemeTier))
				Melder_throw (U"Analysis phoneme tier out of order.");
			IntervalTier_removeEmptyIntervals (analysisPhonemeTier, analysisWordTier);
			Melder_assert (analysisPhonemeTier -> xmax == analysis -> xmax);
			Melder_assert (analysisPhonemeTier -> intervals.size >= 1);
			firstInterval = analysisPhonemeTier -> intervals.at [1];
			lastInterval  = analysisPhonemeTier -> intervals.at [analysisPhonemeTier -> intervals.size];
			firstInterval -> xmin = analysis -> xmin;
			lastInterval  -> xmax = analysis -> xmax;
			Melder_assert (lastInterval -> xmax == analysis -> xmax);
			if (! IntervalTier_check (analysisPhonemeTier))
				Melder_throw (U"Analysis phoneme tier out of order (2).");
		}
		long wordTierNumber = 0, phonemeTierNumber = 0;
		IntervalTier wordTier = nullptr, phonemeTier = nullptr;
		/*
		 * Include a word tier.
		 */
		if (includeWords) {
			/*
			 * Make sure that the word tier exists.
			 */
			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]);
				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."
							U"\nPlease change its name or remove it.");
					wordTierNumber = itier;
					break;
				}
			}
			if (! wordTierNumber) {
				autoIntervalTier newWordTier = IntervalTier_create (my xmin, my xmax);
				Thing_setName (newWordTier.get(), newWordTierName.string);
				my tiers -> addItemAtPosition_move (newWordTier.move(), wordTierNumber = tierNumber + 1);
			}
			Melder_assert (wordTierNumber >= 1 && wordTierNumber <= my tiers->size);
			wordTier = static_cast <IntervalTier> (my tiers->at [wordTierNumber]);
			/*
			 * Make sure that the word tier has boundaries at the edges of the interval.
			 */
			IntervalTier_insertIntervalDestructively (wordTier, interval -> xmin, interval -> xmax);
			/*
			 * Copy the contents of the word analysis into the interval in the word tier.
			 */
			long wordIntervalNumber = IntervalTier_hasTime (wordTier, interval -> xmin);
			Melder_assert (wordIntervalNumber != 0);
			if (analysis) {
				Thing_cast (IntervalTier, analysisWordTier, analysis -> tiers->at [3]);
				if (! IntervalTier_check (analysisWordTier))
					Melder_throw (U"Analysis word tier out of order (3).");
				if (! IntervalTier_check (wordTier))
					Melder_throw (U"Word tier out of order (3).");
				for (long ianalysisInterval = 1; ianalysisInterval <= analysisWordTier -> intervals.size; ianalysisInterval ++) {
					TextInterval analysisInterval = analysisWordTier -> intervals.at [ianalysisInterval];
					TextInterval wordInterval = nullptr;
					double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax;
					if (tmax == analysis -> xmax) {
						wordInterval = wordTier -> intervals.at [wordIntervalNumber];
						TextInterval_setText (wordInterval, analysisInterval -> text);
					} else {
						wordInterval = wordTier -> intervals.at [wordIntervalNumber];
						autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text);
						wordInterval -> xmin = tmax;
						wordTier -> intervals. addItem_move (newInterval.move());
						wordIntervalNumber ++;
					}
				}
				if (! IntervalTier_check (analysisWordTier))
					Melder_throw (U"Analysis word tier out of order (4).");
				if (! IntervalTier_check (wordTier))
					Melder_throw (U"Word tier out of order (4).");
			}
		}
		/*
		 * Include a phoneme tier.
		 */
		if (includePhonemes) {
			/*
			 * Make sure that the phoneme tier exists.
			 */
			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];
				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."
							U"\nPlease change its name or remove it.");
					phonemeTierNumber = itier;
					break;
				}
			}
			if (! phonemeTierNumber) {
				autoIntervalTier newPhonemeTier = IntervalTier_create (my xmin, my xmax);
				Thing_setName (newPhonemeTier.get(), newPhonemeTierName.string);
				my tiers -> addItemAtPosition_move (newPhonemeTier.move(),
					phonemeTierNumber = wordTierNumber ? wordTierNumber + 1 : tierNumber + 1);
			}
			Melder_assert (phonemeTierNumber >= 1 && phonemeTierNumber <= my tiers->size);
			phonemeTier = static_cast <IntervalTier> (my tiers->at [phonemeTierNumber]);
			/*
			 * Make sure that the phoneme tier has boundaries at the edges of the interval.
			 */
			IntervalTier_insertIntervalDestructively (phonemeTier, interval -> xmin, interval -> xmax);
			/*
			 * Copy the contents of the phoneme analysis into the interval in the phoneme tier.
			 */
			long phonemeIntervalNumber = IntervalTier_hasTime (phonemeTier, interval -> xmin);
			Melder_assert (phonemeIntervalNumber != 0);
			if (analysis.get()) {
				Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers->at [4]);
				for (long ianalysisInterval = 1; ianalysisInterval <= analysisPhonemeTier -> intervals.size; ianalysisInterval ++) {
					TextInterval analysisInterval = analysisPhonemeTier -> intervals.at [ianalysisInterval];
					TextInterval phonemeInterval = nullptr;
					double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax;
					if (tmax == analysis -> xmax) {
						phonemeInterval = phonemeTier -> intervals.at [phonemeIntervalNumber];
						TextInterval_setText (phonemeInterval, analysisInterval -> text);
					} else {
						phonemeInterval = phonemeTier -> intervals.at [phonemeIntervalNumber];
						autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text);
						phonemeInterval -> xmin = tmax;
						phonemeTier -> intervals. addItem_move (newInterval.move());
						phonemeIntervalNumber ++;
					}
				}
			}
			if (includeWords) {
				/*
				 * Synchronize the boundaries between the word tier and the phoneme tier.
				 */
				//for (long iinterval = 1; iinterval <=
			}
		}
	} catch (MelderError) {
		Melder_throw (me, U" & ", anySound, U": interval not aligned.");
	}
}
Exemple #23
0
Sound Sound_autoCorrelate (Sound me, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) {
	try {
		long numberOfChannels = my ny, n1 = my nx, n2 = n1 + n1 - 1, nfft = 1;
		while (nfft < n2) nfft *= 2;
		autoNUMvector <double> data (1, nfft);
		double my_xlast = my x1 + (n1 - 1) * my dx;
		autoSound thee = Sound_create (numberOfChannels, my xmin - my xmax, my xmax - my xmin, n2, my dx, my x1 - my_xlast);
		for (long channel = 1; channel <= numberOfChannels; channel ++) {
			double *a = my z [channel];
			for (long i = n1; i > 0; i --) data [i] = a [i];
			for (long i = n1 + 1; i <= nfft; i ++) data [i] = 0.0;
			NUMrealft (data.peek(), nfft, 1);
			data [1] *= data [1];
			data [2] *= data [2];
			for (long i = 3; i <= nfft; i += 2) {
				data [i] = data [i] * data [i] + data [i + 1] * data [i + 1];
				data [i + 1] = 0.0;   // reverse me by taking the conjugate of data1
			}
			NUMrealft (data.peek(), nfft, -1);
			a = thy z [channel];
			for (long i = 1; i < n1; i ++) {
				a [i] = data [i + (nfft - (n1 - 1))];   // data for the first part ("negative lags") is at the end of data
			}
			for (long i = 1; i <= n1; i ++) {
				a [i + (n1 - 1)] = data [i];   // data for the second part ("positive lags") is at the beginning of data
			}
		}
		switch (signalOutsideTimeDomain) {
			case kSounds_convolve_signalOutsideTimeDomain_ZERO: {
				// do nothing
			} break;
			case kSounds_convolve_signalOutsideTimeDomain_SIMILAR: {
				for (long channel = 1; channel <= numberOfChannels; channel ++) {
					double *a = thy z [channel];
					double edge = n1;
					for (long i = 1; i < edge; i ++) {
						double factor = edge / i;
						a [i] *= factor;
						a [n2 + 1 - i] *= factor;
					}
				}
			} break;
			//case kSounds_convolve_signalOutsideTimeDomain_PERIODIC: {
				// do nothing
			//} break;
			default: Melder_fatal (U"Sounds_autoCorrelate: unimplemented outside-time-domain strategy ", signalOutsideTimeDomain);
		}
		switch (scaling) {
			case kSounds_convolve_scaling_INTEGRAL: {
				Vector_multiplyByScalar (thee.peek(), my dx / nfft);
			} break;
			case kSounds_convolve_scaling_SUM: {
				Vector_multiplyByScalar (thee.peek(), 1.0 / nfft);
			} break;
			case kSounds_convolve_scaling_NORMALIZE: {
				double normalizationFactor = Matrix_getNorm (me) * Matrix_getNorm (me);
				if (normalizationFactor != 0.0) {
					Vector_multiplyByScalar (thee.peek(), 1.0 / nfft / normalizationFactor);
				}
			} break;
			case kSounds_convolve_scaling_PEAK_099: {
				Vector_scale (thee.peek(), 0.99);
			} break;
			default: Melder_fatal (U"Sounds_autoCorrelate: unimplemented scaling ", scaling);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": autocorrelation not computed.");
	}
}