static void menu_cb_DrawSelectedSound (TimeSoundEditor me, EDITOR_ARGS_FORM) { EDITOR_FORM (U"Draw selected sound", nullptr) my v_form_pictureWindow (cmd); LABEL (U"", U"Sound:") BOOLEAN (U"Preserve times", my default_picture_preserveTimes ()); REAL (U"left Vertical range", my default_picture_bottom ()); REAL (U"right Vertical range", my default_picture_top ()); my v_form_pictureMargins (cmd); BOOLEAN (U"Garnish", my default_picture_garnish ()); EDITOR_OK my v_ok_pictureWindow (cmd); SET_INTEGER (U"Preserve times", my pref_picture_preserveTimes ()); SET_REAL (U"left Vertical range", my pref_picture_bottom ()); SET_REAL (U"right Vertical range", my pref_picture_top ()); my v_ok_pictureMargins (cmd); SET_INTEGER (U"Garnish", my pref_picture_garnish ()); EDITOR_DO my v_do_pictureWindow (cmd); my pref_picture_preserveTimes () = GET_INTEGER (U"Preserve times"); my pref_picture_bottom () = GET_REAL (U"left Vertical range"); my pref_picture_top () = GET_REAL (U"right Vertical range"); my v_do_pictureMargins (cmd); my pref_picture_garnish () = GET_INTEGER (U"Garnish"); if (! my d_longSound.data && ! my d_sound.data) Melder_throw (U"There is no sound to draw."); autoSound publish = my d_longSound.data ? LongSound_extractPart (my d_longSound.data, my d_startSelection, my d_endSelection, my pref_picture_preserveTimes ()) : Sound_extractPart (my d_sound.data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ()); Editor_openPraatPicture (me); Sound_draw (publish.peek(), my pictureGraphics, 0.0, 0.0, my pref_picture_bottom (), my pref_picture_top (), my pref_picture_garnish (), U"Curve"); Editor_closePraatPicture (me); EDITOR_END }
static void menu_cb_Copy (SoundEditor me, EDITOR_ARGS_DIRECT) { try { Sound_clipboard = my d_longSound.data ? LongSound_extractPart ((LongSound) my data, my d_startSelection, my d_endSelection, false) : Sound_extractPart ((Sound) my data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, false); } catch (MelderError) { Melder_throw (U"Sound selection not copied to clipboard."); } }
int SoundEditor::menu_cb_Copy (EDITOR_ARGS) { SoundEditor *editor = (SoundEditor *)editor_me; Sound publish = editor->_longSound.data ? LongSound_extractPart ((LongSound) editor->_data, editor->_startSelection, editor->_endSelection, FALSE) : Sound_extractPart ((Sound) editor->_data, editor->_startSelection, editor->_endSelection, kSound_windowShape_RECTANGULAR, 1.0, FALSE); iferror return 0; forget (Sound_clipboard); Sound_clipboard = publish; return 1; }
static void do_ExtractSelectedSound (TimeSoundEditor me, bool preserveTimes) { autoSound extract; if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection."); if (my d_longSound.data) { extract = LongSound_extractPart (my d_longSound.data, my d_startSelection, my d_endSelection, preserveTimes); } else if (my d_sound.data) { extract = Sound_extractPart (my d_sound.data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes); } Editor_broadcastPublication (me, extract.transfer()); }
static void menu_cb_Copy (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); try { /* * Create without change. */ autoSound publish = my d_longSound.data ? LongSound_extractPart ((LongSound) my data, my d_startSelection, my d_endSelection, FALSE) : Sound_extractPart ((Sound) my data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, FALSE); /* * Change without error. */ forget (Sound_clipboard); Sound_clipboard = publish.transfer(); } catch (MelderError) { Melder_throw ("Sound selection not copied to clipboard."); } }
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."); } }