Пример #1
0
static LPC _Sound_to_LPC (Sound me, int predictionOrder, double analysisWidth, double dt,
                          double preEmphasisFrequency, int method, double tol1, double tol2) {
	double t1, samplingFrequency = 1.0 / my dx;
	double windowDuration = 2 * analysisWidth; /* gaussian window */
	long nFrames, frameErrorCount = 0;

	if (floor (windowDuration / my dx) < predictionOrder + 1) Melder_throw ("Analysis window duration too short.\n"
		        "For a prediction order of ", predictionOrder, " the analysis window duration has to be greater than ", my dx * (predictionOrder + 1),
		        "Please increase the analysis window duration or lower the prediction order.");
	// Convenience: analyse the whole sound into one LPC_frame
	if (windowDuration > my dx * my nx) {
		windowDuration = my dx * my nx;
	}
	Sampled_shortTermAnalysis (me, windowDuration, dt, & nFrames, & t1);
	autoSound sound = Data_copy (me);
	autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency);
	autoSound window = Sound_createGaussian (windowDuration, samplingFrequency);
	autoLPC thee = LPC_create (my xmin, my xmax, nFrames, dt, t1, predictionOrder, my dx);

	autoMelderProgress progress (L"LPC analysis");

	if (preEmphasisFrequency < samplingFrequency / 2) {
		Sound_preEmphasis (sound.peek(), preEmphasisFrequency);
	}

	for (long i = 1; i <= nFrames; i++) {
		LPC_Frame lpcframe = (LPC_Frame) & thy d_frames[i];
		double t = Sampled_indexToX (thee.peek(), i);
		LPC_Frame_init (lpcframe, predictionOrder);
		Sound_into_Sound (sound.peek(), sframe.peek(), t - windowDuration / 2);
		Vector_subtractMean (sframe.peek());
		Sounds_multiply (sframe.peek(), window.peek());
		if (method == LPC_METHOD_AUTO) {
			if (! Sound_into_LPC_Frame_auto (sframe.peek(), lpcframe)) {
				frameErrorCount++;
			}
		} else if (method == LPC_METHOD_COVAR) {
			if (! Sound_into_LPC_Frame_covar (sframe.peek(), lpcframe)) {
				frameErrorCount++;
			}
		} else if (method == LPC_METHOD_BURG) {
			if (! Sound_into_LPC_Frame_burg (sframe.peek(), lpcframe)) {
				frameErrorCount++;
			}
		} else if (method == LPC_METHOD_MARPLE) {
			if (! Sound_into_LPC_Frame_marple (sframe.peek(), lpcframe, tol1, tol2)) {
				frameErrorCount++;
			}
		}
		if ( (i % 10) == 1) {
			Melder_progress ( (double) i / nFrames, L"LPC analysis of frame ",
			                   Melder_integer (i), L" out of ", Melder_integer (nFrames), L".");
		}
	}
	return thee.transfer();
}
Пример #2
0
autoLPC Cepstrumc_to_LPC (Cepstrumc me) {
	try {
		autoLPC thee = LPC_create (my xmin, my xmax, my nx, my dx, my x1,
		                           my maxnCoefficients, 1.0 / my samplingFrequency);
		for (long i = 1; i <= my nx; i++) {
			LPC_Frame_init (& thy d_frames[i], my frame[i].nCoefficients);
			Cepstrumc_Frame_into_LPC_Frame (& my frame[i], & thy d_frames[i]);
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U":no LPC created.");
	}
}
Пример #3
0
LPC Formant_to_LPC (Formant me, double samplingPeriod) {
	try {
		autoLPC thee = LPC_create (my xmin, my xmax, my nx, my dx, my x1, 2 * my maxnFormants, samplingPeriod);

		for (long i = 1; i <= my nx; i++) {
			Formant_Frame f = & my d_frames[i];
			LPC_Frame lpc = & thy d_frames[i];
			long m = 2 * f -> nFormants;

			LPC_Frame_init (lpc, m);
			Formant_Frame_into_LPC_Frame (f, lpc, samplingPeriod);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no LPC created.");
	}
}
Пример #4
0
LPC LFCC_to_LPC (LFCC me, long numberOfCoefficients) {
	try {
		if (numberOfCoefficients < 1) {
			numberOfCoefficients = my maximumNumberOfCoefficients;
		}
		numberOfCoefficients = MIN (numberOfCoefficients, my maximumNumberOfCoefficients);
		autoLPC thee = LPC_create (my xmin, my xmax, my nx, my dx, my x1, numberOfCoefficients, 0.5 / my fmax);

		for (long i = 1; i <= my nx; i++) {
			LPC_Frame_init (& thy d_frames[i], numberOfCoefficients);
			CC_Frame_into_LPC_Frame (& my frame[i], & thy d_frames[i]);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": no LPC created.");
	}
}
Пример #5
0
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.");
	}
}
Пример #6
0
double LPC_Frame_getVTL_wakita (LPC_Frame me, double samplingPeriod, double refLength) {
	struct structLPC_Frame lpc_struct;
	LPC_Frame lpc = & lpc_struct;
	struct structFormant_Frame f_struct;
	Formant_Frame f = & f_struct;
	struct structTube_Frame rc_struct, af_struct;
	Tube_Frame rc = & rc_struct, af = & af_struct;
	try {
		long m = my nCoefficients;
		double length, dlength = 0.001, wakita_length = NUMundefined;
		double varMin = 1e308;

		memset (& lpc_struct, 0, sizeof (lpc_struct));
		memset (& f_struct, 0, sizeof (f_struct));
		memset (& rc_struct, 0, sizeof (rc_struct));
		memset (& af_struct, 0, sizeof (af_struct));


		LPC_Frame_init (lpc, m);
		Tube_Frame_init (rc, m, refLength);
		Tube_Frame_init (af, m, refLength);

		// Step 2

		LPC_Frame_into_Formant_Frame (me, f, samplingPeriod, 0);

		// LPC_Frame_into_Formant_Frame performs the Formant_Frame_init !!

		if (f -> nFormants < 1) {
			Melder_throw (U"Not enough formants.");
		}

		double *area = af -> c;
		double lmin = length = 0.10;
		double plength = refLength;
		while (length <= 0.25) {
			// Step 3

			double fscale = plength / length;
			for (long i = 1; i <= f -> nFormants; i++) {
				f -> formant[i].frequency *= fscale;
				f -> formant[i].bandwidth *= fscale;
			}

			/*
			20000125: Bovenstaande schaling van f1/b1 kan ook gedaan worden door
			MGfb_to_a (f, b, nf, samplingFrequency*length/refLength, a1)
			De berekening is extreem gevoelig voor de samplefrequentie: een zelfde
			stel f,b waardes geven andere lengtes afhankelijk van Fs. Ook het
			weglaten van een hogere formant heeft consekwenties.
			De refLength zou eigenlijk vast moeten liggen op
			refLength=c*aantalFormanten/Fs waarbij c=340 m/s (geluidssnelheid).
			Bij Fs=10000 zou aantalFormanten=5 zijn en refLength -> 0.17 m
			*/

			// step 4

			Formant_Frame_into_LPC_Frame (f, lpc, samplingPeriod);

			// step 5

			rc -> length = length;
			LPC_Frame_into_Tube_Frame_rc (lpc, rc);

			// step 6.1

			Tube_Frames_rc_into_area (rc, af);

			// step 6.2 Log(areas)

			double logSum = 0.0;
			for (long i = 1; i <= af -> nSegments; i++) {
				area[i] = log (area[i]);
				logSum += area[i];
			}

			// step 6.3 and 7
			double var = 0.0;
			for (long i = 1; i <= af -> nSegments; i++) {
				double delta = area[i] - logSum / af -> nSegments;
				var += delta * delta;
			}

			if (var < varMin) {
				lmin = length; varMin = var;
			}
			plength = length;
			length += dlength;
		}

		wakita_length = lmin;
		f -> destroy ();
		lpc -> destroy ();
		rc -> destroy ();
		af -> destroy ();
		return wakita_length;
	} catch (MelderError) {
		f -> destroy ();
		lpc -> destroy ();
		rc -> destroy ();
		af -> destroy ();
		return NUMundefined;
	}
}
Пример #7
0
double LPC_Frame_getVTL_wakita (LPC_Frame me, double samplingPeriod, double refLength)
{
	struct structLPC_Frame lpc_struct;
	LPC_Frame lpc = & lpc_struct;
	struct structFormant_Frame f_struct;
	Formant_Frame f = & f_struct;
	struct structTube_Frame rc_struct, af_struct;
	Tube_Frame rc = & rc_struct, af = & af_struct;
	long i, m = my nCoefficients;
	double lmin, length, dlength = 0.001, plength, wakita_length = NUMundefined; 
	double *area, var, varMin = 1e38, logSum;
	double fscale = 1;
	
	memset(& lpc_struct, 0, sizeof(lpc_struct));
	memset(& f_struct, 0, sizeof(f_struct));
	memset(& rc_struct, 0, sizeof(rc_struct));
	memset(& af_struct, 0, sizeof(af_struct));
	
	
	if (! LPC_Frame_init  (lpc, m) || 
		! Tube_Frame_init (rc, m, refLength) ||
		! Tube_Frame_init (af, m, refLength) ||
	
		/*
			Step 2
		*/
		
		! LPC_Frame_into_Formant_Frame (me, f, samplingPeriod, 0) ||
		
		/*
			LPC_Frame_into_Formant_Frame performs the Formant_Frame_init !! 
		*/
		
		f -> nFormants < 1) goto end;
	
	area = af -> c;
	lmin = length = 0.10;
	plength = refLength;	
	while (length <= 0.25)
	{
		/* Step 3 */
		
		fscale = plength / length;
		for (i = 1; i <= f -> nFormants; i++)
		{
			f -> formant[i].frequency *= fscale;
			f -> formant[i].bandwidth *= fscale; 
		}
		
		/*
		20000125: Bovenstaande schaling van f1/b1 kan ook gedaan worden door
		MGfb_to_a (f, b, nf, samplingFrequency*length/refLength, a1)
		De berekening is extreem gevoelig voor de samplefrequentie: een zelfde
		stel f,b waardes geven andere lengtes afhankelijk van Fs. Ook het
		weglaten van een hogere formant heeft consekwenties.
		De refLength zou eigenlijk vast moeten liggen op
		refLength=c*aantalFormanten/Fs waarbij c=340 m/s (geluidssnelheid).
		Bij Fs=10000 zou aantalFormanten=5 zijn en refLength -> 0.17 m
		*/
		
		/* step 4 */
		
		if (! Formant_Frame_into_LPC_Frame (f, lpc, samplingPeriod)) goto end;
		
		/* step 5 */
		
		rc -> length = length;
		if (! LPC_Frame_into_Tube_Frame_rc (lpc, rc)) goto end;
		
		/* step 6.1 */
			
		if (! Tube_Frames_rc_into_area (rc, af)) goto end;
		
		/* step 6.2 Log(areas) */
		
		for (logSum = 0, i = 1; i <= af -> nSegments; i++)
		{
			area[i] = log (area[i]);
			logSum += area[i];
		}
		
		/* step 6.3 and 7*/
		
		for (var = 0, i = 1; i <= af -> nSegments; i++)
		{
			double delta = area[i] - logSum / af -> nSegments;
			var += delta * delta;
		}
		
		if (var < varMin)
		{
			lmin = length; varMin = var;
		}
		plength = length;
		length += dlength;
	}
	
	wakita_length = lmin;
	
end:

	Formant_Frame_destroy (f); 
	LPC_Frame_destroy (lpc);
	Tube_Frame_destroy (rc);
	Tube_Frame_destroy (af);
	
	return wakita_length;
}