Formant LPC_to_Formant (LPC me, double margin) {
	try {
		double samplingFrequency = 1.0 / my samplingPeriod;
		long nmax = my maxnCoefficients, err = 0;
		long interval = nmax > 20 ? 1 : 10;

		if (nmax > 99) {
			Melder_throw ("We cannot find the roots of a polynomial of order > 99.");
		}
		if (margin >= samplingFrequency / 4) {
			Melder_throw ("Margin must be smaller than ", samplingFrequency / 4, ".");
		}

		autoFormant thee = Formant_create (my xmin, my xmax, my nx, my dx, my x1, (nmax + 1) / 2);

		autoMelderProgress progress (L"LPC to Formant");

		for (long i = 1; i <= my nx; i++) {
			Formant_Frame formant = & thy d_frames[i];
			LPC_Frame lpc = & my d_frames[i];

			// Initialisation of Formant_Frame is taken care of in Roots_into_Formant_Frame!

			try {
				LPC_Frame_into_Formant_Frame (lpc, formant, my samplingPeriod, margin);
			} catch (MelderError) {
				Melder_clearError();
				err++;
			}

			if ( (interval == 1 || (i % interval) == 1)) {
				Melder_progress ( (double) i / my nx, L"LPC to Formant: frame ", Melder_integer (i),
				                   L" out of ", Melder_integer (my nx), L".");
			}
		}

		Formant_sort (thee.peek());
		if (err > 0) {
			Melder_warning (Melder_integer (err), L" formant frames out of ", Melder_integer (my nx), L" suspect.");
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Formant created.");
	}
}
Exemple #2
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;
	}
}
Exemple #3
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;
}