static long Pitch_getMeanAbsoluteSlope (Pitch me, double *out_hertz, double *out_mel, double *out_semitones, double *out_erb, double *out_withoutOctaveJumps) { long firstVoicedFrame = 0, lastVoicedFrame = 0, nVoiced = 0, i; double *frequencies = NUMvector <double> (1, my nx); for (i = 1; i <= my nx; i ++) { double frequency = my frame [i]. candidate [1]. frequency; frequencies [i] = frequency > 0.0 && frequency < my ceiling ? frequency : 0.0; if (frequencies [i]) nVoiced ++; } for (i = 1; i <= my nx; i ++) /* Look for first voiced frame. */ if (frequencies [i] != 0.0) { firstVoicedFrame = i; break; } for (i = my nx; i >= 1; i --) /* Look for last voiced frame. */ if (frequencies [i] != 0.0) { lastVoicedFrame = i; break; } if (nVoiced > 1) { int ilast = firstVoicedFrame; double span = (lastVoicedFrame - firstVoicedFrame) * my dx, flast = frequencies [ilast]; double slopeHz = 0, slopeMel = 0, slopeSemitones = 0, slopeErb = 0, slopeRobust = 0; for (i = firstVoicedFrame + 1; i <= lastVoicedFrame; i ++) if (frequencies [i] != 0.0) { double localStepSemitones = fabs (SEMITONES (frequencies [i]) - SEMITONES (flast)); slopeHz += fabs (frequencies [i] - flast); slopeMel += fabs (MEL (frequencies [i]) - MEL (flast)); slopeSemitones += localStepSemitones; slopeErb += fabs (ERB (frequencies [i]) - ERB (flast)); while (localStepSemitones >= 12.0) localStepSemitones -= 12.0; /* Kill octave jumps. */ if (localStepSemitones > 6.0) localStepSemitones = 12.0 - localStepSemitones; slopeRobust += localStepSemitones; ilast = i; flast = frequencies [i]; } if (out_hertz) *out_hertz = slopeHz / span; if (out_mel) *out_mel = slopeMel / span; if (out_semitones) *out_semitones = slopeSemitones / span; if (out_erb) *out_erb = slopeErb / span; if (out_withoutOctaveJumps) *out_withoutOctaveJumps = slopeRobust / span; } else { if (out_hertz) *out_hertz = NUMundefined; if (out_mel) *out_mel = NUMundefined; if (out_semitones) *out_semitones = NUMundefined; if (out_erb) *out_erb = NUMundefined; if (out_withoutOctaveJumps) *out_withoutOctaveJumps = NUMundefined; } NUMvector_free (frequencies, 1); return nVoiced; }
void structPitch :: v_info () { long nVoiced; autoNUMvector <double> frequencies (Sampled_getSortedValues (this, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ, & nVoiced), 1); structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of frames: ", nx, U" (", nVoiced, U" voiced)"); MelderInfo_writeLine (U" Time step: ", dx, U" seconds"); MelderInfo_writeLine (U" First frame centred at: ", x1, U" seconds"); MelderInfo_writeLine (U"Ceiling at: ", ceiling, U" Hz"); if (nVoiced >= 1) { // quantiles double quantile10, quantile16, quantile50, quantile84, quantile90; quantile10 = NUMquantile (nVoiced, frequencies.peek(), 0.10); quantile16 = NUMquantile (nVoiced, frequencies.peek(), 0.16); quantile50 = NUMquantile (nVoiced, frequencies.peek(), 0.50); // median quantile84 = NUMquantile (nVoiced, frequencies.peek(), 0.84); quantile90 = NUMquantile (nVoiced, frequencies.peek(), 0.90); MelderInfo_writeLine (U"\nEstimated quantiles:"); MelderInfo_write (U" 10% = ", Melder_single (quantile10), U" Hz = ", Melder_single (MEL (quantile10)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile10)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile10)), U" ERB"); MelderInfo_write (U" 16% = ", Melder_single (quantile16), U" Hz = ", Melder_single (MEL (quantile16)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile16)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile16)), U" ERB"); MelderInfo_write (U" 50% = ", Melder_single (quantile50), U" Hz = ", Melder_single (MEL (quantile50)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile50)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile50)), U" ERB"); MelderInfo_write (U" 84% = ", Melder_single (quantile84), U" Hz = ", Melder_single (MEL (quantile84)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile84)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile84)), U" ERB"); MelderInfo_write (U" 90% = ", Melder_single (quantile90), U" Hz = ", Melder_single (MEL (quantile90)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile90)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile90)), U" ERB"); if (nVoiced > 1) { double corr = sqrt (nVoiced / (nVoiced - 1.0)); MelderInfo_writeLine (U"\nEstimated spreading:"); MelderInfo_write (U" 84%-median = ", Melder_half ((quantile84 - quantile50) * corr), U" Hz = ", Melder_half ((MEL (quantile84) - MEL (quantile50)) * corr), U" Mel = "); MelderInfo_writeLine (Melder_half ((SEMITONES (quantile84) - SEMITONES (quantile50)) * corr), U" semitones = ", Melder_half ((ERB (quantile84) - ERB (quantile50)) * corr), U" ERB"); MelderInfo_write (U" median-16% = ", Melder_half ((quantile50 - quantile16) * corr), U" Hz = ", Melder_half ((MEL (quantile50) - MEL (quantile16)) * corr), U" Mel = "); MelderInfo_writeLine (Melder_half ((SEMITONES (quantile50) - SEMITONES (quantile16)) * corr), U" semitones = ", Melder_half ((ERB (quantile50) - ERB (quantile16)) * corr), U" ERB"); MelderInfo_write (U" 90%-10% = ", Melder_half ((quantile90 - quantile10) * corr), U" Hz = ", Melder_half ((MEL (quantile90) - MEL (quantile10)) * corr), U" Mel = "); MelderInfo_writeLine (Melder_half ((SEMITONES (quantile90) - SEMITONES (quantile10)) * corr), U" semitones = ", Melder_half ((ERB (quantile90) - ERB (quantile10)) * corr), U" ERB"); } } if (nVoiced >= 1) { // extrema, range, mean and standard deviation double minimum = Pitch_getMinimum (this, xmin, xmax, kPitch_unit_HERTZ, false); double maximum = Pitch_getMaximum (this, xmin, xmax, kPitch_unit_HERTZ, false); double meanHertz, meanMel, meanSemitones, meanErb; MelderInfo_write (U"\nMinimum ", Melder_single (minimum), U" Hz = ", Melder_single (MEL (minimum)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (minimum)), U" semitones above 100 Hz = ", Melder_single (ERB (minimum)), U" ERB"); MelderInfo_write (U"Maximum ", Melder_single (maximum), U" Hz = ", Melder_single (MEL (maximum)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (maximum)), U" semitones above 100 Hz = ", Melder_single (ERB (maximum)), U" ERB"); MelderInfo_write (U"Range ", Melder_half (maximum - minimum), U" Hz = ", Melder_single (MEL (maximum) - MEL (minimum)), U" Mel = "); MelderInfo_writeLine (Melder_half (SEMITONES (maximum) - SEMITONES (minimum)), U" semitones = ", Melder_half (ERB (maximum) - ERB (minimum)), U" ERB"); meanHertz = Pitch_getMean (this, 0, 0, kPitch_unit_HERTZ); meanMel = Pitch_getMean (this, 0, 0, kPitch_unit_MEL); meanSemitones = Pitch_getMean (this, 0, 0, kPitch_unit_SEMITONES_100); meanErb = Pitch_getMean (this, 0, 0, kPitch_unit_ERB); MelderInfo_write (U"Average: ", Melder_single (meanHertz), U" Hz = ", Melder_single (meanMel), U" Mel = "); MelderInfo_writeLine (Melder_single (meanSemitones), U" semitones above 100 Hz = ", Melder_single (meanErb), U" ERB"); if (nVoiced >= 2) { double stdevHertz = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_HERTZ); double stdevMel = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_MEL); double stdevSemitones = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_SEMITONES_100); double stdevErb = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_ERB); MelderInfo_write (U"Standard deviation: ", Melder_half (stdevHertz), U" Hz = ", Melder_half (stdevMel), U" Mel = "); MelderInfo_writeLine (Melder_half (stdevSemitones), U" semitones = ", Melder_half (stdevErb), U" ERB"); } } if (nVoiced > 1) { // variability: mean absolute slope double slopeHertz, slopeMel, slopeSemitones, slopeErb, slopeWithoutOctaveJumps; Pitch_getMeanAbsoluteSlope (this, & slopeHertz, & slopeMel, & slopeSemitones, & slopeErb, & slopeWithoutOctaveJumps); MelderInfo_write (U"\nMean absolute slope: ", Melder_half (slopeHertz), U" Hz/s = ", Melder_half (slopeMel), U" Mel/s = "); MelderInfo_writeLine (Melder_half (slopeSemitones), U" semitones/s = ", Melder_half (slopeErb), U" ERB/s"); MelderInfo_writeLine (U"Mean absolute slope without octave jumps: ", Melder_half (slopeWithoutOctaveJumps), U" semitones/s"); } }