double RealTier_getStandardDeviation_curve (RealTier me, double tmin, double tmax) { long n = my points.size, imin, imax; double mean, integral = 0.0; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow if (n == 0) return NUMundefined; if (n == 1) return 0.0; imin = AnyTier_timeToLowIndex (me->asAnyTier(), tmin); if (imin == n) return 0.0; imax = AnyTier_timeToHighIndex (me->asAnyTier(), tmax); if (imax == 1) return 0.0; Melder_assert (imin < n); Melder_assert (imax > 1); /* * Add the areas between the points. * This works even if imin is 0 (offleft) and/or imax is n + 1 (offright). */ mean = RealTier_getMean_curve (me, tmin, tmax); for (long i = imin; i < imax; i ++) { double tleft, fleft, tright, fright, sum, diff; if (i == imin) { tleft = tmin; fleft = RealTier_getValueAtTime (me, tmin); } else { tleft = my points.at [i] -> number; fleft = my points.at [i] -> value - mean; } if (i + 1 == imax) { tright = tmax; fright = RealTier_getValueAtTime (me, tmax); } else { tright = my points.at [i + 1] -> number; fright = my points.at [i + 1] -> value - mean; } /* * The area is integral dt f^2 * = integral dt [f1 + (f2-f1)/(t2-t1) (t-t1)]^2 * = int dt f1^2 + int dt 2 f1 (f2-f1)/(t2-t1) (t-t1) + int dt [(f2-f1)/(t2-t1)]^2 (t-t1)^2 * = f1^2 (t2-t1) + f1 (f2-f1)/(t2-t1) (t2-t1)^2 + 1/3 [(f2-f1)/(t2-t1)]^2 (t2-t1)^3 * = (t2-t1) [f1 f2 + 1/3 (f2-f1)^2] * = (t2-t1) (f1^2 + f2^2 + 1/3 f1 f2) * = (t2-t1) [1/4 (f1+f2)^2 + 1/12 (f1-f2)^2] * In the last expression, we have a sum of squares, which is computationally best. */ sum = fleft + fright; diff = fleft - fright; integral += (sum * sum + (1.0/3.0) * diff * diff) * (tright - tleft); } return sqrt (0.25 * integral / (tmax - tmin)); }
autoPitchTier PitchTier_AnyTier_to_PitchTier (PitchTier pitch, AnyTier tier) { try { SortedSetOfDouble points = tier -> points; if (pitch -> points -> size == 0) Melder_throw (U"No pitch points."); /* * 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 = RealTier_getValueAtTime (pitch, time); RealTier_addPoint (thee.peek(), time, frequency); } return thee; } catch (MelderError) { Melder_throw (pitch, U" & ", tier, U": not converted to PitchTier."); } }
Pitch PitchTier_to_Pitch (PitchTier me, double dt, double pitchFloor, double pitchCeiling) { try { if (my points -> size < 1) { Melder_throw ("The PitchTier is empty."); } if (dt <= 0) { Melder_throw ("The time step should be a positive number."); } if (pitchFloor >= pitchCeiling) { Melder_throw ("The pitch ceiling must be a higher number than the pitch floor."); } double tmin = my xmin, tmax = my xmax, t1 = my xmin + dt / 2; long nt = (tmax - tmin - t1) / dt; if (t1 + nt * dt < tmax) { nt++; } if (nt < 1) { Melder_throw ("Duration is too short."); } autoPitch thee = Pitch_create (tmin, tmax, nt, dt, t1, pitchCeiling, 1); for (long i = 1; i <= nt; i++) { Pitch_Frame frame = (Pitch_Frame) & thy frame [i]; Pitch_Candidate candidate = (Pitch_Candidate) & frame -> candidate [1]; double t = t1 + (i - 1) * dt; double f = RealTier_getValueAtTime (me, t); if (f < pitchFloor || f > pitchCeiling) { f = 0; } candidate -> frequency = f; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no Pitch created."); } }
Pitch PitchTier_to_Pitch (PitchTier me, double dt, double pitchFloor, double pitchCeiling) { Pitch thee = NULL; long i, nt; double tmin = my xmin, tmax = my xmax, t1 = my xmin + dt / 2; if (my points -> size < 1) return Melder_errorp1 (L"The PitchTier is empty."); if (dt <= 0) return Melder_errorp1 (L"The time step should be a positive number."); if (pitchFloor >= pitchCeiling) return Melder_errorp1 (L"The pitch ceiling must be a higher number than the pitch floor."); nt = (tmax - tmin - t1) / dt; if (t1 + nt * dt < tmax) nt++; if (nt < 1) return Melder_errorp1 (L"Duration is too short."); thee = Pitch_create (tmin, tmax, nt, dt, t1, pitchCeiling, 1); if (thee == NULL) return NULL; for (i = 1; i <= nt; i++) { Pitch_Frame frame = & thy frame [i]; Pitch_Candidate candidate = & frame -> candidate [1]; double t = t1 + (i - 1) * dt; double f = RealTier_getValueAtTime (me, t); if (f < pitchFloor || f > pitchCeiling) f = 0; candidate -> frequency = f; } return thee; }
void PitchTier_Pitch_draw (PitchTier me, Pitch uv, Graphics g, double tmin, double tmax, double fmin, double fmax, int nonPeriodicLineType, int garnish, const char32 *method) { long n = my points.size, imin, imax, i; if (nonPeriodicLineType == 0) { PitchTier_draw (me, g, tmin, tmax, fmin, fmax, garnish, method); return; } if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } Graphics_setWindow (g, tmin, tmax, fmin, fmax); Graphics_setInner (g); imin = AnyTier_timeToHighIndex (me->asAnyTier(), tmin); imax = AnyTier_timeToLowIndex (me->asAnyTier(), tmax); if (n == 0) { } else if (imax < imin) { double fleft = RealTier_getValueAtTime (me, tmin); double fright = RealTier_getValueAtTime (me, tmax); Pitch_line (uv, g, tmin, fleft, tmax, fright, nonPeriodicLineType); } else for (i = imin; i <= imax; i ++) { RealPoint point = my points.at [i]; double t = point -> number, f = point -> value; Graphics_speckle (g, t, f); if (i == 1) Pitch_line (uv, g, tmin, f, t, f, nonPeriodicLineType); else if (i == imin) Pitch_line (uv, g, t, f, tmin, RealTier_getValueAtTime (me, tmin), nonPeriodicLineType); if (i == n) Pitch_line (uv, g, t, f, tmax, f, nonPeriodicLineType); else if (i == imax) Pitch_line (uv, g, t, f, tmax, RealTier_getValueAtTime (me, tmax), nonPeriodicLineType); else { RealPoint pointRight = my points.at [i + 1]; Pitch_line (uv, g, t, f, pointRight -> number, pointRight -> value, nonPeriodicLineType); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Frequency (Hz)"); } }
void RealTier_draw (RealTier me, Graphics g, double tmin, double tmax, double fmin, double fmax, int garnish, const char32 *method, const char32 *quantity) { bool drawLines = str32str (method, U"lines") || str32str (method, U"Lines"); bool drawSpeckles = str32str (method, U"speckles") || str32str (method, U"Speckles"); long n = my points.size, imin, imax, i; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } Graphics_setWindow (g, tmin, tmax, fmin, fmax); Graphics_setInner (g); imin = AnyTier_timeToHighIndex (me->asAnyTier(), tmin); imax = AnyTier_timeToLowIndex (me->asAnyTier(), tmax); if (n == 0) { } else if (imax < imin) { double fleft = RealTier_getValueAtTime (me, tmin); double fright = RealTier_getValueAtTime (me, tmax); if (drawLines) Graphics_line (g, tmin, fleft, tmax, fright); } else for (i = imin; i <= imax; i ++) { RealPoint point = my points.at [i]; double t = point -> number, f = point -> value; if (drawSpeckles) Graphics_speckle (g, t, f); if (drawLines) { if (i == 1) Graphics_line (g, tmin, f, t, f); else if (i == imin) Graphics_line (g, t, f, tmin, RealTier_getValueAtTime (me, tmin)); if (i == n) Graphics_line (g, t, f, tmax, f); else if (i == imax) Graphics_line (g, t, f, tmax, RealTier_getValueAtTime (me, tmax)); else { RealPoint pointRight = my points.at [i + 1]; Graphics_line (g, t, f, pointRight -> number, pointRight -> value); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, my v_getUnitText (0, 0, 0)); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (quantity) Graphics_textLeft (g, true, quantity); } }
void Sound_IntensityTier_multiply_inline (Sound me, IntensityTier intensity) { if (intensity -> points -> size == 0) return; for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; double factor = pow (10, RealTier_getValueAtTime (intensity, t) / 20); for (long channel = 1; channel <= my ny; channel ++) { my z [channel] [isamp] *= factor; } } }
void Sound_AmplitudeTier_multiply_inline (Sound me, AmplitudeTier amplitude) { if (amplitude -> numberOfPoints() == 0) return; for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; double factor = RealTier_getValueAtTime (amplitude, t); for (long channel = 1; channel <= my ny; channel ++) { my z [channel] [isamp] *= factor; } } }
Formant FormantGrid_to_Formant (FormantGrid me, double dt, double intensity) { Melder_assert (dt > 0.0); Melder_assert (intensity >= 0.0); long nt = (long) floor ((my xmax - my xmin) / dt) + 1; double t1 = 0.5 * (my xmin + my xmax - (nt - 1) * dt); Formant thee = Formant_create (my xmin, my xmax, nt, dt, t1, my formants -> size); for (long iframe = 1; iframe <= nt; iframe ++) { Formant_Frame frame = & thy frame [iframe]; frame -> intensity = intensity; frame -> nFormants = my formants -> size; frame -> formant = NUMstructvector (Formant_Formant, 1, my formants -> size); double t = t1 + (iframe - 1) * dt; for (long iformant = 1; iformant <= my formants -> size; iformant ++) { Formant_Formant formant = & frame -> formant [iformant]; formant -> frequency = RealTier_getValueAtTime (my formants -> item [iformant], t); formant -> bandwidth = RealTier_getValueAtTime (my bandwidths -> item [iformant], t); } } end: iferror forget (thee); return thee; }
PitchTier PitchTier_PointProcess_to_PitchTier (PitchTier me, PointProcess pp) { try { if (my points -> size == 0) Melder_throw ("No pitch points."); autoPitchTier thee = PitchTier_create (pp -> xmin, pp -> xmax); for (long i = 1; i <= pp -> nt; i ++) { double time = pp -> t [i]; double value = RealTier_getValueAtTime (me, time); RealTier_addPoint (thee.peek(), time, value); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, " & ", pp, ": not converted to PitchTier."); } }
autoIntensityTier IntensityTier_PointProcess_to_IntensityTier (IntensityTier me, PointProcess pp) { try { if (my points -> size == 0) Melder_throw (U"No intensity points."); autoIntensityTier thee = IntensityTier_create (pp -> xmin, pp -> xmax); for (long i = 1; i <= pp -> nt; i ++) { double time = pp -> t [i]; double value = RealTier_getValueAtTime (me, time); RealTier_addPoint (thee.peek(), time, value); } return thee; } catch (MelderError) { Melder_throw (me, U" & ", pp, U": not converted to IntensityTier."); } }
Intensity IntensityTier_to_Intensity (IntensityTier me, double dt) { try { long nt = (long) floor ((my xmax - my xmin) / dt); double t1 = 0.5 * dt; autoIntensity thee = Intensity_create (my xmin, my xmax, nt, dt, t1); for (long i = 1; i <= nt; i++) { double time = t1 + (i - 1) * dt; thy z[1][i] = RealTier_getValueAtTime (me, time); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U" no Intensity created."); } }
Formant FormantGrid_to_Formant (FormantGrid me, double dt, double intensity) { try { Melder_assert (dt > 0.0); Melder_assert (intensity >= 0.0); long nt = (long) floor ((my xmax - my xmin) / dt) + 1; double t1 = 0.5 * (my xmin + my xmax - (nt - 1) * dt); autoFormant thee = Formant_create (my xmin, my xmax, nt, dt, t1, my formants -> size); for (long iframe = 1; iframe <= nt; iframe ++) { Formant_Frame frame = & thy d_frames [iframe]; frame -> intensity = intensity; frame -> nFormants = my formants -> size; frame -> formant = NUMvector <structFormant_Formant> (1, my formants -> size); double t = t1 + (iframe - 1) * dt; for (long iformant = 1; iformant <= my formants -> size; iformant ++) { Formant_Formant formant = & frame -> formant [iformant]; formant -> frequency = RealTier_getValueAtTime ((RealTier) my formants -> item [iformant], t); formant -> bandwidth = RealTier_getValueAtTime ((RealTier) my bandwidths -> item [iformant], t); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not converted to Formant."); } }
void Sound_FormantGrid_filter_inline (Sound me, FormantGrid formantGrid) { double dt = my dx; if (formantGrid -> formants -> size && formantGrid -> bandwidths -> size) for (long iformant = 1; iformant <= formantGrid -> formants -> size; iformant ++) { RealTier formantTier = (RealTier) formantGrid -> formants -> item [iformant]; RealTier bandwidthTier = (RealTier) formantGrid -> bandwidths -> item [iformant]; for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; /* * Compute LP coefficients. */ double formant, bandwidth; formant = RealTier_getValueAtTime (formantTier, t); bandwidth = RealTier_getValueAtTime (bandwidthTier, t); if (NUMdefined (formant) && NUMdefined (bandwidth)) { double cosomdt = cos (2 * NUMpi * formant * dt); double r = exp (- NUMpi * bandwidth * dt); /* Formants at 0 Hz or the Nyquist are single poles, others are double poles. */ if (fabs (cosomdt) > 0.999999) { /* Allow for round-off errors. */ /* single pole: D(z) = 1 - r z^-1 */ for (long channel = 1; channel <= my ny; channel ++) { if (isamp > 1) my z [channel] [isamp] += r * my z [channel] [isamp - 1]; } } else { /* double pole: D(z) = 1 + p z^-1 + q z^-2 */ double p = - 2 * r * cosomdt; double q = r * r; for (long channel = 1; channel <= my ny; channel ++) { if (isamp > 1) my z [channel] [isamp] -= p * my z [channel] [isamp - 1]; if (isamp > 2) my z [channel] [isamp] -= q * my z [channel] [isamp - 2]; } } } } } }
double RealTier_getArea (RealTier me, double tmin, double tmax) { long n = my points.size, imin, imax; //RealPoint *points = & my points [0]; if (n == 0) return NUMundefined; if (n == 1) return (tmax - tmin) * my points.at [1] -> value; imin = AnyTier_timeToLowIndex (me->asAnyTier(), tmin); if (imin == n) return (tmax - tmin) * my points.at [n] -> value; imax = AnyTier_timeToHighIndex (me->asAnyTier(), tmax); if (imax == 1) return (tmax - tmin) * my points.at [1] -> value; Melder_assert (imin < n); Melder_assert (imax > 1); /* * Sum the areas between the points. * This works even if imin is 0 (offleft) and/or imax is n + 1 (offright). */ double area = 0.0; for (long i = imin; i < imax; i ++) { double tleft, fleft, tright, fright; if (i == imin) { tleft = tmin; fleft = RealTier_getValueAtTime (me, tmin); } else { tleft = my points.at [i] -> number; fleft = my points.at [i] -> value; } if (i + 1 == imax) { tright = tmax; fright = RealTier_getValueAtTime (me, tmax); } else { tright = my points.at [i + 1] -> number; fright = my points.at [i + 1] -> value; } area += 0.5 * (fleft + fright) * (tright - tleft); } return area; }
autoPitch Pitch_PitchTier_to_Pitch (Pitch me, PitchTier tier) { try { if (tier -> points.size == 0) Melder_throw (U"No pitch points."); autoPitch thee = Data_copy (me); for (long iframe = 1; iframe <= my nx; iframe ++) { Pitch_Frame frame = & thy frame [iframe]; Pitch_Candidate cand = & frame -> candidate [1]; if (cand -> frequency > 0.0 && cand -> frequency <= my ceiling) cand -> frequency = RealTier_getValueAtTime (tier, Sampled_indexToX (me, iframe)); cand -> strength = 0.9; frame -> nCandidates = 1; } return thee; } catch (MelderError) { Melder_throw (me, U" & ", tier, U": not converted to Pitch."); } }
autoVocalTract VocalTractTier_to_VocalTract (VocalTractTier me, double time) { try { VocalTractPoint vtp = (VocalTractPoint) my d_vocalTracts -> item[1]; long numberOfSections = vtp -> d_vocalTract -> nx; autoVocalTract thee = VocalTract_create (numberOfSections, vtp -> d_vocalTract -> dx); for (long isection = 1; isection <= numberOfSections; isection++) { autoRealTier section = RealTier_create (my xmin, my xmax); for (long i = 1; i <= my d_vocalTracts -> size; i++) { VocalTractPoint vtpi = (VocalTractPoint) my d_vocalTracts -> item[i]; double areai = vtpi -> d_vocalTract -> z[1][isection]; RealTier_addPoint (section.peek(), vtpi -> number, areai); } thy z[1][isection] = RealTier_getValueAtTime (section.peek(), time); } return thee; } catch (MelderError) { Melder_throw (me, U": no VocalTract created."); } }
autoSound PitchTier_to_Sound_sine (PitchTier me, double tmin, double tmax, double samplingFrequency) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; long numberOfSamples = 1 + (long) floor ((my xmax - my xmin) * samplingFrequency); // >= 1 double samplingPeriod = 1.0 / samplingFrequency; double tmid = (tmin + tmax) / 2.0; double t1 = tmid - 0.5 * (numberOfSamples - 1) * samplingPeriod; autoSound thee = Sound_create (1, tmin, tmax, numberOfSamples, samplingPeriod, t1); double phase = 0.0; for (long isamp = 2; isamp <= numberOfSamples; isamp ++) { double tleft = t1 + (isamp - 1.5) * samplingPeriod; double fleft = RealTier_getValueAtTime (me, tleft); phase += fleft * thy dx; thy z [1] [isamp] = 0.5 * sin (2.0 * NUMpi * phase); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (sine)."); } }
autoLPC VocalTractTier_to_LPC (VocalTractTier me, double timeStep) { try { if (my d_vocalTracts -> size == 0) { Melder_throw (U"Empty VocalTractTier"); } long numberOfFrames = (long) floor ((my xmax - my xmin) / timeStep); VocalTractPoint vtp = (VocalTractPoint) my d_vocalTracts -> item[1]; long numberOfSections = vtp -> d_vocalTract -> nx; double samplingPeriod = 1.0 / (1000.0 * numberOfSections); autoNUMmatrix<double> area (1, numberOfFrames, 1, numberOfSections + 1); autoNUMvector<double> areavec (1, numberOfSections + 1); autoLPC thee = LPC_create (my xmin, my xmax, numberOfFrames, timeStep, timeStep / 2, numberOfSections, samplingPeriod); // interpolate each section for (long isection = 1; isection <= numberOfSections; isection++) { autoRealTier sectioni = RealTier_create (my xmin, my xmax); for (long i = 1; i <= my d_vocalTracts -> size; i++) { VocalTractPoint vtpi = (VocalTractPoint) my d_vocalTracts -> item[i]; double areai = vtpi -> d_vocalTract -> z[1][isection]; RealTier_addPoint (sectioni.peek(), vtpi -> number, areai); } for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double time = thy x1 + (iframe - 1) * thy dx; area[iframe][isection] = RealTier_getValueAtTime (sectioni.peek(), time); area[iframe][numberOfSections + 1] = 0.0001; // normalisation is area[n+1] = 0.0001 } } for (long iframe = 1; iframe <= numberOfFrames; iframe++) { LPC_Frame frame = &thy d_frames[iframe]; LPC_Frame_init (frame, numberOfSections); for (long i = 1; i <= numberOfSections + 1; i++) { areavec[i] = area[iframe][numberOfSections + 1 - i]; } NUMlpc_area_to_lpc (areavec.peek(), numberOfSections + 1, frame -> a); frame -> gain = 1e-6; // something } return thee; } catch (MelderError) { Melder_throw (U": not converted to LPC."); } }
static double getFunction1 (I, long irow, double x) { iam (FormantGrid); RealTier tier = (structRealTier *)my formants -> item [irow]; return RealTier_getValueAtTime (tier, x); }
void structFormantGridEditor :: v_draw () { FormantGrid grid = (FormantGrid) our data; Ordered tiers = our editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier selectedTier = (RealTier) tiers -> item [selectedFormant]; double ymin = our editingBandwidths ? our p_bandwidthFloor : our p_formantFloor; double ymax = our editingBandwidths ? our p_bandwidthCeiling : our p_formantCeiling; Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, ymin, ymax); Graphics_setColour (our d_graphics, Graphics_RED); Graphics_line (our d_graphics, our d_startWindow, our ycursor, our d_endWindow, our ycursor); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, our ycursor, Melder_float (Melder_half (our ycursor))); Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_TOP); Graphics_text (our d_graphics, our d_endWindow, ymax, Melder_float (Melder_half (ymax)), U" Hz"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, ymin, Melder_float (Melder_half (ymin)), U" Hz"); Graphics_setLineWidth (our d_graphics, 1); Graphics_setColour (our d_graphics, Graphics_GREY); for (long iformant = 1; iformant <= grid -> formants -> size; iformant ++) if (iformant != our selectedFormant) { RealTier tier = (RealTier) tiers -> item [iformant]; long imin = AnyTier_timeToHighIndex (tier, our d_startWindow); long imax = AnyTier_timeToLowIndex (tier, our d_endWindow); long n = tier -> points -> size; if (n == 0) { } else if (imax < imin) { double yleft = RealTier_getValueAtTime (tier, our d_startWindow); double yright = RealTier_getValueAtTime (tier, our d_endWindow); Graphics_line (our d_graphics, our d_startWindow, yleft, our d_endWindow, yright); } else for (long i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) tier -> points -> item [i]; double t = point -> number, y = point -> value; Graphics_fillCircle_mm (our d_graphics, t, y, 2); if (i == 1) Graphics_line (our d_graphics, our d_startWindow, y, t, y); else if (i == imin) Graphics_line (our d_graphics, t, y, our d_startWindow, RealTier_getValueAtTime (tier, our d_startWindow)); if (i == n) Graphics_line (our d_graphics, t, y, our d_endWindow, y); else if (i == imax) Graphics_line (our d_graphics, t, y, our d_endWindow, RealTier_getValueAtTime (tier, our d_endWindow)); else { RealPoint pointRight = (RealPoint) tier -> points -> item [i + 1]; Graphics_line (our d_graphics, t, y, pointRight -> number, pointRight -> value); } } } Graphics_setColour (our d_graphics, Graphics_BLUE); long ifirstSelected = AnyTier_timeToHighIndex (selectedTier, our d_startSelection); long ilastSelected = AnyTier_timeToLowIndex (selectedTier, our d_endSelection); long n = selectedTier -> points -> size; long imin = AnyTier_timeToHighIndex (selectedTier, our d_startWindow); long imax = AnyTier_timeToLowIndex (selectedTier, our d_endWindow); Graphics_setLineWidth (our d_graphics, 2); if (n == 0) { Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (our d_graphics, 0.5 * (our d_startWindow + our d_endWindow), 0.5 * (ymin + ymax), U"(no points in selected formant tier)"); } else if (imax < imin) { double yleft = RealTier_getValueAtTime (selectedTier, our d_startWindow); double yright = RealTier_getValueAtTime (selectedTier, our d_endWindow); Graphics_line (our d_graphics, our d_startWindow, yleft, our d_endWindow, yright); } else for (long i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) selectedTier -> points -> item [i]; double t = point -> number, y = point -> value; if (i >= ifirstSelected && i <= ilastSelected) Graphics_setColour (our d_graphics, Graphics_RED); Graphics_fillCircle_mm (our d_graphics, t, y, 3); Graphics_setColour (our d_graphics, Graphics_BLUE); if (i == 1) Graphics_line (our d_graphics, our d_startWindow, y, t, y); else if (i == imin) Graphics_line (our d_graphics, t, y, our d_startWindow, RealTier_getValueAtTime (selectedTier, our d_startWindow)); if (i == n) Graphics_line (our d_graphics, t, y, our d_endWindow, y); else if (i == imax) Graphics_line (our d_graphics, t, y, our d_endWindow, RealTier_getValueAtTime (selectedTier, our d_endWindow)); else { RealPoint pointRight = (RealPoint) selectedTier -> points -> item [i + 1]; Graphics_line (our d_graphics, t, y, pointRight -> number, pointRight -> value); } } Graphics_setLineWidth (our d_graphics, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); }
double structFormantGrid :: v_getFunction1 (long irow, double x) { RealTier tier = (RealTier) formants -> item [irow]; return RealTier_getValueAtTime (tier, x); }
double FormantGrid_getBandwidthAtTime (FormantGrid me, long iformant, double t) { if (iformant < 1 || iformant > my bandwidths -> size) return NUMundefined; return RealTier_getValueAtTime ((RealTier) my bandwidths -> item [iformant], t); }
static double getFunction1 (I, long irow, double x) { iam (RealTier); (void) irow; return RealTier_getValueAtTime (me, x); }
double structRealTier :: v_getFunction1 (long irow, double x) { (void) irow; return RealTier_getValueAtTime (this, x); }
autoSound Sound_Point_Pitch_Duration_to_Sound (Sound me, PointProcess pulses, PitchTier pitch, DurationTier duration, double maxT) { try { long ipointleft, ipointright; double deltat = 0, handledTime = my xmin; double startOfSourceNoise, endOfSourceNoise, startOfTargetNoise, endOfTargetNoise; double durationOfSourceNoise, durationOfTargetNoise; double startOfSourceVoice, endOfSourceVoice, startOfTargetVoice, endOfTargetVoice; double durationOfSourceVoice, durationOfTargetVoice; double startingPeriod, finishingPeriod, ttarget, voicelessPeriod; if (duration -> points.size == 0) Melder_throw (U"No duration points."); /* * Create a Sound long enough to hold the longest possible duration-manipulated sound. */ autoSound thee = Sound_create (1, my xmin, my xmin + 3 * (my xmax - my xmin), 3 * my nx, my dx, my x1); /* * Below, I'll abbreviate the voiced interval as "voice" and the voiceless interval as "noise". */ if (pitch && pitch -> points.size) for (ipointleft = 1; ipointleft <= pulses -> nt; ipointleft = ipointright + 1) { /* * Find the beginning of the voice. */ startOfSourceVoice = pulses -> t [ipointleft]; // the first pulse of the voice startingPeriod = 1.0 / RealTier_getValueAtTime (pitch, startOfSourceVoice); startOfSourceVoice -= 0.5 * startingPeriod; // the first pulse is in the middle of a period /* * Measure one noise. */ startOfSourceNoise = handledTime; endOfSourceNoise = startOfSourceVoice; durationOfSourceNoise = endOfSourceNoise - startOfSourceNoise; startOfTargetNoise = startOfSourceNoise + deltat; endOfTargetNoise = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, endOfSourceNoise); durationOfTargetNoise = endOfTargetNoise - startOfTargetNoise; /* * Copy the noise. */ voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget = startOfTargetNoise + 0.5 * voicelessPeriod; while (ttarget < endOfTargetNoise) { double tsource; double tleft = startOfSourceNoise, tright = endOfSourceNoise; int i; for (i = 1; i <= 15; i ++) { double tsourcemid = 0.5 * (tleft + tright); double ttargetmid = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, tsourcemid); if (ttargetmid < ttarget) tleft = tsourcemid; else tright = tsourcemid; } tsource = 0.5 * (tleft + tright); copyBell (me, tsource, voicelessPeriod, voicelessPeriod, thee.get(), ttarget); voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget += voicelessPeriod; } deltat += durationOfTargetNoise - durationOfSourceNoise; /* * Find the end of the voice. */ for (ipointright = ipointleft + 1; ipointright <= pulses -> nt; ipointright ++) if (pulses -> t [ipointright] - pulses -> t [ipointright - 1] > maxT) break; ipointright --; endOfSourceVoice = pulses -> t [ipointright]; // the last pulse of the voice finishingPeriod = 1.0 / RealTier_getValueAtTime (pitch, endOfSourceVoice); endOfSourceVoice += 0.5 * finishingPeriod; // the last pulse is in the middle of a period /* * Measure one voice. */ durationOfSourceVoice = endOfSourceVoice - startOfSourceVoice; /* * This will be copied to an interval with a different location and duration. */ startOfTargetVoice = startOfSourceVoice + deltat; endOfTargetVoice = startOfTargetVoice + RealTier_getArea (duration, startOfSourceVoice, endOfSourceVoice); durationOfTargetVoice = endOfTargetVoice - startOfTargetVoice; /* * Copy the voiced part. */ ttarget = startOfTargetVoice + 0.5 * startingPeriod; while (ttarget < endOfTargetVoice) { double tsource, period; long isourcepulse; double tleft = startOfSourceVoice, tright = endOfSourceVoice; int i; for (i = 1; i <= 15; i ++) { double tsourcemid = 0.5 * (tleft + tright); double ttargetmid = startOfTargetVoice + RealTier_getArea (duration, startOfSourceVoice, tsourcemid); if (ttargetmid < ttarget) tleft = tsourcemid; else tright = tsourcemid; } tsource = 0.5 * (tleft + tright); period = 1.0 / RealTier_getValueAtTime (pitch, tsource); isourcepulse = PointProcess_getNearestIndex (pulses, tsource); copyBell2 (me, pulses, isourcepulse, period, period, thee.get(), ttarget, maxT); ttarget += period; } deltat += durationOfTargetVoice - durationOfSourceVoice; handledTime = endOfSourceVoice; } /* * Copy the remaining unvoiced part, if we are at the end. */ startOfSourceNoise = handledTime; endOfSourceNoise = my xmax; durationOfSourceNoise = endOfSourceNoise - startOfSourceNoise; startOfTargetNoise = startOfSourceNoise + deltat; endOfTargetNoise = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, endOfSourceNoise); durationOfTargetNoise = endOfTargetNoise - startOfTargetNoise; voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget = startOfTargetNoise + 0.5 * voicelessPeriod; while (ttarget < endOfTargetNoise) { double tsource; double tleft = startOfSourceNoise, tright = endOfSourceNoise; for (int i = 1; i <= 15; i ++) { double tsourcemid = 0.5 * (tleft + tright); double ttargetmid = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, tsourcemid); if (ttargetmid < ttarget) tleft = tsourcemid; else tright = tsourcemid; } tsource = 0.5 * (tleft + tright); copyBell (me, tsource, voicelessPeriod, voicelessPeriod, thee.get(), ttarget); voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget += voicelessPeriod; } /* * Find the number of trailing zeroes and hack the sound's time domain. */ thy xmax = thy xmin + RealTier_getArea (duration, my xmin, my xmax); if (fabs (thy xmax - my xmax) < 1e-12) thy xmax = my xmax; // common situation thy nx = Sampled_xToLowIndex (thee.get(), thy xmax); if (thy nx > 3 * my nx) thy nx = 3 * my nx; return thee; } catch (MelderError) { Melder_throw (me, U": not manipulated."); } }
double FormantGrid_getFormantAtTime (FormantGrid me, long iformant, double t) { if (iformant < 1 || iformant > my formants -> size) return NUMundefined; return RealTier_getValueAtTime (my formants -> item [iformant], t); }