Beispiel #1
0
Ltas PointProcess_Sound_to_Ltas_harmonics (PointProcess pulses, Sound sound,
	long maximumHarmonic,
	double shortestPeriod, double longestPeriod, double maximumPeriodFactor)
{
	try {
		long numberOfPeriods = pulses -> nt - 2;
		autoLtas ltas = Ltas_create (maximumHarmonic, 1.0);
		ltas -> xmax = maximumHarmonic;
		if (numberOfPeriods < 1)
			Melder_throw ("There are no periods in the point process.");
		autoMelderProgress progress (L"LTAS (harmonics) analysis...");
		for (long ipulse = 2; ipulse < pulses -> nt; ipulse ++) {
			double leftInterval = pulses -> t [ipulse] - pulses -> t [ipulse - 1];
			double rightInterval = pulses -> t [ipulse + 1] - pulses -> t [ipulse];
			double intervalFactor = leftInterval > rightInterval ? leftInterval / rightInterval : rightInterval / leftInterval;
			Melder_progress ((double) ipulse / pulses -> nt, L"Sound & PointProcess: To Ltas: pulse ", Melder_integer (ipulse), L" out of ", Melder_integer (pulses -> nt));
			if (leftInterval >= shortestPeriod && leftInterval <= longestPeriod &&
				rightInterval >= shortestPeriod && rightInterval <= longestPeriod &&
				intervalFactor <= maximumPeriodFactor)
			{
				/*
				 * We have a period! Compute the spectrum.
				 */
				long localMaximumHarmonic;
				autoSound period = Sound_extractPart (sound,
					pulses -> t [ipulse] - 0.5 * leftInterval, pulses -> t [ipulse] + 0.5 * rightInterval,
					kSound_windowShape_RECTANGULAR, 1.0, FALSE);
				autoSpectrum spectrum = Sound_to_Spectrum (period.peek(), FALSE);
				localMaximumHarmonic = maximumHarmonic < spectrum -> nx ? maximumHarmonic : spectrum -> nx;
				for (long iharm = 1; iharm <= localMaximumHarmonic; iharm ++) {
					double realPart = spectrum -> z [1] [iharm];
					double imaginaryPart = spectrum -> z [2] [iharm];
					double energy = (realPart * realPart + imaginaryPart * imaginaryPart) * 2.0 * spectrum -> dx;
					ltas -> z [1] [iharm] += energy;
				}
			} else {
				numberOfPeriods -= 1;
			}
		}
		if (numberOfPeriods < 1)
			Melder_throw (L"There are no periods in the point process.");
		for (long iharm = 1; iharm <= ltas -> nx; iharm ++) {
			if (ltas -> z [1] [iharm] == 0.0) {
				ltas -> z [1] [iharm] = -300.0;
			} else {
				double energyInThisBand = ltas -> z [1] [iharm];
				double powerInThisBand = energyInThisBand / (sound -> xmax - sound -> xmin);
				ltas -> z [1] [iharm] = 10.0 * log10 (powerInThisBand / 4.0e-10);
			}
		}
		return ltas.transfer();
	} catch (MelderError) {
		Melder_throw (sound, " & ", pulses, ": LTAS analysis (harmonics) not performed.");
	}
}
Beispiel #2
0
Ltas PointProcess_Sound_to_Ltas (PointProcess pulses, Sound sound,
	double maximumFrequency, double bandWidth,
	double shortestPeriod, double longestPeriod, double maximumPeriodFactor)
{
	Ltas ltas = NULL, numbers = NULL;
	Sound period = NULL;
	Spectrum spectrum = NULL;
	long numberOfPeriods = pulses -> nt - 2, ipulse, ifreq, iband, totalNumberOfEnergies = 0;
	ltas = Ltas_create (maximumFrequency / bandWidth, bandWidth); cherror
	ltas -> xmax = maximumFrequency;
	numbers = (structLtas *)Data_copy (ltas);
	if (numberOfPeriods < 1) error1 (L"Cannot compute an Ltas if there are no periods in the point process.")
	for (ipulse = 2; ipulse < pulses -> nt; ipulse ++) {
		double leftInterval = pulses -> t [ipulse] - pulses -> t [ipulse - 1];
		double rightInterval = pulses -> t [ipulse + 1] - pulses -> t [ipulse];
		double intervalFactor = leftInterval > rightInterval ? leftInterval / rightInterval : rightInterval / leftInterval;
		Melder_progress4 ((double) ipulse / pulses -> nt, L"Sound & PointProcess: To Ltas: pulse ", Melder_integer (ipulse), L" out of ", Melder_integer (pulses -> nt));
		if (leftInterval >= shortestPeriod && leftInterval <= longestPeriod &&
		    rightInterval >= shortestPeriod && rightInterval <= longestPeriod &&
		    intervalFactor <= maximumPeriodFactor)
		{
			/*
			 * We have a period! Compute the spectrum.
			 */
			period = Sound_extractPart (sound,
				pulses -> t [ipulse] - 0.5 * leftInterval, pulses -> t [ipulse] + 0.5 * rightInterval,
				kSound_windowShape_RECTANGULAR, 1.0, FALSE); cherror
			spectrum = Sound_to_Spectrum (period, FALSE); cherror
			for (ifreq = 1; ifreq <= spectrum -> nx; ifreq ++) {
				double frequency = spectrum -> xmin + (ifreq - 1) * spectrum -> dx;
				double realPart = spectrum -> z [1] [ifreq];
				double imaginaryPart = spectrum -> z [2] [ifreq];
				double energy = (realPart * realPart + imaginaryPart * imaginaryPart) * 2.0 * spectrum -> dx /* OLD: * sound -> nx */;
				iband = ceil (frequency / bandWidth);
				if (iband >= 1 && iband <= ltas -> nx) {
					ltas -> z [1] [iband] += energy;
					numbers -> z [1] [iband] += 1;
					totalNumberOfEnergies += 1;
				}
			}
			forget (spectrum);
			forget (period);
		} else {
Beispiel #3
0
Ltas PointProcess_Sound_to_Ltas (PointProcess pulses, Sound sound,
	double maximumFrequency, double bandWidth,
	double shortestPeriod, double longestPeriod, double maximumPeriodFactor)
{
	try {
		long numberOfPeriods = pulses -> nt - 2, totalNumberOfEnergies = 0;
		autoLtas ltas = Ltas_create (maximumFrequency / bandWidth, bandWidth);
		ltas -> xmax = maximumFrequency;
		autoLtas numbers = Data_copy (ltas.peek());
		if (numberOfPeriods < 1)
			Melder_throw ("Cannot compute an Ltas if there are no periods in the point process.");
		autoMelderProgress progress (L"Ltas analysis...");
		for (long ipulse = 2; ipulse < pulses -> nt; ipulse ++) {
			double leftInterval = pulses -> t [ipulse] - pulses -> t [ipulse - 1];
			double rightInterval = pulses -> t [ipulse + 1] - pulses -> t [ipulse];
			double intervalFactor = leftInterval > rightInterval ? leftInterval / rightInterval : rightInterval / leftInterval;
			Melder_progress ((double) ipulse / pulses -> nt, L"Sound & PointProcess: To Ltas: pulse ", Melder_integer (ipulse), L" out of ", Melder_integer (pulses -> nt));
			if (leftInterval >= shortestPeriod && leftInterval <= longestPeriod &&
				rightInterval >= shortestPeriod && rightInterval <= longestPeriod &&
				intervalFactor <= maximumPeriodFactor)
			{
				/*
				 * We have a period! Compute the spectrum.
				 */
				autoSound period = Sound_extractPart (sound,
					pulses -> t [ipulse] - 0.5 * leftInterval, pulses -> t [ipulse] + 0.5 * rightInterval,
					kSound_windowShape_RECTANGULAR, 1.0, FALSE);
				autoSpectrum spectrum = Sound_to_Spectrum (period.peek(), FALSE);
				for (long ifreq = 1; ifreq <= spectrum -> nx; ifreq ++) {
					double frequency = spectrum -> xmin + (ifreq - 1) * spectrum -> dx;
					double realPart = spectrum -> z [1] [ifreq];
					double imaginaryPart = spectrum -> z [2] [ifreq];
					double energy = (realPart * realPart + imaginaryPart * imaginaryPart) * 2.0 * spectrum -> dx /* OLD: * sound -> nx */;
					long iband = ceil (frequency / bandWidth);
					if (iband >= 1 && iband <= ltas -> nx) {
						ltas -> z [1] [iband] += energy;
						numbers -> z [1] [iband] += 1;
						totalNumberOfEnergies += 1;
					}
				}
			} else {
				numberOfPeriods -= 1;
			}
		}
		if (numberOfPeriods < 1)
			Melder_throw ("There are no periods in the point process.");
		for (long iband = 1; iband <= ltas -> nx; iband ++) {
			if (numbers -> z [1] [iband] == 0.0) {
				ltas -> z [1] [iband] = NUMundefined;
			} else {
				/*
				 * Each bin now contains a total energy in Pa2 sec.
				 * To convert this to power density, we
				 */
				double totalEnergyInThisBand = ltas -> z [1] [iband];
				if (0 /* i.e. if you just want to have a spectrum of the voiced parts... */) {
					double energyDensityInThisBand = totalEnergyInThisBand / ltas -> dx;
					double powerDensityInThisBand = energyDensityInThisBand / (sound -> xmax - sound -> xmin);
					ltas -> z [1] [iband] = 10.0 * log10 (powerDensityInThisBand / 4.0e-10);
				} else {
					/*
					 * And this is what we really want. The total energy has to be redistributed.
					 */
					double meanEnergyInThisBand = totalEnergyInThisBand / numbers -> z [1] [iband];
					double meanNumberOfEnergiesPerBand = (double) totalNumberOfEnergies / ltas -> nx;
					double redistributedEnergyInThisBand = meanEnergyInThisBand * meanNumberOfEnergiesPerBand;
					double redistributedEnergyDensityInThisBand = redistributedEnergyInThisBand / ltas -> dx;
					double redistributedPowerDensityInThisBand = redistributedEnergyDensityInThisBand / (sound -> xmax - sound -> xmin);
					ltas -> z [1] [iband] = 10.0 * log10 (redistributedPowerDensityInThisBand / 4.0e-10);
					/* OLD: ltas -> z [1] [iband] = 10.0 * log10 (ltas -> z [1] [iband] / numbers -> z [1] [iband] * sound -> nx);*/
				}
			}
		}
		for (long iband = 1; iband <= ltas -> nx; iband ++) {
			if (ltas -> z [1] [iband] == NUMundefined) {
				long ibandleft = iband - 1, ibandright = iband + 1;
				while (ibandleft >= 1 && ltas -> z [1] [ibandleft] == NUMundefined) ibandleft --;
				while (ibandright <= ltas -> nx && ltas -> z [1] [ibandright] == NUMundefined) ibandright ++;
				if (ibandleft < 1 && ibandright > ltas -> nx)
					Melder_throw ("Cannot create an Ltas without energy in any bins.");
				if (ibandleft < 1) {
					ltas -> z [1] [iband] = ltas -> z [1] [ibandright];
				} else if (ibandright > ltas -> nx) {
					ltas -> z [1] [iband] = ltas -> z [1] [ibandleft];
				} else {
					double frequency = ltas -> x1 + (iband - 1) * ltas -> dx;
					double fleft = ltas -> x1 + (ibandleft - 1) * ltas -> dx;
					double fright = ltas -> x1 + (ibandright - 1) * ltas -> dx;
					ltas -> z [1] [iband] = ((fright - frequency) * ltas -> z [1] [ibandleft]
						+ (frequency - fleft) * ltas -> z [1] [ibandright]) / (fright - fleft);
				}
			}
		}
		return ltas.transfer();
	} catch (MelderError) {
		Melder_throw (sound, " & ", pulses, ": LTAS analysis not performed.");
	}
}