Example #1
0
static void menu_cb_addPointAtCursor (RealTierEditor me, EDITOR_ARGS_DIRECT) {
	if (NUMdefined (my v_minimumLegalValue ()) && my ycursor < my v_minimumLegalValue ())
		Melder_throw (U"Cannot add a point below ", my v_minimumLegalValue (), my v_rightTickUnits (), U".");
	if (NUMdefined (my v_maximumLegalValue ()) && my ycursor > my v_maximumLegalValue ())
		Melder_throw (U"Cannot add a point above ", my v_maximumLegalValue (), my v_rightTickUnits (), U".");
	Editor_save (me, U"Add point");
	RealTier_addPoint ((RealTier) my data, 0.5 * (my d_startSelection + my d_endSelection), my ycursor);
	RealTierEditor_updateScaling (me);
	FunctionEditor_redraw (me);
	Editor_broadcastDataChanged (me);
}
Example #2
0
static double Sound_findExtremum (Sound me, double tmin, double tmax, int includeMaxima, int includeMinima) {
	long imin = Sampled_xToLowIndex (me, tmin), imax = Sampled_xToHighIndex (me, tmax);
	double iextremum;
	Melder_assert (NUMdefined (tmin));
	Melder_assert (NUMdefined (tmax));
	if (imin < 1) imin = 1;
	if (imax > my nx) imax = my nx;
	iextremum = findExtremum_3 (my z [1], my ny > 1 ? my z [2] : NULL, imin - 1, imax - imin + 1, includeMaxima, includeMinima);
	if (iextremum)
		return my x1 + (imin - 1 + iextremum - 1) * my dx;
	else
		return (tmin + tmax) / 2;
}
Example #3
0
static void menu_cb_MoveCursorToZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
	double zero = Sound_getNearestZeroCrossing ((Sound) my data, 0.5 * (my d_startSelection + my d_endSelection), 1);   // STEREO BUG
	if (NUMdefined (zero)) {
		my d_startSelection = my d_endSelection = zero;
		FunctionEditor_marksChanged (me, true);
	}
}
Example #4
0
int SoundEditor::menu_cb_MoveCursorToZero (EDITOR_ARGS) {
	SoundEditor *editor = (SoundEditor *)editor_me;
	double zero = Sound_getNearestZeroCrossing ((Sound) editor->_data, 0.5 * (editor->_startSelection + editor->_endSelection), 1);   // STEREO BUG
	if (NUMdefined (zero)) {
		editor->_startSelection = editor->_endSelection = zero;
		editor->marksChanged ();
	}
	return 1;
}
Example #5
0
static bool PointProcess_isPeriod (PointProcess me, long ileft, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor) {
	/*
	 * This function answers the question: is the interval from point 'ileft' to point 'ileft+1' a period?
	 */
	long iright = ileft + 1;
	/*
	 * Period condition 1: both 'ileft' and 'iright' have to be within the point process.
	 */
	if (ileft < 1 || iright > my nt) {
		return false;
	} else {
		/*
		 * Period condition 2: the interval has to be within the boundaries, if specified.
		 */
		if (minimumPeriod == maximumPeriod) {
			return true;   // all intervals count as periods, irrespective of absolute size and relative size
		} else {
			double interval = my t [iright] - my t [ileft];
			if (interval <= 0.0 || interval < minimumPeriod || interval > maximumPeriod) {
				return false;
			} else if (! NUMdefined (maximumPeriodFactor) || maximumPeriodFactor < 1.0) {
				return true;
			} else {
				/*
				 * Period condition 3: the interval cannot be too different from both of its neigbours, if any.
				 */
				double previousInterval = ileft <= 1 ? NUMundefined : my t [ileft] - my t [ileft - 1];
				double nextInterval = iright >= my nt ? NUMundefined : my t [iright + 1] - my t [iright];
				double previousIntervalFactor = NUMdefined (previousInterval) && previousInterval > 0.0 ? interval / previousInterval : NUMundefined;
				double nextIntervalFactor = NUMdefined (nextInterval) && nextInterval > 0.0 ? interval / nextInterval : NUMundefined;
				if (! NUMdefined (previousIntervalFactor) && ! NUMdefined (nextIntervalFactor)) {
					return true;   // no neighbours: this is a period
				}
				if (NUMdefined (previousIntervalFactor) && previousIntervalFactor > 0.0 && previousIntervalFactor < 1.0) {
					previousIntervalFactor = 1.0 / previousIntervalFactor;
				}
				if (NUMdefined (nextIntervalFactor) && nextIntervalFactor > 0.0 && nextIntervalFactor < 1.0) {
					nextIntervalFactor = 1.0 / nextIntervalFactor;
				}
				if (NUMdefined (previousIntervalFactor) && previousIntervalFactor > maximumPeriodFactor &&
					NUMdefined (nextIntervalFactor) && nextIntervalFactor > maximumPeriodFactor)
				{
					return false;
				}
			}
		}
	}
	return true;
}
// xmin, xmax in hz versus bark/mel or lin
void BandFilterSpectrogram_drawFrequencyScale (BandFilterSpectrogram me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) {
	if (xmin < 0 || xmax < 0 || ymin < 0 || ymax < 0) {
		Melder_warning (U"Frequencies must be >= 0.");
		return;
	}

	// scale is in hertz
	if (xmin >= xmax) { // autoscaling
		xmin = 0;
		xmax = my v_frequencyToHertz (my ymax);
	}

	if (ymin >= ymax) { // autoscaling
		ymin = my ymin;
		ymax = my ymax;
	}

	long n = 2000;

	Graphics_setInner (g);
	Graphics_setWindow (g, xmin, xmax, ymin, ymax);

	double dx = (xmax - xmin) / (n - 1);
	double x1 = xmin, y1 = my v_hertzToFrequency (x1);
	for (long i = 2; i <= n;  i++) {
		double x2 = x1 + dx, y2 = my v_hertzToFrequency (x2);
		if (NUMdefined (y1) && NUMdefined (y2)) {
			double xo1, yo1, xo2, yo2;
			if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) {
				Graphics_line (g, xo1, yo1, xo2, yo2);
			}
		}
		x1 = x2; y1 = y2;
	}
	Graphics_unsetInner (g);

	if (garnish) {
		Graphics_drawInnerBox (g);
		Graphics_marksLeft (g, 2, 1, 1, 0);
		Graphics_textLeft (g, 1, Melder_cat (U"Frequency (", my v_getFrequencyUnit (), U")"));
		Graphics_marksBottom (g, 2, 1, 1, 0);
		Graphics_textBottom (g, 1, U"Frequency (Hz)");
	}
}
Example #7
0
static void menu_cb_MoveEtoZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
	double zero = Sound_getNearestZeroCrossing ((Sound) my data, my d_endSelection, 1);   // STEREO BUG
	if (NUMdefined (zero)) {
		my d_endSelection = zero;
		if (my d_startSelection > my d_endSelection) {
			double dummy = my d_startSelection;
			my d_startSelection = my d_endSelection;
			my d_endSelection = dummy;
		}
		FunctionEditor_marksChanged (me, true);
	}
}
Example #8
0
int SoundEditor::menu_cb_MoveEtoZero (EDITOR_ARGS) {
	SoundEditor *editor = (SoundEditor *)editor_me;
	double zero = Sound_getNearestZeroCrossing ((Sound) editor->_data, editor->_endSelection, 1);   // STEREO BUG
	if (NUMdefined (zero)) {
		editor->_endSelection = zero;
		if (editor->_startSelection > editor->_endSelection) {
			double dummy = editor->_startSelection;
			editor->_startSelection = editor->_endSelection;
			editor->_endSelection = dummy;
		}
		editor->marksChanged ();
	}
	return 1;
}
autoAmplitudeTier PointProcess_Sound_to_AmplitudeTier_point (PointProcess me, Sound thee) {
	try {
		long imin, imax, numberOfPeaks = PointProcess_getWindowPoints (me, my xmin, my xmax, & imin, & imax);
		if (numberOfPeaks < 3) return nullptr;
		autoAmplitudeTier him = AmplitudeTier_create (my xmin, my xmax);
		for (long i = imin; i <= imax; i ++) {
			double value = Vector_getValueAtX (thee, my t [i], Vector_CHANNEL_AVERAGE, Vector_VALUE_INTERPOLATION_SINC700);
			if (NUMdefined (value)) RealTier_addPoint (him.peek(), my t [i], value);
		}
		return him;
	} catch (MelderError) {
		Melder_throw (me, U" & ", thee, U": not converted to AmplitudeTier.");
	}
}
Example #10
0
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];
					}
				}
			}
		}
	}
}
Example #11
0
double structVector :: v_getValueAtSample (long isamp, long ilevel, int unit) {
// Preconditions:
//    1 <= isamp <= my nx
//    0 <= ilevel <= my ny
	double value;
	if (ilevel > Vector_CHANNEL_AVERAGE) {
		value = z [ilevel] [isamp];
	} else if (ny == 1) {
		value = z [1] [isamp];   // optimization
	} else if (ny == 2) {
		value = 0.5 * (z [1] [isamp] + z [2] [isamp]);   // optimization
	} else {
		double sum = 0.0;
		for (long channel = 1; channel <= ny; channel ++) {
			sum += z [channel] [isamp];
		}
		value = sum / ny;
	}
	return NUMdefined (value) ? v_convertStandardToSpecialUnit (value, ilevel, unit) : NUMundefined;
}
Example #12
0
double Sampled_getQuantile (I, double xmin, double xmax, double quantile, long ilevel, int unit) {
	iam (Sampled);
	long i, imin, imax, numberOfDefinedSamples = 0;
	double *values = NUMdvector (1, my nx), result = NUMundefined;
	iferror return NUMundefined;
	Function_unidirectionalAutowindow (me, & xmin, & xmax);
	if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) return NUMundefined;
	Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax);
	for (i = imin; i <= imax; i ++) {
		double value = our getValueAtSample (me, i, ilevel, unit);
		if (NUMdefined (value)) {
			values [++ numberOfDefinedSamples] = value;
		}
	}
	if (numberOfDefinedSamples >= 1) {
		NUMsort_d (numberOfDefinedSamples, values);
		result = NUMquantile (numberOfDefinedSamples, values, quantile);
	}
	NUMdvector_free (values, 1);
	return result;
}
Example #13
0
void Pitch_Intensity_draw (Pitch pitch, Intensity intensity, Graphics g,
	double f1, double f2, double s1, double s2, int garnish, int connect)
{
	if (f2 <= f1) Pitch_getExtrema (pitch, & f1, & f2);
	if (f1 == 0.0) return;   /* All voiceless. */
	if (f1 == f2) { f1 -= 1.0; f2 += 1.0; }
	if (s2 <= s1) Matrix_getWindowExtrema (intensity, 0, 0, 1, 1, & s1, & s2);
	if (s1 == s2) { s1 -= 1.0; s2 += 1.0; }
	Graphics_setWindow (g, f1, f2, s1, s2);
	Graphics_setInner (g);
	long previousI = 0;
	double previousX = NUMundefined, previousY = NUMundefined;
	for (long i = 1; i <= pitch -> nx; i ++) {
		double t = Sampled_indexToX (pitch, i);
		double x = pitch -> frame [i]. candidate [1]. frequency;
		double y = Sampled_getValueAtX (intensity, t, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ, TRUE);
		if (x == 0) {
			continue;   /* Voiceless. */
		}
		if (connect & 1) Graphics_speckle (g, x, y);
		if ((connect & 2) && NUMdefined (previousX)) {
			if (previousI >= 1 && previousI < i - 1) {
				Graphics_setLineType (g, Graphics_DOTTED);
			}
			Graphics_line (g, previousX, previousY, x, y);
			Graphics_setLineType (g, Graphics_DRAWN);
		}
		previousX = x;
		previousY = y;
		previousI = i;
	}
	Graphics_unsetInner (g);
	if (garnish) {
		Graphics_drawInnerBox (g);
		Graphics_textBottom (g, 1, L"Fundamental frequency (Hz)");
		Graphics_marksBottom (g, 2, 1, 1, 0);
		Graphics_textLeft (g, 1, L"Intensity (dB)");
		Graphics_marksLeft (g, 2, 1, 1, 0);
	}
}
static void Sampled_speckleInside (Sampled me, Graphics g, double xmin, double xmax, double ymin, double ymax,
	double speckle_mm, long ilevel, int unit)
{
	Function_unidirectionalAutowindow (me, & xmin, & xmax);
	long ixmin, ixmax;
	Sampled_getWindowSamples (me, xmin, xmax, & ixmin, & ixmax);
	if (Function_isUnitLogarithmic (me, ilevel, unit)) {
		ymin = Function_convertStandardToSpecialUnit (me, ymin, ilevel, unit);
		ymax = Function_convertStandardToSpecialUnit (me, ymax, ilevel, unit);
	}
	if (ymax <= ymin) return;
	Graphics_setWindow (g, xmin, xmax, ymin, ymax);
	for (long ix = ixmin; ix <= ixmax; ix ++) {
		double value = Sampled_getValueAtSample (me, ix, ilevel, unit);
		if (NUMdefined (value)) {
			double x = Sampled_indexToX (me, ix);
			if (value >= ymin && value <= ymax) {
				Graphics_fillCircle_mm (g, x, value, speckle_mm);
			}
		}
	}
}
double Sampled_getQuantile (Sampled me, double xmin, double xmax, double quantile, long ilevel, int unit) {
	try {
		autoNUMvector <double> values (1, my nx);
		Function_unidirectionalAutowindow (me, & xmin, & xmax);
		if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) return NUMundefined;
		long imin, imax, numberOfDefinedSamples = 0;
		Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax);
		for (long i = imin; i <= imax; i ++) {
			double value = my v_getValueAtSample (i, ilevel, unit);
			if (NUMdefined (value)) {
				values [++ numberOfDefinedSamples] = value;
			}
		}
		double result = NUMundefined;
		if (numberOfDefinedSamples >= 1) {
			NUMsort_d (numberOfDefinedSamples, values.peek());
			result = NUMquantile (numberOfDefinedSamples, values.peek(), quantile);
		}
		return result;
	} catch (MelderError) {
		Melder_throw (me, ": quantile not computed.");
	}
}
Example #16
0
autoAmplitudeTier PointProcess_Sound_to_AmplitudeTier_period (PointProcess me, Sound thee, double tmin, double tmax,
	double pmin, double pmax, double maximumPeriodFactor)
{
	try {
		if (tmax <= tmin) tmin = my xmin, tmax = my xmax;
		long imin, imax;
		long numberOfPeaks = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax);
		if (numberOfPeaks < 3) Melder_throw (U"Too few pulses between ", tmin, U" and ", tmax, U" seconds.");
		autoAmplitudeTier him = AmplitudeTier_create (tmin, tmax);
		for (long i = imin + 1; i < imax; i ++) {
			double p1 = my t [i] - my t [i - 1], p2 = my t [i + 1] - my t [i];
			double intervalFactor = p1 > p2 ? p1 / p2 : p2 / p1;
			if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && intervalFactor <= maximumPeriodFactor)) {
				double peak = Sound_getHannWindowedRms (thee, my t [i], 0.2 * p1, 0.2 * p2);
				if (NUMdefined (peak) && peak > 0.0)
					RealTier_addPoint (him.peek(), my t [i], peak);
			}
		}
		return him;
	} catch (MelderError) {
		Melder_throw (me, U" & ", thee, U": not converted to AmplitudeTier.");
	}
}
Example #17
0
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);
    }
}
Example #18
0
static autoIntensity Sound_to_Intensity_ (Sound me, double minimumPitch, double timeStep, int subtractMeanPressure) {
	try {
		/*
		 * Preconditions.
		 */
		if (! NUMdefined (minimumPitch)) Melder_throw (U"(Sound-to-Intensity:) Minimum pitch undefined.");
		if (! NUMdefined (timeStep)) Melder_throw (U"(Sound-to-Intensity:) Time step undefined.");
		if (timeStep < 0.0) Melder_throw (U"(Sound-to-Intensity:) Time step should be zero or positive instead of ", timeStep, U".");
		if (my dx <= 0.0) Melder_throw (U"(Sound-to-Intensity:) The Sound's time step should be positive.");
		if (minimumPitch <= 0.0) Melder_throw (U"(Sound-to-Intensity:) Minimum pitch should be positive.");
		/*
		 * Defaults.
		 */
		if (timeStep == 0.0) timeStep = 0.8 / minimumPitch;   // default: four times oversampling Hanning-wise

		double windowDuration = 6.4 / minimumPitch;
		Melder_assert (windowDuration > 0.0);
		double halfWindowDuration = 0.5 * windowDuration;
		long halfWindowSamples = (long) floor (halfWindowDuration / my dx);
		autoNUMvector <double> amplitude (- halfWindowSamples, halfWindowSamples);
		autoNUMvector <double> window (- halfWindowSamples, halfWindowSamples);

		for (long i = - halfWindowSamples; i <= halfWindowSamples; i ++) {
			double x = i * my dx / halfWindowDuration, root = 1 - x * x;
			window [i] = root <= 0.0 ? 0.0 : NUMbessel_i0_f ((2 * NUMpi * NUMpi + 0.5) * sqrt (root));
		}

		long numberOfFrames;
		double thyFirstTime;
		try {
			Sampled_shortTermAnalysis (me, windowDuration, timeStep, & numberOfFrames, & thyFirstTime);
		} catch (MelderError) {
			Melder_throw (U"The duration of the sound in an intensity analysis should be at least 6.4 divided by the minimum pitch (", minimumPitch, U" Hz), "
				U"i.e. at least ", 6.4 / minimumPitch, U" s, instead of ", my xmax - my xmin, U" s.");
		}
		autoIntensity thee = Intensity_create (my xmin, my xmax, numberOfFrames, timeStep, thyFirstTime);
		for (long iframe = 1; iframe <= numberOfFrames; iframe ++) {
			double midTime = Sampled_indexToX (thee.peek(), iframe);
			long midSample = Sampled_xToNearestIndex (me, midTime);
			long leftSample = midSample - halfWindowSamples, rightSample = midSample + halfWindowSamples;
			double sumxw = 0.0, sumw = 0.0, intensity;
			if (leftSample < 1) leftSample = 1;
			if (rightSample > my nx) rightSample = my nx;

			for (long channel = 1; channel <= my ny; channel ++) {
				for (long i = leftSample; i <= rightSample; i ++) {
					amplitude [i - midSample] = my z [channel] [i];
				}
				if (subtractMeanPressure) {
					double sum = 0.0;
					for (long i = leftSample; i <= rightSample; i ++) {
						sum += amplitude [i - midSample];
					}
					double mean = sum / (rightSample - leftSample + 1);
					for (long i = leftSample; i <= rightSample; i ++) {
						amplitude [i - midSample] -= mean;
					}
				}
				for (long i = leftSample; i <= rightSample; i ++) {
					sumxw += amplitude [i - midSample] * amplitude [i - midSample] * window [i - midSample];
					sumw += window [i - midSample];
				}
			}
			intensity = sumxw / sumw;
			intensity /= 4e-10;
			thy z [1] [iframe] = intensity < 1e-30 ? -300 : 10 * log10 (intensity);
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": intensity analysis not performed.");
	}
}
Example #19
0
double Sound_getPowerInAir (Sound me) {
	long n;
	double sum2 = getSumOfSquares (me, 0, 0, & n);
	return NUMdefined (sum2) ? sum2 / (n * my ny) / 400 : NUMundefined;
}
void Sampled_getMaximumAndX (Sampled me, double xmin, double xmax, long ilevel, int unit, int interpolate,
	double *return_maximum, double *return_xOfMaximum)
{
	long imin, imax, i;
	double maximum = -1e301, xOfMaximum = 0.0;
	if (xmin == NUMundefined || xmax == NUMundefined) {
		maximum = xOfMaximum = NUMundefined;
		goto end;
	}
	Function_unidirectionalAutowindow (me, & xmin, & xmax);
	if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) {
		maximum = xOfMaximum = NUMundefined;   // requested range and logical domain do not intersect
		goto end;
	}
	if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) {
		/*
		 * No sample centres between tmin and tmax.
		 * Try to return the greater of the values at these two points.
		 */
		double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, interpolate);
		double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, interpolate);
		if (NUMdefined (fleft) && fleft > maximum) maximum = fleft, xOfMaximum = xmin;
		if (NUMdefined (fright) && fright > maximum) maximum = fright, xOfMaximum = xmax;
	} else {
		for (i = imin; i <= imax; i ++) {
			double fmid = my v_getValueAtSample (i, ilevel, unit);
			if (fmid == NUMundefined) continue;
			if (interpolate == FALSE) {
				if (fmid > maximum) maximum = fmid, xOfMaximum = i;
			} else {
				/*
				 * Try an interpolation, possibly even taking into account a sample just outside the selection.
				 */
				double fleft = i <= 1 ? NUMundefined : my v_getValueAtSample (i - 1, ilevel, unit);
				double fright = i >= my nx ? NUMundefined : my v_getValueAtSample (i + 1, ilevel, unit);
				if (fleft == NUMundefined || fright == NUMundefined) {
					if (fmid > maximum) maximum = fmid, xOfMaximum = i;
				} else if (fmid > fleft && fmid >= fright) {
					double y [4], i_real, localMaximum;
					y [1] = fleft, y [2] = fmid, y [3] = fright;
					localMaximum = NUMimproveMaximum (y, 3, 2, NUM_PEAK_INTERPOLATE_PARABOLIC, & i_real);
					if (localMaximum > maximum)
						maximum = localMaximum, xOfMaximum = i_real + i - 2;
				}
			}
		}
		xOfMaximum = my x1 + (xOfMaximum - 1) * my dx;   /* From index plus phase to time. */
		/* Check boundary values. */
		if (interpolate) {
			double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, TRUE);
			double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, TRUE);
			if (NUMdefined (fleft) && fleft > maximum) maximum = fleft, xOfMaximum = xmin;
			if (NUMdefined (fright) && fright > maximum) maximum = fright, xOfMaximum = xmax;
		}
		if (xOfMaximum < xmin) xOfMaximum = xmin;
		if (xOfMaximum > xmax) xOfMaximum = xmax;
	}
	if (maximum == -1e301) maximum = xOfMaximum = NUMundefined;
end:
	if (return_maximum) *return_maximum = maximum;
	if (return_xOfMaximum) *return_xOfMaximum = xOfMaximum;
}
Example #21
0
void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double globalMaximum) {
	Sound sound = my d_sound.data;
	LongSound longSound = my d_longSound.data;
	Melder_assert (!! sound != !! longSound);
	int nchan = sound ? sound -> ny : longSound -> numberOfChannels;
	bool cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow;
	Graphics_setColour (my d_graphics, Graphics_BLACK);
	bool fits;
	try {
		fits = sound ? true : LongSound_haveWindow (longSound, my d_startWindow, my d_endWindow);
	} catch (MelderError) {
		bool outOfMemory = !! str32str (Melder_getError (), U"memory");
		if (Melder_debug == 9) Melder_flushError (); else Melder_clearError ();
		Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0);
		Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF);
		Graphics_text (my d_graphics, 0.5, 0.5, outOfMemory ? U"(out of memory)" : U"(cannot read sound file)");
		return;
	}
	if (! fits) {
		Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0);
		Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF);
		Graphics_text (my d_graphics, 0.5, 0.5, U"(window too large; zoom in to see the data)");
		return;
	}
	long first, last;
	if (Sampled_getWindowSamples (sound ? (Sampled) sound : (Sampled) longSound, my d_startWindow, my d_endWindow, & first, & last) <= 1) {
		Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0);
		Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF);
		Graphics_text (my d_graphics, 0.5, 0.5, U"(zoom out to see the data)");
		return;
	}
	const int numberOfVisibleChannels = nchan > 8 ? 8 : nchan;
	const int firstVisibleChannel = my d_sound.channelOffset + 1;
	int lastVisibleChannel = my d_sound.channelOffset + numberOfVisibleChannels;
	if (lastVisibleChannel > nchan) lastVisibleChannel = nchan;
	double maximumExtent = 0.0, visibleMinimum = 0.0, visibleMaximum = 0.0;
	if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) {
		if (longSound)
			LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, firstVisibleChannel, & visibleMinimum, & visibleMaximum);
		else
			Matrix_getWindowExtrema (sound, first, last, firstVisibleChannel, firstVisibleChannel, & visibleMinimum, & visibleMaximum);
		for (int ichan = firstVisibleChannel + 1; ichan <= lastVisibleChannel; ichan ++) {
			double visibleChannelMinimum, visibleChannelMaximum;
			if (longSound)
				LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & visibleChannelMinimum, & visibleChannelMaximum);
			else
				Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & visibleChannelMinimum, & visibleChannelMaximum);
			if (visibleChannelMinimum < visibleMinimum)
				visibleMinimum = visibleChannelMinimum;
			if (visibleChannelMaximum > visibleMaximum)
				visibleMaximum = visibleChannelMaximum;
		}
		maximumExtent = visibleMaximum - visibleMinimum;
	}
	for (int ichan = firstVisibleChannel; ichan <= lastVisibleChannel; ichan ++) {
		double cursorFunctionValue = longSound ? 0.0 :
			Vector_getValueAtX (sound, 0.5 * (my d_startSelection + my d_endSelection), ichan, 70);
		/*
		 * BUG: this will only work for mono or stereo, until Graphics_function16 handles quadro.
		 */
		double ymin = (double) (numberOfVisibleChannels - ichan + my d_sound.channelOffset) / numberOfVisibleChannels;
		double ymax = (double) (numberOfVisibleChannels + 1 - ichan + my d_sound.channelOffset) / numberOfVisibleChannels;
		Graphics_Viewport vp = Graphics_insetViewport (my d_graphics, 0, 1, ymin, ymax);
		bool horizontal = false;
		double minimum = sound ? globalMinimum : -1.0, maximum = sound ? globalMaximum : 1.0;
		if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) {
			if (nchan > 2) {
				if (longSound) {
					LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum);
				} else {
					Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum);
				}
				if (maximumExtent > 0.0) {
					double middle = 0.5 * (minimum + maximum);
					minimum = middle - 0.5 * maximumExtent;
					maximum = middle + 0.5 * maximumExtent;
				}
			} else {
				minimum = visibleMinimum;
				maximum = visibleMaximum;
			}
		} else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL) {
			if (longSound) {
				LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum);
			} else {
				Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum);
			}
		} else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_HEIGHT) {
			if (longSound) {
				LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum);
			} else {
				Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum);
			}
			double channelExtent = my p_sound_scaling_height;
			double middle = 0.5 * (minimum + maximum);
			minimum = middle - 0.5 * channelExtent;
			maximum = middle + 0.5 * channelExtent;
		} else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_RANGE) {
			minimum = my p_sound_scaling_minimum;
			maximum = my p_sound_scaling_maximum;
		}
		if (minimum == maximum) { horizontal = true; minimum -= 1.0; maximum += 1.0;}
		Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum, maximum);
		if (horizontal) {
			Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF);
			double mid = 0.5 * (minimum + maximum);
			Graphics_text (my d_graphics, my d_startWindow, mid, Melder_float (Melder_half (mid)));
		} else {
			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics, cursorFunctionValue - minimum) > 5.0) {
				Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_BOTTOM);
				Graphics_text (my d_graphics, my d_startWindow, minimum, Melder_float (Melder_half (minimum)));
			}
			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics, maximum - cursorFunctionValue) > 5.0) {
				Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP);
				Graphics_text (my d_graphics, my d_startWindow, maximum, Melder_float (Melder_half (maximum)));
			}
		}
		if (minimum < 0 && maximum > 0 && ! horizontal) {
			Graphics_setWindow (my d_graphics, 0, 1, minimum, maximum);
			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || fabs (Graphics_dyWCtoMM (my d_graphics, cursorFunctionValue - 0.0)) > 3.0) {
				Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF);
				Graphics_text (my d_graphics, 0, 0, U"0");
			}
			Graphics_setColour (my d_graphics, Graphics_CYAN);
			Graphics_setLineType (my d_graphics, Graphics_DOTTED);
			Graphics_line (my d_graphics, 0, 0, 1, 0);
			Graphics_setLineType (my d_graphics, Graphics_DRAWN);
		}
		/*
		 * Garnish the drawing area of each channel.
		 */
		Graphics_setWindow (my d_graphics, 0, 1, 0, 1);
		Graphics_setColour (my d_graphics, Graphics_CYAN);
		Graphics_innerRectangle (my d_graphics, 0, 1, 0, 1);
		Graphics_setColour (my d_graphics, Graphics_BLACK);
		if (nchan > 1) {
			Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF);
			const char32 *channelName = my v_getChannelName (ichan);
			static MelderString channelLabel;
			MelderString_copy (& channelLabel, ( channelName ? U"ch" : U"Channel " ), ichan);
			if (channelName)
				MelderString_append (& channelLabel, U": ", channelName);
			if (ichan > 8 && ichan - my d_sound.channelOffset == 1) {
				MelderString_append (& channelLabel, U" " UNITEXT_UPWARDS_ARROW);
			} else if (ichan >= 8 && ichan - my d_sound.channelOffset == 8 && ichan < nchan) {
				MelderString_append (& channelLabel, U" " UNITEXT_DOWNWARDS_ARROW);
			}
			Graphics_text (my d_graphics, 1, 0.5, channelLabel.string);
		}
		/*
		 * Draw a very thin separator line underneath.
		 */
		if (ichan < nchan) {
			/*Graphics_setColour (d_graphics, Graphics_BLACK);*/
			Graphics_line (my d_graphics, 0, 0, 1, 0);
		}
		/*
		 * Draw the samples.
		 */
		/*if (ichan == 1) FunctionEditor_SoundAnalysis_drawPulses (this);*/
		if (sound) {
			Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum, maximum);
			if (cursorVisible && NUMdefined (cursorFunctionValue))
				FunctionEditor_drawCursorFunctionValue (me, cursorFunctionValue, Melder_float (Melder_half (cursorFunctionValue)), U"");
			Graphics_setColour (my d_graphics, Graphics_BLACK);
			Graphics_function (my d_graphics, sound -> z [ichan], first, last,
				Sampled_indexToX (sound, first), Sampled_indexToX (sound, last));
		} else {
			Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum * 32768, maximum * 32768);
			Graphics_function16 (my d_graphics,
				longSound -> buffer - longSound -> imin * nchan + (ichan - 1), nchan - 1, first, last,
				Sampled_indexToX (longSound, first), Sampled_indexToX (longSound, last));
		}
		Graphics_resetViewport (my d_graphics, vp);
	}
	Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0);
	Graphics_rectangle (my d_graphics, 0.0, 1.0, 0.0, 1.0);
}
void Sampled_drawInside (Sampled me, Graphics g, double xmin, double xmax, double ymin, double ymax,
	double speckle_mm, long ilevel, int unit)
{
	try {
		if (speckle_mm != 0.0) {
			Sampled_speckleInside (me, g, xmin, xmax, ymin, ymax, speckle_mm, ilevel, unit);
			return;
		}
		Function_unidirectionalAutowindow (me, & xmin, & xmax);
		long ixmin, ixmax, startOfDefinedStretch = -1;
		Sampled_getWindowSamples (me, xmin, xmax, & ixmin, & ixmax);
		if (Function_isUnitLogarithmic (me, ilevel, unit)) {
			ymin = Function_convertStandardToSpecialUnit (me, ymin, ilevel, unit);
			ymax = Function_convertStandardToSpecialUnit (me, ymax, ilevel, unit);
		}
		if (ymax <= ymin) return;
		Graphics_setWindow (g, xmin, xmax, ymin, ymax);
		autoNUMvector <double> xarray (ixmin - 1, ixmax + 1);
		autoNUMvector <double> yarray (ixmin - 1, ixmax + 1);
		double previousValue = Sampled_getValueAtSample (me, ixmin - 1, ilevel, unit);
		if (NUMdefined (previousValue)) {
			startOfDefinedStretch = ixmin - 1;
			xarray [ixmin - 1] = Sampled_indexToX (me, ixmin - 1);
			yarray [ixmin - 1] = previousValue;
		}
		for (long ix = ixmin; ix <= ixmax; ix ++) {
			double x = Sampled_indexToX (me, ix), value = Sampled_getValueAtSample (me, ix, ilevel, unit);
			if (NUMdefined (value)) {
				if (NUMdefined (previousValue)) {
					xarray [ix] = x;
					yarray [ix] = value;
				} else {
					startOfDefinedStretch = ix - 1;
					xarray [ix - 1] = x - 0.5 * my dx;
					yarray [ix - 1] = value;
					xarray [ix] = x;
					yarray [ix] = value;
				}
			} else if (NUMdefined (previousValue)) {
				Melder_assert (startOfDefinedStretch >= ixmin - 1);
				if (ix > ixmin) {
					xarray [ix] = x - 0.5 * my dx;
					yarray [ix] = previousValue;
					if (xarray [startOfDefinedStretch] < xmin) {
						double phase = (xmin - xarray [startOfDefinedStretch]) / my dx;
						xarray [startOfDefinedStretch] = xmin;
						yarray [startOfDefinedStretch] = phase * yarray [startOfDefinedStretch + 1] + (1.0 - phase) * yarray [startOfDefinedStretch];
					}
					Graphics_polyline (g, ix + 1 - startOfDefinedStretch, & xarray [startOfDefinedStretch], & yarray [startOfDefinedStretch]);
				}
				startOfDefinedStretch = -1;
			}
			previousValue = value;
		}
		if (startOfDefinedStretch > -1) {
			double x = Sampled_indexToX (me, ixmax + 1), value = Sampled_getValueAtSample (me, ixmax + 1, ilevel, unit);
			Melder_assert (NUMdefined (previousValue));
			if (NUMdefined (value)) {
				xarray [ixmax + 1] = x;
				yarray [ixmax + 1] = value;
			} else {
				xarray [ixmax + 1] = x - 0.5 * my dx;
				yarray [ixmax + 1] = previousValue;
			}
			if (xarray [startOfDefinedStretch] < xmin) {
				double phase = (xmin - xarray [startOfDefinedStretch]) / my dx;
				xarray [startOfDefinedStretch] = xmin;
				yarray [startOfDefinedStretch] = phase * yarray [startOfDefinedStretch + 1] + (1.0 - phase) * yarray [startOfDefinedStretch];
			}
			if (xarray [ixmax + 1] > xmax) {
				double phase = (xarray [ixmax + 1] - xmax) / my dx;
				xarray [ixmax + 1] = xmax;
				yarray [ixmax + 1] = phase * yarray [ixmax] + (1.0 - phase) * yarray [ixmax + 1];
			}
			Graphics_polyline (g, ixmax + 2 - startOfDefinedStretch, & xarray [startOfDefinedStretch], & yarray [startOfDefinedStretch]);
		}
	} catch (MelderError) {
		Melder_clearError ();
	}
}
Example #23
0
bool Pitch_isVoiced_i (Pitch me, long iframe) {
	return NUMdefined (Sampled_getValueAtSample (me, iframe, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ));
}
void BarkSpectrogram_drawSekeyHansonFilterFunctions (BarkSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish) {
	double xmin = zmin, xmax = zmax;
	if (zmin >= zmax) {
		zmin = my ymin; zmax = my ymax;
		xmin = xIsHertz ? my v_frequencyToHertz (zmin) : zmin;
		xmax = xIsHertz ? my v_frequencyToHertz (zmax) : zmax;
	}
	if (xIsHertz) {
		zmin = my v_hertzToFrequency (xmin); zmax = my v_hertzToFrequency (xmax);
	}
	if (ymin >= ymax) {
		ymin = yscale_dB ? -60 : 0;
		ymax = yscale_dB ? 0 : 1;
	}
	fromFilter = fromFilter <= 0 ? 1 : fromFilter;
	toFilter = toFilter <= 0 || toFilter > my ny ? my ny : toFilter;
	if (fromFilter > toFilter) {
		fromFilter = 1; toFilter = my ny;
	}
	long n = xIsHertz ? 1000 : 500;
	autoNUMvector<double> xz (1, n), xhz (1,n), y (1, n);

	Graphics_setInner (g);
	Graphics_setWindow (g, xmin, xmax, ymin, ymax);

	double dz = (zmax - zmin) / (n - 1);
	for (long iz = 1; iz <= n; iz++) {
		double f = zmin + (iz - 1) * dz;
		xz[iz] = f;
		xhz[iz] = my v_frequencyToHertz (f); // just in case we need the linear scale
	}
	for (long ifilter = fromFilter; ifilter <= toFilter; ifilter++) {
		double zMid = Matrix_rowToY (me, ifilter);
		for (long iz = 1; iz <= n; iz++) {
			double z = xz[iz] - (zMid - 0.215);
			double amp = 7 - 7.5 * z - 17.5 * sqrt (0.196 + z * z);
			y[iz] = yscale_dB ? amp : pow (10, amp / 10);
		}
		// the drawing
		double x1 = xIsHertz ? xhz[1] : xz[1], y1 = y[1];
		for (long iz = 2; iz <= n; iz++) {
			double x2 = xIsHertz ? xhz[iz] : xz[iz], y2 = y[iz];
			if (NUMdefined (x1) && NUMdefined (x2)) {
				double xo1, yo1, xo2, yo2;
				if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) {
					Graphics_line (g, xo1, yo1, xo2, yo2);
				}
			}
			x1 = x2; y1 = y2;
		}
	}	
	Graphics_unsetInner (g);

	if (garnish) {
		double distance = yscale_dB ? 10 : 0.5;
		Graphics_drawInnerBox (g);
		Graphics_marksBottom (g, 2, 1, 1, 0);
		Graphics_marksLeftEvery (g, 1, distance, 1, 1, 0);
		Graphics_textLeft (g, 1, yscale_dB ? U"Amplitude (dB)" : U"Amplitude");
		Graphics_textBottom (g, 1, Melder_cat (U"Frequency (", xIsHertz ? U"Hz" : my v_getFrequencyUnit (), U")"));
	}
}
Example #25
0
bool Pitch_isVoiced_t (Pitch me, double time) {
	return NUMdefined (Sampled_getValueAtX (me, time, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ, false));
}
void MelSpectrogram_drawTriangularFilterFunctions (MelSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish) {
	double xmin = zmin, xmax = zmax;
	if (zmin >= zmax) {
		zmin = my ymin; zmax = my ymax; // mel
		xmin = xIsHertz ? my v_frequencyToHertz (zmin) : zmin;
		xmax = xIsHertz ? my v_frequencyToHertz (zmax) : zmax;
	}
	if (xIsHertz) {
		zmin = my v_hertzToFrequency (xmin); zmax = my v_hertzToFrequency (xmax);
	}

	if (ymin >= ymax) {
		ymin = yscale_dB ? -60 : 0;
		ymax = yscale_dB ? 0 : 1;
	}
	fromFilter = fromFilter <= 0 ? 1 : fromFilter;
	toFilter = toFilter <= 0 || toFilter > my ny ? my ny : toFilter;
	if (fromFilter > toFilter) {
		fromFilter = 1; toFilter = my ny;
	}
	
	long n = xIsHertz ? 1000 : 500;
	autoNUMvector<double> xz (1, n), xhz (1,n), y (1, n);

	Graphics_setInner (g);
	Graphics_setWindow (g, xmin, xmax, ymin, ymax);
	
	double dz = (zmax - zmin) / (n - 1);
	for (long iz = 1; iz <= n; iz++) {
		double f = zmin + (iz - 1) * dz;
		xz[iz] = f;
		xhz[iz] = my v_frequencyToHertz (f); // just in case we need the linear scale
	}
	
	for (long ifilter = fromFilter; ifilter <= toFilter; ifilter++) {
		double zc = Matrix_rowToY (me, ifilter), zl = zc - my dy, zh = zc + my dy;
		double xo1, yo1, xo2, yo2;
		if (yscale_dB) {
			for (long iz = 1; iz <= n; iz++) {
				double z = xz[iz];
				double amp = NUMtriangularfilter_amplitude (zl, zc, zh, z);
				y[iz] = yscale_dB ? (amp > 0 ? 20 * log10 (amp) : ymin - 10) : amp;
			}
			double x1 = xIsHertz ? xhz[1] : xz[1], y1 = y[1];
			if (NUMdefined (y1)) {
				for (long iz = 1; iz <= n; iz++) {
					double x2 = xIsHertz ? xhz[iz] : xz[iz], y2 = y[iz];
					if (NUMdefined (y2)) {
						if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) {
							Graphics_line (g, xo1, yo1, xo2, yo2);
						}
					}
					x1 = x2; y1 = y2;
				}
			}
		} else {
			double x1 = xIsHertz ? my v_frequencyToHertz (zl) : zl;
			double x2 = xIsHertz ? my v_frequencyToHertz (zc) : zc;
			if (NUMclipLineWithinRectangle (x1, 0, x2, 1, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) {
				Graphics_line (g, xo1, yo1, xo2, yo2);
			}
			double x3 = xIsHertz ? my v_frequencyToHertz (zh) : zh;
			if (NUMclipLineWithinRectangle (x2, 1, x3, 0, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) {
				Graphics_line (g, xo1, yo1, xo2, yo2);
			}
		}
	}

	Graphics_unsetInner (g);

	if (garnish) {
		Graphics_drawInnerBox (g);
		Graphics_marksBottom (g, 2, 1, 1, 0);
		Graphics_marksLeftEvery (g, 1, yscale_dB ? 10 : 0.5, 1, 1, 0);
		Graphics_textLeft (g, 1, yscale_dB ? U"Amplitude (dB)" : U"Amplitude");
		Graphics_textBottom (g, 1, Melder_cat (U"Frequency (", ( xIsHertz ? U"Hz" : my v_getFrequencyUnit () ), U")"));
	}
}
Example #27
0
double Function_convertSpecialToStandardUnit (Function me, double value, long ilevel, int unit) {
	return NUMdefined (value) ? my v_convertSpecialToStandardUnit (value, ilevel, unit) : NUMundefined;
}
static void Sampled_getSum2AndDefinitionRange
	(Sampled me, double xmin, double xmax, long ilevel, int unit, double mean, int interpolate, double *return_sum2, double *return_definitionRange)
{
	/*
		This function computes the area under the linearly interpolated squared difference curve between xmin and xmax.
		Outside [x1-dx/2, xN+dx/2], the curve is undefined and neither times nor values are counted.
		In [x1-dx/2,x1] and [xN,xN+dx/2], the curve is linearly extrapolated.
	*/
	long imin, imax, isamp;
	double sum2 = 0.0, definitionRange = 0.0;
	Function_unidirectionalAutowindow (me, & xmin, & xmax);
	if (Function_intersectRangeWithDomain (me, & xmin, & xmax)) {
		if (interpolate) {
			if (Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) {
				double leftEdge = my x1 - 0.5 * my dx, rightEdge = leftEdge + my nx * my dx;
				for (isamp = imin; isamp <= imax; isamp ++) {
					double value = my v_getValueAtSample (isamp, ilevel, unit);   // a fast way to integrate a linearly interpolated curve; works everywhere except at the edges
					if (NUMdefined (value)) {
						value -= mean;
						value *= value;
						definitionRange += 1.0;
						sum2 += value;
					}
				}
				/*
				 * Corrections within the first and last sampling intervals.
				 */
				if (xmin > leftEdge) {   // otherwise, constant extrapolation over 0.5 sample is OK
					double phase = (my x1 + (imin - 1) * my dx - xmin) / my dx;   // this fraction of sampling interval is still to be determined
					double rightValue = Sampled_getValueAtSample (me, imin, ilevel, unit);
					double leftValue = Sampled_getValueAtSample (me, imin - 1, ilevel, unit);
					if (NUMdefined (rightValue)) {
						rightValue -= mean;
						rightValue *= rightValue;
						definitionRange -= 0.5;   // delete constant extrapolation over 0.5 sample
						sum2 -= 0.5 * rightValue;
						if (NUMdefined (leftValue)) {
							leftValue -= mean;
							leftValue *= leftValue;
							definitionRange += phase;   // add current fraction
							sum2 += phase * (rightValue + 0.5 * phase * (leftValue - rightValue));   // interpolate to outside sample
						} else {
							if (phase > 0.5) phase = 0.5;
							definitionRange += phase;   // add current fraction, but never more than 0.5
							sum2 += phase * rightValue;
						}
					} else if (NUMdefined (leftValue) && phase > 0.5) {
						leftValue -= mean;
						leftValue *= leftValue;
						definitionRange += phase - 0.5;
						sum2 += (phase - 0.5) * leftValue;
					}
				}
				if (xmax < rightEdge) {   // otherwise, constant extrapolation is OK
					double phase = (xmax - (my x1 + (imax - 1) * my dx)) / my dx;   // this fraction of sampling interval is still to be determined
					double leftValue = Sampled_getValueAtSample (me, imax, ilevel, unit);
					double rightValue = Sampled_getValueAtSample (me, imax + 1, ilevel, unit);
					if (NUMdefined (leftValue)) {
						leftValue -= mean;
						leftValue *= leftValue;
						definitionRange -= 0.5;   // delete constant extrapolation over 0.5 sample
						sum2 -= 0.5 * leftValue;
						if (NUMdefined (rightValue)) {
							rightValue -= mean;
							rightValue *= rightValue;
							definitionRange += phase;   // add current fraction
							sum2 += phase * (leftValue + 0.5 * phase * (rightValue - leftValue));   // interpolate to outside sample
						} else {
							if (phase > 0.5) phase = 0.5;
							definitionRange += phase;   // add current fraction, but never more than 0.5
							sum2 += phase * leftValue;
						}
					} else if (NUMdefined (rightValue) && phase > 0.5) {
						rightValue -= mean;
						rightValue *= rightValue;
						definitionRange += phase - 0.5;
						sum2 += (phase - 0.5) * rightValue;
					}
				}
			} else {   // no sample centres between xmin and xmax
				/*
				 * Try to return the mean of the interpolated values at these two points.
				 * Thus, a small (xmin, xmax) range gives the same value as the (xmin+xmax)/2 point.
				 */
				double leftValue = Sampled_getValueAtSample (me, imax, ilevel, unit);
				double rightValue = Sampled_getValueAtSample (me, imin, ilevel, unit);
				double phase1 = (xmin - (my x1 + (imax - 1) * my dx)) / my dx;
				double phase2 = (xmax - (my x1 + (imax - 1) * my dx)) / my dx;
				if (imin == imax + 1) {   // not too far from sample definition region
					if (NUMdefined (leftValue)) {
						leftValue -= mean;
						leftValue *= leftValue;
						if (NUMdefined (rightValue)) {
							rightValue -= mean;
							rightValue *= rightValue;
							definitionRange += phase2 - phase1;
							sum2 += (phase2 - phase1) * (leftValue + 0.5 * (phase1 + phase2) * (rightValue - leftValue));
						} else if (phase1 < 0.5) {
							if (phase2 > 0.5) phase2 = 0.5;
							definitionRange += phase2 - phase1;
							sum2 += (phase2 - phase1) * leftValue;
						}
					} else if (NUMdefined (rightValue) && phase2 > 0.5) {
						rightValue -= mean;
						rightValue *= rightValue;
						if (phase1 < 0.5) phase1 = 0.5;
						definitionRange += phase2 - phase1;
						sum2 += (phase2 - phase1) * rightValue;
					}
				}
			}
		} else {   // no interpolation
			double rimin = Sampled_xToIndex (me, xmin), rimax = Sampled_xToIndex (me, xmax);
			if (rimax >= 0.5 && rimin < my nx + 0.5) {
				imin = rimin < 0.5 ? 0 : (long) floor (rimin + 0.5);
				imax = rimax >= my nx + 0.5 ? my nx + 1 : (long) floor (rimax + 0.5);
				for (isamp = imin + 1; isamp < imax; isamp ++) {
					double value = my v_getValueAtSample (isamp, ilevel, unit);
					if (NUMdefined (value)) {
						value -= mean;
						value *= value;
						definitionRange += 1.0;
						sum2 += value;
					}
				}
				if (imin == imax) {
					double value = my v_getValueAtSample (imin, ilevel, unit);
					if (NUMdefined (value)) {
						double phase = rimax - rimin;
						value -= mean;
						value *= value;
						definitionRange += phase;
						sum2 += phase * value;
					}
				} else {
					if (imin >= 1) {
						double value = my v_getValueAtSample (imin, ilevel, unit);
						if (NUMdefined (value)) {
							double phase = imin - rimin + 0.5;
							value -= mean;
							value *= value;
							definitionRange += phase;
							sum2 += phase * value;
						}
					}
					if (imax <= my nx) {
						double value = my v_getValueAtSample (imax, ilevel, unit);
						if (NUMdefined (value)) {
							double phase = rimax - imax + 0.5;
							value -= mean;
							value *= value;
							definitionRange += phase;
							sum2 += phase * value;
						}
					}
				}
			}
		}
	}
	if (return_sum2) *return_sum2 = sum2;
	if (return_definitionRange) *return_definitionRange = definitionRange;
}
Example #29
0
double AmplitudeTier_getShimmer_dda (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) {
	double apq3 = AmplitudeTier_getShimmer_apq3 (me, pmin, pmax, maximumAmplitudeFactor);
	return NUMdefined (apq3) ? 3.0 * apq3 : NUMundefined;
}
Example #30
0
double Function_convertToNonlogarithmic (Function me, double value, long ilevel, int unit) {
	return NUMdefined (value) && my v_isUnitLogarithmic (ilevel, unit) ? pow (10.0, value) : value;
}