Example #1
0
static void Sound_PointProcess_fillVoiceless (Sound me, PointProcess pulses) {
	long ipointleft, ipointright;
	double beginVoiceless = my xmin, endVoiceless;
	for (ipointleft = 1; ipointleft <= pulses -> nt; ipointleft = ipointright + 1) {
		long i1, i2, i;
		endVoiceless = pulses -> t [ipointleft] - 0.005;
		i1 = Sampled_xToHighIndex (me, beginVoiceless);
		if (i1 < 1) i1 = 1; if (i1 > my nx) i1 = my nx;
		i2 = Sampled_xToLowIndex (me, endVoiceless);
		if (i2 < 1) i2 = 1; if (i2 > my nx) i2 = my nx;
		if (i2 - i1 > 10) for (i = i1; i <= i2; i ++)
			my z [1] [i] = NUMrandomGauss (0.0, 0.3);
		for (ipointright = ipointleft + 1; ipointright <= pulses -> nt; ipointright ++)
			if (pulses -> t [ipointright] - pulses -> t [ipointright - 1] > MAX_T)
				break;
		ipointright --;
		beginVoiceless = pulses -> t [ipointright] + 0.005;
	}
	endVoiceless = my xmax;
	{
		long i1, i2, i;
		i1 = Sampled_xToHighIndex (me, beginVoiceless);
		if (i1 < 1) i1 = 1; if (i1 > my nx) i1 = my nx;
		i2 = Sampled_xToLowIndex (me, endVoiceless);
		if (i2 < 1) i2 = 1; if (i2 > my nx) i2 = my nx;
		if (i2 - i1 > 10) for (i = i1; i <= i2; i ++)
			my z [1] [i] = NUMrandomGauss (0.0, 0.3);
	}
}
Example #2
0
static void copyFlat (Sound me, double tmin, double tmax, Sound thee, double tminTarget) {
	long imin = Sampled_xToHighIndex (me, tmin);
	if (imin < 1) imin = 1;
	long imax = Sampled_xToHighIndex (me, tmax) - 1;   // not xToLowIndex: ensure separation of subsequent calls
	if (imax > my nx) imax = my nx;
	if (imax < imin) return;
	long iminTarget = Sampled_xToHighIndex (thee, tminTarget);
	if (iminTarget < 1) iminTarget = 1;
	trace (tmin, U" ", tmax, U" ", tminTarget, U" ", imin, U" ", imax, U" ", iminTarget);
	Melder_assert (iminTarget + imax - imin <= thy nx);
	NUMvector_copyElements (my z [1] + imin, thy z [1] + iminTarget, 0, imax - imin);
}
Example #3
0
static void copyFall (Sound me, double tmin, double tmax, Sound thee, double tminTarget) {
	long imin = Sampled_xToHighIndex (me, tmin);
	if (imin < 1) imin = 1;
	long imax = Sampled_xToHighIndex (me, tmax) - 1;   // not xToLowIndex: ensure separation of subsequent calls
	if (imax > my nx) imax = my nx;
	if (imax < imin) return;
	long iminTarget = Sampled_xToHighIndex (thee, tminTarget);
	long distance = iminTarget - imin;
	double dphase = NUMpi / (imax - imin + 1);
	for (long i = imin; i <= imax; i ++) {
		long iTarget = i + distance;
		if (iTarget >= 1 && iTarget <= thy nx)
			thy z [1] [iTarget] += my z [1] [i] * 0.5 * (1.0 + cos (dphase * (i - imin + 0.5)));
	}
}
Example #4
0
int Manipulation_playPart (Manipulation me, double tmin, double tmax, int method) {
	try {
		if (method == Manipulation_OVERLAPADD) {
			if (! my sound)
				Melder_throw (U"Cannot synthesize overlap-add without a sound.");
			autoSound part = Data_copy (my sound.get());
			long imin = Sampled_xToLowIndex (part.get(), tmin), imax = Sampled_xToHighIndex (part.get(), tmax);
			double *amp = part -> z [1];
			for (long i = 1; i <= imin; i ++) amp [i] = 0.0;
			for (long i = imax; i <= part -> nx; i ++) amp [i] = 0.0;
			autoSound saved = my sound.move();
			my sound = part.move();
			try {
				autoSound played = Manipulation_to_Sound (me, Manipulation_OVERLAPADD);
				my sound = saved.move();
				amp = played -> z [1];
				for (imin = 1; imin <= played -> nx; imin ++)
					if (amp [imin] != 0.0) break;
				for (imax = played -> nx; imax >= 1; imax --)
					if (amp [imax] != 0.0) break;
				Sound_playPart (played.get(), played -> x1 + (imin - 1.5) * played -> dx, played -> x1 + (imax - 0.5) * played -> dx, nullptr, nullptr);
			} catch (MelderError) {
				my sound = saved.move();
				throw;
			}
		} else {
			autoSound sound = Manipulation_to_Sound (me, method);
			Sound_playPart (sound.get(), tmin, tmax, nullptr, nullptr);
		}
		return 1;
	} catch (MelderError) {
		Melder_throw (me, U": not played.");
	}
}
Example #5
0
Polygon Sound_to_Polygon (Sound me, int channel, double tmin, double tmax, double ymin, double ymax, double level) {
	try {
		bool clip = ymin < ymax;
		if (channel < 1 || channel > my ny) {
			Melder_throw ("Channel does not exist.");
		}
		if (tmin >= tmax) {
			tmin = my xmin;
			tmax = my xmax;
		}
		if (tmin < my xmin) {
			tmin = my xmin;
		}
		if (tmax > my xmax) {
			tmax = my xmax;
		}
		if (tmin >= my xmax || tmax < my xmin) {
			Melder_throw ("Invalid domain.");
		}
		long k = 1, i1 = Sampled_xToHighIndex (me, tmin);
		long i2 = Sampled_xToLowIndex (me, tmax);
		long numberOfPoints = i2 - i1 + 1 + 2 + 2; // begin + endpoint + level
		autoPolygon him = Polygon_create (numberOfPoints);

		/*
			In Vector_getValueAtX the interpolation only returns defined values between the
			left and right edges that are calculated as
				left = x1 - 0.5 * dx; right = left + my nx * dx.
			Given a sound, for example on the domain [0,...], the value of 'left' with the above formula might
			not return exactly xmin but instead a very small deviation (due to the imprecise
			representation of real numbers in a computer).
			Querying for the value at xmin which is outside the interpolation domain then produces an 'undefined'.
			We try to avoid this with the following workaround.
		*/
		double xmin = my x1 - 0.5 * my dx;
		double xmax = xmin + my nx * my dx;
		tmin = tmin < xmin ? xmin : tmin;
		tmax = tmax > xmax ? xmax : tmax;
		// End of workaround
		his x[k] = tmin;
		his y[k++] = CLIP_Y (level, ymin, ymax);
		his x[k] = tmin;
		double y = Vector_getValueAtX (me, tmin, channel, Vector_VALUE_INTERPOLATION_LINEAR);
		his y[k++] = CLIP_Y (y, ymin, ymax);
		for (long i = i1; i <= i2; i++) {
			y = my z[channel][i];
			his x[k] = my x1 + (i - 1) * my dx;
			his y[k++] = CLIP_Y (y, ymin, ymax);
		}
		his x[k] = tmax;
		y = Vector_getValueAtX (me, tmax, channel, Vector_VALUE_INTERPOLATION_LINEAR);
		his y[k++] = CLIP_Y (y, ymin, ymax);
		his x[k] = tmax;
		his y[k++] = CLIP_Y (level, ymin, ymax);
		return him.transfer();
	} catch (MelderError) {
		Melder_throw (me, ":no Polygon created.");
	}
}
static Spectrum Spectrum_band (Spectrum me, double fmin, double fmax) {
	autoSpectrum band = Data_copy (me);
	double *re = band -> z [1], *im = band -> z [2];
	long imin = Sampled_xToLowIndex (band.peek(), fmin), imax = Sampled_xToHighIndex (band.peek(), fmax);
	for (long i = 1; i <= imin; i ++) re [i] = 0.0, im [i] = 0.0;
	for (long i = imax; i <= band -> nx; i ++) re [i] = 0.0, im [i] = 0.0;
	return band.transfer();
}
Example #7
0
static double Sound_findMaximumCorrelation (Sound me, double t1, double windowLength, double tmin2, double tmax2, double *tout, double *peak) {
	double maximumCorrelation = -1.0, r1 = 0.0, r2 = 0.0, r3 = 0.0, r1_best, r3_best, ir;
	double halfWindowLength = 0.5 * windowLength;
	long i1, i2, ileft2;
	long ileft1 = Sampled_xToNearestIndex ((Sampled) me, t1 - halfWindowLength);
	long iright1 = Sampled_xToNearestIndex ((Sampled) me, t1 + halfWindowLength);
	long ileft2min = Sampled_xToLowIndex ((Sampled) me, tmin2 - halfWindowLength);
	long ileft2max = Sampled_xToHighIndex ((Sampled) me, tmax2 - halfWindowLength);
	*peak = 0.0;   /* Default. */
	for (ileft2 = ileft2min; ileft2 <= ileft2max; ileft2 ++) {
		double norm1 = 0.0, norm2 = 0.0, product = 0.0, localPeak = 0.0;
		if (my ny == 1) {
			for (i1 = ileft1, i2 = ileft2; i1 <= iright1; i1 ++, i2 ++) {
				if (i1 < 1 || i1 > my nx || i2 < 1 || i2 > my nx) continue;
				double amp1 = my z [1] [i1], amp2 = my z [1] [i2];
				norm1 += amp1 * amp1;
				norm2 += amp2 * amp2;
				product += amp1 * amp2;
				if (fabs (amp2) > localPeak)
					localPeak = fabs (amp2);
			}
		} else {
			for (i1 = ileft1, i2 = ileft2; i1 <= iright1; i1 ++, i2 ++) {
				if (i1 < 1 || i1 > my nx || i2 < 1 || i2 > my nx) continue;
				double amp1 = 0.5 * (my z [1] [i1] + my z [2] [i1]), amp2 = 0.5 * (my z [1] [i2] + my z [2] [i2]);
				norm1 += amp1 * amp1;
				norm2 += amp2 * amp2;
				product += amp1 * amp2;
				if (fabs (amp2) > localPeak)
					localPeak = fabs (amp2);
			}
		}
		r1 = r2;
		r2 = r3;
		r3 = product ? product / (sqrt (norm1 * norm2)) : 0.0;
		if (r2 > maximumCorrelation && r2 >= r1 && r2 >= r3) {
			r1_best = r1;
			maximumCorrelation = r2;
			r3_best = r3;
			ir = ileft2 - 1;
			*peak = localPeak;  
		}
	}
	/*
	 * Improve the result by means of parabolic interpolation.
	 */
	if (maximumCorrelation > -1.0) {
		double d2r = 2 * maximumCorrelation - r1_best - r3_best;
		if (d2r != 0.0) {
			double dr = 0.5 * (r3_best - r1_best);
			maximumCorrelation += 0.5 * dr * dr / d2r;
			ir += dr / d2r;
		}
		*tout = t1 + (ir - ileft1) * my dx;
	}
	return maximumCorrelation;
}
Example #8
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 #9
0
static void menu_cb_voiceless (EDITOR_ARGS) {
    EDITOR_IAM (PitchEditor);
    Pitch pitch = (Pitch) my data;
    long ileft = Sampled_xToHighIndex (pitch, my d_startSelection);
    long iright = Sampled_xToLowIndex (pitch, my d_endSelection);
    if (ileft < 1) ileft = 1;
    if (iright > pitch -> nx) iright = pitch -> nx;
    Editor_save (me, L"Unvoice");
    for (long i = ileft; i <= iright; i ++) {
        Pitch_Frame frame = & pitch -> frame [i];
        for (long cand = 1; cand <= frame -> nCandidates; cand ++) {
            if (frame -> candidate [cand]. frequency == 0.0) {
                struct structPitch_Candidate help = frame -> candidate [1];
                frame -> candidate [1] = frame -> candidate [cand];
                frame -> candidate [cand] = help;
            }
        }
    }
    FunctionEditor_redraw (me);
    my broadcastDataChanged ();
}
Example #10
0
static int Pitch_getVoicedIntervalAfter (Pitch me, double after, double *tleft, double *tright) {
	long ileft = Sampled_xToHighIndex (me, after), iright;
	if (ileft > my nx) return 0;   /* Offright. */
	if (ileft < 1) ileft = 1;   /* Offleft. */

	/* Search for first voiced frame. */
	for (; ileft <= my nx; ileft ++)
		if (Pitch_isVoiced_i (me, ileft)) break;
	if (ileft > my nx) return 0;   /* Offright. */

	/* Search for last voiced frame. */
	for (iright = ileft; iright <= my nx; iright ++)
		if (! Pitch_isVoiced_i (me, iright)) break;
	iright --;

	*tleft = Sampled_indexToX (me, ileft) - 0.5 * my dx;   /* The whole frame is considered voiced. */
	*tright = Sampled_indexToX (me, iright) + 0.5 * my dx;
	if (*tleft >= my xmax - 0.5 * my dx) return 0;
	if (*tleft < my xmin) *tleft = my xmin;
	if (*tright > my xmax) *tright = my xmax;
	return 1;
}
Example #11
0
/*
	gain used as a constant amplitude multiplyer within a frame of duration my dx.
	future alternative: convolve gain with a  smoother.
*/
autoSound LPC_and_Sound_filter (LPC me, Sound thee, int useGain) {
	try {
		double xmin = my xmin > thy xmin ? my xmin : thy xmin;
		double xmax = my xmax < thy xmax ? my xmax : thy xmax;
		if (xmin >= xmax) {
			Melder_throw (U"Domains of Sound [", thy xmin, U",", thy xmax, U"] and LPC [",
				my xmin, U",", my xmax, U"] do not overlap.");
		}
		// resample sound if samplings don't match
		autoSound source;
		if (my samplingPeriod != thy dx) {
			source = Sound_resample (thee, 1.0 / my samplingPeriod, 50);
			thee = source.get();   // reference copy; remove at end
		}

		autoSound him = Data_copy (thee);

		double *x = his z[1];
		long ifirst = Sampled_xToHighIndex (thee, xmin);
		long ilast = Sampled_xToLowIndex (thee, xmax);
		for (long i = ifirst; i <= ilast; i++) {
			double t = his x1 + (i - 1) * his dx; /* Sampled_indexToX (him, i) */
			long iFrame = lround ( (t - my x1) / my dx + 1.0); /* Sampled_xToNearestIndex (me, t) */
			if (iFrame < 1) {
				continue;
			}
			if (iFrame > my nx) {
				break;
			}
			double *a = my d_frames[iFrame].a;
			long m = i > my d_frames[iFrame].nCoefficients ? my d_frames[iFrame].nCoefficients : i - 1;
			for (long j = 1; j <= m; j++) {
				x[i] -= a[j] * x[i - j];
			}
		}

		// Make samples before first frame and after last frame zero.

		for (long i = 1; i < ifirst; i++) {
			x[i] = 0.0;
		}

		for (long i = ilast + 1; i <= his nx; i++) {
			x[i] = 0.0;
		}
		if (useGain) {
			for (long i = ifirst; i <= ilast; i++) {
				double t = his x1 + (i - 1) * his dx; /* Sampled_indexToX (him, i) */
				double riFrame = (t - my x1) / my dx + 1; /* Sampled_xToIndex (me, t); */
				long iFrame = (long) floor (riFrame);
				double phase = riFrame - iFrame;
				if (iFrame < 0 || iFrame > my nx) {
					x[i] = 0.0;
				} else if (iFrame == 0) {
					x[i] *= sqrt (my d_frames[1].gain) * phase;
				} else if (iFrame == my nx) {
					x[i] *= sqrt (my d_frames[my nx].gain) * (1.0 - phase);
				} else x[i] *=
					    phase * sqrt (my d_frames[iFrame + 1].gain) + (1.0 - phase) * sqrt (my d_frames[iFrame].gain);
			}
		}
		return him;
	} catch (MelderError) {
		Melder_throw (thee, U": not filtered.");
	}
}
Example #12
0
Polygon Sounds_to_Polygon_enclosed (Sound me, Sound thee, int channel, double tmin, double tmax, double ymin, double ymax) {
	try {
		bool clip = ymin < ymax;
		if (my ny > 1 && thy ny > 1 && my ny != thy ny) {
			Melder_throw ("The numbers of channels of the two sounds have to be equal or 1.");
		}

		long numberOfChannels = my ny > thy ny ? my ny : thy ny;

		if (channel < 1 || channel > numberOfChannels) {
			Melder_throw ("Channel does not exist.");
		}
		// find overlap in the domains  with xmin workaround as in Sound_to_Polygon
		double xmin1 = my x1 - 0.5 * my dx, xmin2 = thy x1 - 0.5 * thy dx ;
		double xmin = my xmin > thy xmin ? xmin1 : xmin2;
		double xmax = my xmax < thy xmax ? xmin1 + my nx * my dx : xmin2 + thy nx * thy dx;
		if (xmax <= xmin) {
			Melder_throw ("Domains must overlap.");
		}
		if (tmin >= tmax) {
			tmin = xmin;
			tmax = xmax;
		}
		if (tmin < xmin) {
			tmin = xmin;
		}
		if (tmax > xmax) {
			tmax = xmax;
		}
		if (tmin >= xmax || tmax < xmin) {
			Melder_throw ("Invalid domain.");
		}

		long k = 1;
		long ib1 = Sampled_xToHighIndex (me, tmin);
		long ie1 = Sampled_xToLowIndex (me, tmax);
		long n1 = ie1 - ib1 + 1;
		long ib2 = Sampled_xToHighIndex (thee, tmin);
		long ie2 = Sampled_xToLowIndex (thee, tmax);
		long n2 = ie2 - ib2 + 1;
		long numberOfPoints = n1 + n2 + 4; // me + thee + begin + endpoint + closing

		autoPolygon him = Polygon_create (numberOfPoints);

		// my starting point at tmin

		double y = Vector_getValueAtX (me, tmin, (my ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR);
		his x[k] = tmin;
		his y[k++] = CLIP_Y (y, ymin, ymax);

		// my samples

		for (long i = ib1; i <= ie1; i++) {
			double t = my x1 + (i - 1) * my dx;
			y = my z[my ny == 1 ? 1 : channel][i];
			his x[k] = t;
			his y[k++] = CLIP_Y (y, ymin, ymax);
		}

		// my end point at tmax

		y = Vector_getValueAtX (me, tmax, (my ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR);
		his x[k] = tmax;
		his y[k++] = y;

		// thy starting point at tmax

		y = Vector_getValueAtX (thee, tmax, (thy ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR);
		his x[k] = tmax;
		his y[k++] = y;

		// thy samples

		for (long i = ie2; i >= ib2; i--) {
			double t = thy x1 + (i - 1) * thy dx;
			y = thy z[thy ny == 1 ? 1 : channel][i];
			his x[k] = t;
			his y[k++] = CLIP_Y (y, ymin, ymax);
		}

		// thy end point at tmin

		y = Vector_getValueAtX (thee, tmin, (thy ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR);
		his x[k] = tmin;
		his y[k] = y;

		Melder_assert (k == numberOfPoints);
		return him.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no enclosed Polygon created.");
	}
}