static int CategoriesEditorInsert_execute (CategoriesEditorInsert me) { CategoriesEditor editor = static_cast<CategoriesEditor> (my boss); Categories categories = static_cast<Categories> (editor -> data); autoSimpleString str = Data_copy ((SimpleString) my categories -> item[1]); Ordered_addItemAtPosition_move (categories, str.move(), my selection[1]); update (editor, my selection[1], 0, my selection, 1); return 1; }
static int CategoriesEditorRemove_undo (CategoriesEditorRemove me) { CategoriesEditor editor = (CategoriesEditor) my boss; Categories categories = (Categories) editor -> data; for (long i = 1; i <= my nSelected; i++) { autoSimpleString item = Data_copy ((SimpleString) my categories -> item[i]); Ordered_addItemAtPosition_move (categories, item.move(), my selection[i]); } update (editor, my selection[1], 0, my selection, my nSelected); return 1; }
static int CategoriesEditorReplace_execute (CategoriesEditorReplace me) { CategoriesEditor editor = static_cast<CategoriesEditor> (my boss); Categories categories = static_cast<Categories> (editor -> data); for (long i = my nSelected; i >= 1; i--) { autoSimpleString str = Data_copy ((SimpleString) my categories -> item[1]); Ordered_addItemAtPosition_move (my categories.peek(), (SimpleString) categories -> item[my selection[i]], 2); // YUCK categories -> item[my selection[i]] = str.releaseToAmbiguousOwner(); } update (editor, my selection[1], my selection[my nSelected], my selection, my nSelected); return 1; }
static int CategoriesEditorRemove_execute (CategoriesEditorRemove me) { CategoriesEditor editor = static_cast<CategoriesEditor> (my boss); Categories categories = static_cast<Categories> (editor -> data); for (long i = my nSelected; i >= 1; i--) { autoSimpleString item = Data_copy ((SimpleString) categories -> item[my selection[i]]); Ordered_addItemAtPosition_move (my categories.peek(), item.move(), 1); Collection_removeItem (categories, my selection[i]); } update (editor, my selection[1], 0, nullptr, 0); return 1; }
void praat_addAction4 (ClassInfo class1, int n1, ClassInfo class2, int n2, ClassInfo class3, int n3, ClassInfo class4, int n4, const char32 *title, const char32 *after, unsigned long flags, UiCallback callback) { try { int depth = flags, key = 0; bool unhidable = false, hidden = false, attractive = false; unsigned long motifFlags = 0; if (flags > 7) { depth = ((flags & praat_DEPTH_7) >> 16); unhidable = (flags & praat_UNHIDABLE) != 0; hidden = (flags & praat_HIDDEN) != 0 && ! unhidable; key = flags & 0x000000FF; motifFlags = key ? flags & (0x002000FF | GuiMenu_BUTTON_STATE_MASK) : flags & GuiMenu_BUTTON_STATE_MASK; attractive = (motifFlags & praat_ATTRACTIVE) != 0; } fixSelectionSpecification (& class1, & n1, & class2, & n2, & class3, & n3); if (callback && ! title) Melder_throw (U"An action command with callback has no title. Classes: ", class1 ? class1 -> className : U"", U" ", class2 ? class2 -> className : U"", U" ", class3 ? class3 -> className : U"", U" ", class4 ? class4 -> className : U"", U"."); if (! class1) Melder_throw (U"The action command \"", title, U"\" has no first class."); /* * Determine the position of the new command. */ long position; if (after) { // search for existing command with same selection long found = lookUpMatchingAction (class1, class2, class3, class4, after); if (found == 0) Melder_throw (U"The action command \"", title, U"\" cannot be put after \"", after, U"\",\n" U"because the latter command does not exist."); position = found + 1; // after 'after' } else { position = theActions -> size + 1; // at end } /* * Make new command. */ autoPraat_Command action = Thing_new (Praat_Command); action -> class1 = class1; action -> n1 = n1; action -> class2 = class2; action -> n2 = n2; action -> class3 = class3; action -> n3 = n3; action -> class4 = class4; action -> n4 = n4; action -> title = Melder_dup_f (title); action -> depth = depth; action -> callback = callback; // null for a separator action -> button = nullptr; action -> script = nullptr; action -> hidden = hidden; action -> unhidable = unhidable; action -> attractive = attractive; /* * Insert new command. */ Ordered_addItemAtPosition_move (theActions, action.move(), position); } catch (MelderError) {
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 -> numberOfIntervals ()) Melder_throw (U"Interval ", intervalNumber, U" does not exist."); TextInterval interval = headTier -> interval (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.peek(), part.peek(), interval, silenceThreshold, minSilenceDuration, minSoundingDuration); } catch (MelderError) { Melder_clearError (); // ignore all error messages from DTW and the like } } if (analysis.peek()) { /* * Clean up the analysis. */ Melder_assert (analysis -> xmin == interval -> xmin); Melder_assert (analysis -> xmax == interval -> xmax); Melder_assert (analysis -> numberOfTiers () == 4); Thing_cast (IntervalTier, analysisWordTier, analysis -> tier (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 -> numberOfIntervals () >= 1); TextInterval firstInterval = analysisWordTier -> interval (1); TextInterval lastInterval = analysisWordTier -> interval (analysisWordTier -> numberOfIntervals ()); 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 -> tier (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 -> numberOfIntervals () >= 1); firstInterval = analysisPhonemeTier -> interval (1); lastInterval = analysisPhonemeTier -> interval (analysisPhonemeTier -> numberOfIntervals ()); 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 numberOfTiers (); itier ++) { IntervalTier tier = static_cast <IntervalTier> (my tier (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.peek(), newWordTierName.string); Ordered_addItemAtPosition_move (my tiers.get(), newWordTier.move(), wordTierNumber = tierNumber + 1); } Melder_assert (wordTierNumber >= 1 && wordTierNumber <= my tiers -> size); wordTier = static_cast <IntervalTier> (my tier (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.peek()) { Thing_cast (IntervalTier, analysisWordTier, analysis -> tier (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 -> numberOfIntervals (); ianalysisInterval ++) { TextInterval analysisInterval = analysisWordTier -> interval (ianalysisInterval); TextInterval wordInterval = nullptr; double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax; if (tmax == analysis -> xmax) { wordInterval = wordTier -> interval (wordIntervalNumber); TextInterval_setText (wordInterval, analysisInterval -> text); } else { wordInterval = wordTier -> interval (wordIntervalNumber); autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text); wordInterval -> xmin = tmax; Collection_addItem_move (wordTier -> intervals.get(), 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 numberOfTiers (); itier ++) { IntervalTier tier = static_cast <IntervalTier> (my tier (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.peek(), newPhonemeTierName.string); Ordered_addItemAtPosition_move (my tiers.get(), newPhonemeTier.move(), phonemeTierNumber = wordTierNumber ? wordTierNumber + 1 : tierNumber + 1); } Melder_assert (phonemeTierNumber >= 1 && phonemeTierNumber <= my tiers -> size); phonemeTier = static_cast <IntervalTier> (my tiers -> item [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.peek()) { Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers -> item [4]); for (long ianalysisInterval = 1; ianalysisInterval <= analysisPhonemeTier -> numberOfIntervals (); ianalysisInterval ++) { TextInterval analysisInterval = analysisPhonemeTier -> interval (ianalysisInterval); TextInterval phonemeInterval = nullptr; double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax; if (tmax == analysis -> xmax) { phonemeInterval = phonemeTier -> interval (phonemeIntervalNumber); TextInterval_setText (phonemeInterval, analysisInterval -> text); } else { phonemeInterval = phonemeTier -> interval (phonemeIntervalNumber); autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text); phonemeInterval -> xmin = tmax; Collection_addItem_move (phonemeTier -> intervals.get(), 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."); } }