autoTable TextGrids_to_Table_textAlignmentment (TextGrid target, long ttier, TextGrid source, long stier, EditCostsTable costs) {
	try {
		IntervalTier targetTier = TextGrid_checkSpecifiedTierIsIntervalTier (target, ttier);
		IntervalTier sourceTier = TextGrid_checkSpecifiedTierIsIntervalTier (source, stier);
		return IntervalTiers_to_Table_textAlignmentment (targetTier, sourceTier, costs);
	} catch (MelderError) {
		Melder_throw (U"No text alignment table created from TextGrids ", target, U" and ", source, U".");
	}
}
Ejemplo n.º 2
0
static PointProcess TextGrid_getStartingPoints_multiNumeric (TextGrid me, uint16_t number) {
	try {
		autoPointProcess thee = NULL;
		int numberOfBits = my numberOfTiers();
		for (int ibit = 0; ibit < numberOfBits; ibit ++) {
			(void) TextGrid_checkSpecifiedTierIsIntervalTier (me, ibit + 1);
			if (number & (1 << ibit)) {
				autoPointProcess bitEvents = TextGrid_getStartingPoints (me, ibit + 1, kMelder_string_EQUAL_TO, L"1");
				if (thee.peek()) {
					autoPointProcess intersection = PointProcesses_intersection (thee.peek(), bitEvents.peek());
					thee.reset (intersection.transfer());
				} else {
					thee.reset (bitEvents.transfer());
				}
			}
		}
		for (int ibit = 0; ibit < numberOfBits; ibit ++) {
			autoPointProcess bitEvents = TextGrid_getStartingPoints (me, ibit + 1, kMelder_string_EQUAL_TO, L"1");
			if (! (number & (1 << ibit))) {
				if (thee.peek()) {
					autoPointProcess difference = PointProcesses_difference (thee.peek(), bitEvents.peek());
					thee.reset (difference.transfer());
				} else {
					thee.reset (PointProcess_create (my xmin, my xmax, 10));
				}
			}
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": starting points not converted to PointProcess.");
	}
}
Ejemplo n.º 3
0
static autoPointProcess TextGrid_getStartingPoints_multiNumeric (TextGrid me, uint16_t number) {
	try {
		autoPointProcess thee;
		int numberOfBits = my tiers->size;
		for (int ibit = 0; ibit < numberOfBits; ibit ++) {
			(void) TextGrid_checkSpecifiedTierIsIntervalTier (me, ibit + 1);
			if (number & (1 << ibit)) {
				autoPointProcess bitEvents = TextGrid_getStartingPoints (me, ibit + 1, kMelder_string_EQUAL_TO, U"1");
				if (thee) {
					thee = PointProcesses_intersection (thee.get(), bitEvents.get());
				} else {
					thee = bitEvents.move();
				}
			}
		}
		for (int ibit = 0; ibit < numberOfBits; ibit ++) {
			autoPointProcess bitEvents = TextGrid_getStartingPoints (me, ibit + 1, kMelder_string_EQUAL_TO, U"1");
			if (! (number & (1 << ibit))) {
				if (thee) {
					thee = PointProcesses_difference (thee.get(), bitEvents.get());
				} else {
					thee = PointProcess_create (my xmin, my xmax, 10);
				}
			}
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": starting points not converted to PointProcess.");
	}
}
autoTextGrid SpeechSynthesizer_and_Sound_and_TextGrid_align2 (SpeechSynthesizer me, Sound thee, TextGrid him, long tierNumber, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double trimDuration) {
    try {//TODO: check not empty tier
    	IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (him, tierNumber);
        autoTextGrid grid = SpeechSynthesizer_and_Sound_and_IntervalTier_align2 (me, thee, tier, istart, iend, silenceThreshold, minSilenceDuration, minSoundingDuration, trimDuration);
        return grid;
    } catch (MelderError) {
        Melder_throw (U"");
    }
}
Ejemplo n.º 5
0
Collection TextGrid_Sound_extractAllIntervals (TextGrid me, Sound sound, long tierNumber, int preserveTimes) {
	try {
		IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		autoCollection collection = Collection_create (NULL, tier -> intervals -> size);
		for (long iseg = 1; iseg <= tier -> intervals -> size; iseg ++) {
			TextInterval segment = (TextInterval) tier -> intervals -> item [iseg];
			autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
			Thing_setName (interval.peek(), segment -> text ? segment -> text : L"untitled");
			Collection_addItem (collection.peek(), interval.transfer()); 
		}
		return collection.transfer();
	} catch (MelderError) {
		Melder_throw (me, " & ", sound, ": intervals not extracted.");
	}
}
Ejemplo n.º 6
0
autoSoundList TextGrid_Sound_extractAllIntervals (TextGrid me, Sound sound, long tierNumber, bool preserveTimes) {
	try {
		IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		autoSoundList list = SoundList_create ();
		for (long iseg = 1; iseg <= tier -> intervals.size; iseg ++) {
			TextInterval segment = tier -> intervals.at [iseg];
			autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
			Thing_setName (interval.get(), segment -> text ? segment -> text : U"untitled");
			list -> addItem_move (interval.move());
		}
		return list;
	} catch (MelderError) {
		Melder_throw (me, U" & ", sound, U": intervals not extracted.");
	}
}
Ejemplo n.º 7
0
autoCollection TextGrid_Sound_extractAllIntervals (TextGrid me, Sound sound, long tierNumber, int preserveTimes) {
	try {
		IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		autoCollection collection = Collection_create (nullptr, tier -> numberOfIntervals ());
		for (long iseg = 1; iseg <= tier -> numberOfIntervals (); iseg ++) {
			TextInterval segment = tier -> interval (iseg);
			autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
			Thing_setName (interval.peek(), segment -> text ? segment -> text : U"untitled");
			Collection_addItem_move (collection.peek(), interval.move());
		}
		return collection;
	} catch (MelderError) {
		Melder_throw (me, U" & ", sound, U": intervals not extracted.");
	}
}
Ejemplo n.º 8
0
Collection TextGrid_Sound_extractNonemptyIntervals (TextGrid me, Sound sound, long tierNumber, int preserveTimes) {
	try {
		IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		autoCollection collection = Collection_create (NULL, tier -> numberOfIntervals ());
		for (long iseg = 1; iseg <= tier -> numberOfIntervals (); iseg ++) {
			TextInterval segment = tier -> interval (iseg);
			if (segment -> text != NULL && segment -> text [0] != '\0') {
				autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
				Thing_setName (interval.peek(), segment -> text ? segment -> text : L"untitled");
				Collection_addItem (collection.peek(), interval.transfer());
			}
		}
		if (collection -> size == 0) Melder_warning (L"No non-empty intervals were found.");
		return collection.transfer();
	} catch (MelderError) {
		Melder_throw (me, " & ", sound, ": non-empty intervals not extracted.");
	}
}
Ejemplo n.º 9
0
autoSoundList TextGrid_Sound_extractIntervalsWhere (TextGrid me, Sound sound, long tierNumber,
	int comparison_Melder_STRING, const char32 *text, bool preserveTimes)
{
	try {
		IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		autoSoundList list = SoundList_create ();
		long count = 0;
		for (long iseg = 1; iseg <= tier -> intervals.size; iseg ++) {
			TextInterval segment = tier -> intervals.at [iseg];
			if (Melder_stringMatchesCriterion (segment -> text, comparison_Melder_STRING, text)) {
				autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
				Thing_setName (interval.get(), Melder_cat (sound -> name ? sound -> name : U"", U"_", text, U"_", ++ count));
				list -> addItem_move (interval.move());
			}
		}
		if (list->size == 0)
			Melder_warning (U"No label that ", kMelder_string_getText (comparison_Melder_STRING), U" the text \"", text, U"\" was found.");
		return list;
	} catch (MelderError) {
		Melder_throw (me, U" & ", sound, U": intervals not extracted.");
	}
}
Ejemplo n.º 10
0
Collection TextGrid_Sound_extractIntervalsWhere (TextGrid me, Sound sound, long tierNumber,
	int comparison_Melder_STRING, const wchar_t *text, int preserveTimes)
{
	try {
		IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber);
		autoCollection collection = Collection_create (NULL, tier -> intervals -> size);
		long count = 0;
		for (long iseg = 1; iseg <= tier -> intervals -> size; iseg ++) {
			TextInterval segment = (TextInterval) tier -> intervals -> item [iseg];
			if (Melder_stringMatchesCriterion (segment -> text, comparison_Melder_STRING, text)) {
				autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
				wchar_t name [1000];
				swprintf (name, 1000, L"%ls_%ls_%ld", sound -> name ? sound -> name : L"", text, ++ count);
				Thing_setName (interval.peek(), name);
				Collection_addItem (collection.peek(), interval.transfer());
			}
		}
		if (collection -> size == 0)
			Melder_warning ("No label that ", kMelder_string_getText (comparison_Melder_STRING), " the text \"", text, "\" was found.");
		return collection.transfer();
	} catch (MelderError) {
		Melder_throw (me, " & ", sound, ": intervals not extracted.");
	}
}
Ejemplo n.º 11
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.");
	}
}