static void IntervalTier_insertIntervalDestructively (IntervalTier me, double tmin, double tmax) { Melder_assert (tmin < tmax); Melder_assert (tmin >= my xmin); Melder_assert (tmax <= my xmax); /* * Make sure that the tier has boundaries at the edges of the interval. */ long firstIntervalNumber = IntervalTier_hasTime (me, tmin); if (! firstIntervalNumber) { long intervalNumber = IntervalTier_timeToIndex (me, tmin); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (tmin, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = my intervals.at [intervalNumber]; /* * Move the text to the left of the boundary. */ autoTextInterval newInterval = TextInterval_create (tmin, interval -> xmax, U""); interval -> xmax = tmin; my intervals. addItem_move (newInterval.move()); firstIntervalNumber = IntervalTier_hasTime (me, interval -> xmin); } Melder_assert (firstIntervalNumber >= 1 && firstIntervalNumber <= my intervals.size); long lastIntervalNumber = IntervalTier_hasTime (me, tmax); if (! lastIntervalNumber) { long intervalNumber = IntervalTier_timeToIndex (me, tmax); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (tmin, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = my intervals.at [intervalNumber]; /* * Move the text to the right of the boundary. */ autoTextInterval newInterval = TextInterval_create (interval -> xmin, tmax, U""); interval -> xmin = tmax; my intervals. addItem_move (newInterval.move()); lastIntervalNumber = IntervalTier_hasTime (me, interval -> xmax); } Melder_assert (lastIntervalNumber >= 1 && lastIntervalNumber <= my intervals.size); /* * Empty the interval in the word tier. */ trace (U"Empty interval %ld down to ", lastIntervalNumber, U".", firstIntervalNumber); for (long iinterval = lastIntervalNumber; iinterval >= firstIntervalNumber; iinterval --) { TextInterval interval = my intervals.at [iinterval]; if (interval -> xmin > tmin && interval -> xmin < tmax) { Melder_assert (iinterval > 1); TextInterval previous = my intervals.at [iinterval - 1]; previous -> xmax = tmax; // collapse left and right intervals into left interval TextInterval_setText (previous, U""); my intervals. removeItem (iinterval); // remove right interval } if (interval -> xmax == tmax) { TextInterval_setText (interval, U""); } } }
static void IntervalTier_add (IntervalTier me, double xmin, double xmax, const char32 *label) { long i = IntervalTier_timeToIndex (me, xmin); // xmin is in interval i if (i < 1) { Melder_throw (U"Index too low."); } autoTextInterval newti = TextInterval_create (xmin, xmax, label); TextInterval interval = (TextInterval) my intervals -> item[i]; double xmaxi = interval -> xmax; if (xmax > xmaxi) { Melder_throw (U"Don't know what to do"); // Don't know what to do } if (xmin == interval -> xmin) { if (xmax == interval -> xmax) { // interval already present TextInterval_setText (interval, label); return; } // split interval interval -> xmin = xmax; Collection_addItem (my intervals, newti.transfer()); return; } interval -> xmax = xmin; Collection_addItem (my intervals, newti.transfer()); // extra interval when xmax's are not the same if (xmax < xmaxi) { autoTextInterval newti2 = TextInterval_create (xmax, xmaxi, interval -> text); Collection_addItem (my intervals, newti2.transfer()); } }