void Vector_getMinimumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation, double *return_minimum, double *return_xOfMinimum, long *return_channelOfMinimum) { double minimum, xOfMinimum; long channelOfMinimum = 1; Vector_getMinimumAndX (me, xmin, xmax, 1, interpolation, & minimum, & xOfMinimum); for (long channel = 2; channel <= my ny; channel ++) { double minimumOfChannel, xOfMinimumOfChannel; Vector_getMinimumAndX (me, xmin, xmax, channel, interpolation, & minimumOfChannel, & xOfMinimumOfChannel); if (minimumOfChannel < minimum) { minimum = minimumOfChannel; xOfMinimum = xOfMinimumOfChannel; channelOfMinimum = channel; } } if (return_minimum) *return_minimum = minimum; if (return_xOfMinimum) *return_xOfMinimum = xOfMinimum; if (return_channelOfMinimum) *return_channelOfMinimum = channelOfMinimum; }
autoRealTier Vector_to_RealTier_valleys (Vector me, long channel, ClassInfo klas) { try { autoRealTier thee = RealTier_createWithClass (my xmin, my xmax, klas); for (long i = 2; i < my nx; i ++) { double left = my z [channel] [i - 1], centre = my z [channel] [i], right = my z [channel] [i + 1]; if (left >= centre && right > centre) { double x, minimum; Vector_getMinimumAndX (me, my x1 + (i - 2.5) * my dx, my x1 + (i + 0.5) * my dx, channel, NUM_PEAK_INTERPOLATE_PARABOLIC, & minimum, & x); RealTier_addPoint (thee.get(), x, minimum); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to ", klas -> className, U" (valleys)."); } }
TextGrid Intensity_to_TextGrid_detectSilences (Intensity me, double silenceThreshold_dB, double minSilenceDuration, double minSoundingDuration, const char32 *silenceLabel, const char32 *soundingLabel) { try { double duration = my xmax - my xmin, time; if (silenceThreshold_dB >= 0) { Melder_throw (U"The silence threshold w.r.t. the maximum intensity should be a negative number."); } autoTextGrid thee = TextGrid_create (my xmin, my xmax, U"silences", U""); IntervalTier it = (IntervalTier) thy tiers -> item[1]; TextInterval_setText ( (TextInterval) it -> intervals -> item[1], soundingLabel); if (minSilenceDuration > duration) { return thee.transfer(); } double intensity_max_db, intensity_min_db, xOfMaximum, xOfMinimum; Vector_getMaximumAndX (me, 0, 0, 1, NUM_PEAK_INTERPOLATE_PARABOLIC, &intensity_max_db, &xOfMaximum); Vector_getMinimumAndX (me, 0, 0, 1, NUM_PEAK_INTERPOLATE_PARABOLIC, &intensity_min_db, &xOfMinimum); double intensity_dbRange = intensity_max_db - intensity_min_db; if (intensity_dbRange < 10) Melder_warning (U"The loudest and softest part in your sound only differ by ", intensity_dbRange, U" dB."); double intensityThreshold = intensity_max_db - fabs (silenceThreshold_dB); if (minSilenceDuration > duration || intensityThreshold < intensity_min_db) { return thee.transfer(); } int inSilenceInterval = my z[1][1] < intensityThreshold; long iinterval = 1; const char32 *label; for (long i = 2; i <= my nx; i++) { int addBoundary = 0; if (my z[1][i] < intensityThreshold) { if (!inSilenceInterval) { // Start of silence addBoundary = 1; inSilenceInterval = 1; label = soundingLabel; } } else { if (inSilenceInterval) { // End of silence addBoundary = 1; inSilenceInterval = 0; label = silenceLabel; } } if (addBoundary) { time = my x1 + (i - 1) * my dx; IntervalTier_addBoundaryUnsorted (it, iinterval, time, label); iinterval++; } } // (re)label last interval */ label = inSilenceInterval ? silenceLabel : soundingLabel; TextInterval_setText ( (TextInterval) it -> intervals -> item[iinterval], label); Sorted_sort (it -> intervals); // First remove short non-silence intervals in-between silence intervals and // then remove the remaining short silence intervals. // This works much better than first removing short silence intervals and // then short non-silence intervals. IntervalTier_cutIntervals_minimumDuration (it, soundingLabel, minSoundingDuration); IntervalTier_cutIntervalsOnLabelMatch (it, silenceLabel); IntervalTier_cutIntervals_minimumDuration (it, silenceLabel, minSilenceDuration); IntervalTier_cutIntervalsOnLabelMatch (it, soundingLabel); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": TextGrid not created."); } }