PointProcess Sound_Pitch_to_PointProcess_peaks (Sound sound, Pitch pitch, int includeMaxima, int includeMinima) { PointProcess point = PointProcess_create (sound -> xmin, sound -> xmax, 10); double t = pitch -> xmin; double addedRight = -1e300; /* * Cycle over all voiced intervals. */ for (;;) { double tleft, tright, tmiddle, f0middle, tmax, tsave; if (! Pitch_getVoicedIntervalAfter (pitch, t, & tleft, & tright)) break; /* * Go to the middle of the voiced interval. */ tmiddle = (tleft + tright) / 2; if (! Melder_progress1 ((tmiddle - sound -> xmin) / (sound -> xmax - sound -> xmin), L"Sound & Pitch to PointProcess")) goto end; f0middle = Pitch_getValueAtTime (pitch, tmiddle, kPitch_unit_HERTZ, Pitch_LINEAR); /* * Our first point is near this middle. */ Melder_assert (NUMdefined (f0middle)); tmax = Sound_findExtremum (sound, tmiddle - 0.5 / f0middle, tmiddle + 0.5 / f0middle, includeMaxima, includeMinima); Melder_assert (NUMdefined (tmax)); if (! PointProcess_addPoint (point, tmax)) goto end; tsave = tmax; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR); if (f0 == NUMundefined) break; tmax = Sound_findExtremum (sound, tmax - 1.25 / f0, tmax - 0.8 / f0, includeMaxima, includeMinima); if (tmax < tleft) { if (tmax - addedRight > 0.8 / f0) if (! PointProcess_addPoint (point, tmax)) goto end; break; } if (tmax - addedRight > 0.8 / f0) /* Do not fill in a short originally unvoiced interval twice. */ if (! PointProcess_addPoint (point, tmax)) goto end; } tmax = tsave; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR); if (f0 == NUMundefined) break; tmax = Sound_findExtremum (sound, tmax + 0.8 / f0, tmax + 1.25 / f0, includeMaxima, includeMinima); if (tmax > tright) { if (! PointProcess_addPoint (point, tmax)) goto end; addedRight = tmax; break; } if (! PointProcess_addPoint (point, tmax)) goto end; addedRight = tmax; } t = tright; } end: Melder_progress1 (1.0, NULL); iferror forget (point); return point; }
autoPitchTier Pitch_AnyTier_to_PitchTier (Pitch pitch, AnyTier tier, int checkMethod) { try { SortedSetOfDouble points = tier -> points; if (checkMethod == 2) { autoPitchTier temp = Pitch_to_PitchTier (pitch); autoPitchTier thee = PitchTier_AnyTier_to_PitchTier (temp.peek(), tier); return thee.transfer(); } /* * Result's domain is a union of both domains. */ autoPitchTier thee = PitchTier_create ( pitch -> xmin < tier -> xmin ? pitch -> xmin : tier -> xmin, pitch -> xmax > tier -> xmax ? pitch -> xmax : tier -> xmax); /* * Copy pitch's frequencies at tier's points to the resulting PitchTier. */ for (long ipoint = 1; ipoint <= points -> size; ipoint ++) { AnyPoint point = (AnyPoint) points -> item [ipoint]; double time = point -> number; double frequency = Pitch_getValueAtTime (pitch, time, kPitch_unit_HERTZ, Pitch_LINEAR); if (frequency == NUMundefined && checkMethod) Melder_throw (U"No periodicity at time ", time, U" seconds."); RealTier_addPoint (thee.peek(), time, frequency); } return thee; } catch (MelderError) { Melder_throw (pitch, U" & ", tier, U": not converted to PitchTier."); } }
static void menu_cb_getPitch (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); if (my d_startSelection == my d_endSelection) { Melder_informationReal (Pitch_getValueAtTime ((Pitch) my data, my d_startSelection, kPitch_unit_HERTZ, 1), L"Hz"); } else { Melder_informationReal (Pitch_getMean ((Pitch) my data, my d_startSelection, my d_endSelection, kPitch_unit_HERTZ), L"Hz"); } }
void structPitchEditor :: v_draw () { Pitch pitch = (Pitch) our data; long it, it1, it2; double dyUnv, dyIntens; Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_rectangle (our d_graphics, 0, 1, 0, 1); dyUnv = Graphics_dyMMtoWC (our d_graphics, HEIGHT_UNV); dyIntens = Graphics_dyMMtoWC (our d_graphics, HEIGHT_INTENS); Sampled_getWindowSamples (pitch, our d_startWindow, our d_endWindow, & it1, & it2); /* * Show pitch. */ { long df = pitch -> ceiling > 10000 ? 2000 : pitch -> ceiling > 5000 ? 1000 : pitch -> ceiling > 2000 ? 500 : pitch -> ceiling > 800 ? 200 : pitch -> ceiling > 400 ? 100 : 50; double radius; Graphics_Viewport previous; previous = Graphics_insetViewport (our d_graphics, 0, 1, dyUnv, 1 - dyIntens); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0, pitch -> ceiling); radius = Graphics_dxMMtoWC (our d_graphics, RADIUS); /* Horizontal hair at current pitch. */ if (our d_startSelection == our d_endSelection && our d_startSelection >= our d_startWindow && our d_startSelection <= our d_endWindow) { double f = Pitch_getValueAtTime (pitch, our d_startSelection, kPitch_unit_HERTZ, Pitch_LINEAR); if (NUMdefined (f)) { Graphics_setColour (our d_graphics, Graphics_RED); Graphics_line (our d_graphics, our d_startWindow - radius, f, our d_endWindow, f); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text1 (our d_graphics, our d_startWindow - radius, f, Melder_fixed (f, 2)); } } /* Horizontal scaling lines. */ Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_setLineType (our d_graphics, Graphics_DOTTED); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); for (long f = df; f <= pitch -> ceiling; f += df) { Graphics_line (our d_graphics, our d_startWindow, f, our d_endWindow, f); Graphics_text2 (our d_graphics, our d_endWindow + radius/2, f, Melder_integer (f), L" Hz"); } Graphics_setLineType (our d_graphics, Graphics_DRAWN); /* Show candidates. */ for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it); double f = frame -> candidate [1]. frequency; if (f > 0.0 && f < pitch -> ceiling) { Graphics_setColour (our d_graphics, Graphics_MAGENTA); Graphics_fillCircle_mm (our d_graphics, t, f, RADIUS * 2); } Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); for (int icand = 1; icand <= frame -> nCandidates; icand ++) { int strength = (int) floor (10 * frame -> candidate [icand]. strength + 0.5); f = frame -> candidate [icand]. frequency; if (strength > 9) strength = 9; if (f > 0 && f <= pitch -> ceiling) Graphics_text1 (our d_graphics, t, f, Melder_integer (strength)); } } Graphics_resetViewport (our d_graphics, previous); } /* * Show intensity. */ { Graphics_Viewport previous = Graphics_insetViewport (our d_graphics, 0, 1, 1 - dyIntens, 1); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, 0.5, L"intens"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, 0.5, L"intens"); Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it); int strength = (int) floor (10 * frame -> intensity + 0.5); // map 0.0-1.0 to 0-9 if (strength > 9) strength = 9; Graphics_text1 (our d_graphics, t, 0.5, Melder_integer (strength)); } Graphics_resetViewport (our d_graphics, previous); } if (it1 > 1) it1 -= 1; if (it2 < pitch -> nx) it2 += 1; /* * Show voicelessness. */ { Graphics_Viewport previous = Graphics_insetViewport (our d_graphics, 0, 1, 0, dyUnv); Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_line (our d_graphics, our d_startWindow, 1, our d_endWindow, 1); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, 0.5, L"Unv"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, 0.5, L"Unv"); for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it), tleft = t - 0.5 * pitch -> dx, tright = t + 0.5 * pitch -> dx; double f = frame -> candidate [1]. frequency; if ((f > 0.0 && f < pitch -> ceiling) || tright <= our d_startWindow || tleft >= our d_endWindow) continue; if (tleft < our d_startWindow) tleft = our d_startWindow; if (tright > our d_endWindow) tright = our d_endWindow; Graphics_fillRectangle (our d_graphics, tleft, tright, 0, 1); } Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_resetViewport (our d_graphics, previous); } }
FormantFilter Sound_and_Pitch_to_FormantFilter (Sound me, Pitch thee, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw) { try { double t1, windowDuration = 2 * analysisWidth; /* gaussian window */ double nyquist = 0.5 / my dx, samplingFrequency = 2 * nyquist, fmin_hz = 0; long nt, f0_undefined = 0; if (my xmin > thy xmin || my xmax > thy xmax) Melder_throw ("The domain of the Sound is not included in the domain of the Pitch."); double f0_median = Pitch_getQuantile (thee, thy xmin, thy xmax, 0.5, kPitch_unit_HERTZ); if (f0_median == NUMundefined || f0_median == 0) { f0_median = 100; Melder_warning (L"Pitch values undefined. Bandwith fixed to 100 Hz. "); } if (f1_hz <= 0) { f1_hz = 100; } if (fmax_hz <= 0) { fmax_hz = nyquist; } if (df_hz <= 0) { df_hz = f0_median / 2; } if (relative_bw <= 0) { relative_bw = 1.1; } fmax_hz = MIN (fmax_hz, nyquist); long nf = floor ( (fmax_hz - f1_hz) / df_hz + 0.5); Sampled_shortTermAnalysis (me, windowDuration, dt, &nt, &t1); autoFormantFilter him = FormantFilter_create (my xmin, my xmax, nt, dt, t1, fmin_hz, fmax_hz, nf, df_hz, f1_hz); // Temporary objects autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelderProgress progress (L"Sound & Pitch: To FormantFilter"); for (long i = 1; i <= nt; i++) { double t = Sampled_indexToX (him.peek(), i); double b, f0 = Pitch_getValueAtTime (thee, t, kPitch_unit_HERTZ, 0); if (f0 == NUMundefined || f0 == 0) { f0_undefined++; f0 = f0_median; } b = relative_bw * f0; Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); Sound_into_FormantFilter_frame (sframe.peek(), him.peek(), i, b); if ( (i % 10) == 1) { Melder_progress ( (double) i / nt, L"Frame ", Melder_integer (i), L" out of ", Melder_integer (nt), L"."); } } double ref = FilterBank_DBREF * gaussian_window_squared_correction (window -> nx); NUMdmatrix_to_dBs (his z, 1, his ny, 1, his nx, ref, FilterBank_DBFAC, FilterBank_DBFLOOR); return him.transfer(); } catch (MelderError) { Melder_throw ("FormantFilter not created from Pitch & FormantFilter."); } }
autoSpectrogram Sound_and_Pitch_to_Spectrogram (Sound me, Pitch thee, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw) { try { double t1, windowDuration = 2.0 * analysisWidth; /* gaussian window */ double nyquist = 0.5 / my dx, samplingFrequency = 2.0 * nyquist, fmin_hz = 0.0; long numberOfFrames, f0_undefined = 0.0; if (my xmin > thy xmin || my xmax > thy xmax) Melder_throw (U"The domain of the Sound is not included in the domain of the Pitch."); double f0_median = Pitch_getQuantile (thee, thy xmin, thy xmax, 0.5, kPitch_unit_HERTZ); if (f0_median == NUMundefined || f0_median == 0.0) { f0_median = 100.0; Melder_warning (U"Pitch values undefined. Bandwith fixed to 100 Hz. "); } if (f1_hz <= 0.0) { f1_hz = 100.0; } if (fmax_hz <= 0.0) { fmax_hz = nyquist; } if (df_hz <= 0.0) { df_hz = f0_median / 2.0; } if (relative_bw <= 0.0) { relative_bw = 1.1; } fmax_hz = MIN (fmax_hz, nyquist); long numberOfFilters = lround ( (fmax_hz - f1_hz) / df_hz); Sampled_shortTermAnalysis (me, windowDuration, dt, &numberOfFrames, &t1); autoSpectrogram him = Spectrogram_create (my xmin, my xmax, numberOfFrames, dt, t1, fmin_hz, fmax_hz, numberOfFilters, df_hz, f1_hz); // Temporary objects autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelderProgress progress (U"Sound & Pitch: To FormantFilter"); for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double t = Sampled_indexToX (him.get(), iframe); double b, f0 = Pitch_getValueAtTime (thee, t, kPitch_unit_HERTZ, 0); if (f0 == NUMundefined || f0 == 0.0) { f0_undefined ++; f0 = f0_median; } b = relative_bw * f0; Sound_into_Sound (me, sframe.get(), t - windowDuration / 2.0); Sounds_multiply (sframe.get(), window.get()); Sound_into_Spectrogram_frame (sframe.get(), him.get(), iframe, b); if (iframe % 10 == 1) { Melder_progress ( (double) iframe / numberOfFrames, U"Frame ", iframe, U" out of ", numberOfFrames, U"."); } } _Spectrogram_windowCorrection (him.get(), window -> nx); return him; } catch (MelderError) { Melder_throw (U"FormantFilter not created from Pitch & FormantFilter."); } }
PointProcess Sound_Pitch_to_PointProcess_cc (Sound sound, Pitch pitch) { PointProcess point = PointProcess_create (sound -> xmin, sound -> xmax, 10); double t = pitch -> xmin; double addedRight = -1e300; double globalPeak = Vector_getAbsoluteExtremum (sound, sound -> xmin, sound -> xmax, 0), peak; /* * Cycle over all voiced intervals. */ for (;;) { double tleft, tright, tmiddle, f0middle, tmax, tsave; if (! Pitch_getVoicedIntervalAfter (pitch, t, & tleft, & tright)) break; /* * Go to the middle of the voice stretch. */ tmiddle = (tleft + tright) / 2; if (! Melder_progress1 ((tmiddle - sound -> xmin) / (sound -> xmax - sound -> xmin), L"Sound & Pitch to PointProcess")) goto end; f0middle = Pitch_getValueAtTime (pitch, tmiddle, kPitch_unit_HERTZ, Pitch_LINEAR); /* * Our first point is near this middle. */ if (f0middle == NUMundefined) { Melder_fatal ("Sound_Pitch_to_PointProcess_cc: tleft %ls, tright %ls, f0middle %ls", Melder_double (tleft), Melder_double (tright), Melder_double (f0middle)); } tmax = Sound_findExtremum (sound, tmiddle - 0.5 / f0middle, tmiddle + 0.5 / f0middle, TRUE, TRUE); Melder_assert (NUMdefined (tmax)); if (! PointProcess_addPoint (point, tmax)) goto end; tsave = tmax; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation; if (f0 == NUMundefined) break; correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax - 1.25 / f0, tmax - 0.8 / f0, & tmax, & peak); if (correlation == -1) /*break*/ tmax -= 1.0 / f0; /* This one period will drop out. */ if (tmax < tleft) { if (correlation > 0.7 && peak > 0.023333 * globalPeak && tmax - addedRight > 0.8 / f0) if (! PointProcess_addPoint (point, tmax)) goto end; break; } if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { if (tmax - addedRight > 0.8 / f0) /* Do not fill in a short originally unvoiced interval twice. */ if (! PointProcess_addPoint (point, tmax)) goto end; } } tmax = tsave; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation; if (f0 == NUMundefined) break; correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax + 0.8 / f0, tmax + 1.25 / f0, & tmax, & peak); if (correlation == -1) /*break*/ tmax += 1.0 / f0; if (tmax > tright) { if (correlation > 0.7 && peak > 0.023333 * globalPeak) { if (! PointProcess_addPoint (point, tmax)) goto end; addedRight = tmax; } break; } if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { if (! PointProcess_addPoint (point, tmax)) goto end; addedRight = tmax; } } t = tright; } end: Melder_progress1 (1.0, NULL); iferror forget (point); return point; }