static int PointProcess_isVoiced_t (PointProcess me, double t, double maxT) {
	long imid = PointProcess_getNearestIndex (me, t);
	if (imid == 0) return 0;
	double tmid = my t [imid];
	int leftVoiced = imid > 1 && tmid - my t [imid - 1] <= maxT;
	int rightVoiced = imid < my nt && my t [imid + 1] - tmid <= maxT;
	if ((leftVoiced && t <= tmid) || (rightVoiced && t >= tmid)) return 1;
	if (leftVoiced && t < 1.5 * tmid - 0.5 * my t [imid - 1]) return 1;
	if (rightVoiced && t > 1.5 * tmid - 0.5 * my t [imid + 1]) return 1;
	return 0;
}
Exemplo n.º 2
0
autoSound Sound_Point_Point_to_Sound (Sound me, PointProcess source, PointProcess target, double maxT) {
	try {
		autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1);
		if (source -> nt < 2 || target -> nt < 2) {   // almost completely voiceless?
			NUMvector_copyElements (my z [1], thy z [1], 1, my nx);
			return thee;
		}
		for (long i = 1; i <= target -> nt; i ++) {
			double tmid = target -> t [i];
			double tleft = i > 1 ? target -> t [i - 1] : my xmin;
			double tright = i < target -> nt ? target -> t [i + 1] : my xmax;
			double leftWidth = tmid - tleft, rightWidth = tright - tmid;
			int leftVoiced = i > 1 && leftWidth <= maxT;
			int rightVoiced = i < target -> nt && rightWidth <= maxT;
			long isource = PointProcess_getNearestIndex (source, tmid);
			if (! leftVoiced) leftWidth = rightWidth;   // symmetric bell
			if (! rightVoiced) rightWidth = leftWidth;   // symmetric bell
			if (leftVoiced || rightVoiced) {
				copyBell2 (me, source, isource, leftWidth, rightWidth, thee.get(), tmid, maxT);
				if (! leftVoiced) {
					double startOfFlat = ( i == 1 ? tleft : (tleft + tmid) / 2.0 );
					double endOfFlat = tmid - leftWidth;
					copyFlat (me, startOfFlat, endOfFlat, thee.get(), startOfFlat);
					copyFall (me, endOfFlat, tmid, thee.get(), endOfFlat);
				} else if (! rightVoiced) {
					double startOfFlat = tmid + rightWidth;
					double endOfFlat = ( i == target -> nt ? tright : (tmid + tright) / 2.0 );
					copyRise (me, tmid, startOfFlat, thee.get(), startOfFlat);
					copyFlat (me, startOfFlat, endOfFlat, thee.get(), startOfFlat);
				}
			} else {
				double startOfFlat = ( i == 1 ? tleft : (tleft + tmid) / 2.0 );
				double endOfFlat = ( i == target -> nt ? tright : (tmid + tright) / 2.0 );
				copyFlat (me, startOfFlat, endOfFlat, thee.get(), startOfFlat);
			}
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not manipulated.");
	}
}
Exemplo n.º 3
0
void PointProcess_removePointNear (PointProcess me, double t) {
	PointProcess_removePoint (me, PointProcess_getNearestIndex (me, t));
}
Exemplo n.º 4
0
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.");
	}
}