void LPC_Frame_into_Tube_Frame_area (LPC_Frame me, Tube_Frame thee) { struct structTube_Frame rc_struct = { 0 }; Tube_Frame rc = & rc_struct; Tube_Frame_init (rc, my nCoefficients, thy length); LPC_Frame_into_Tube_Frame_rc (me, rc); Tube_Frames_rc_into_area (rc, thee); rc -> destroy (); }
int LPC_Frame_into_Tube_Frame_area (LPC_Frame me, Tube_Frame thee) { struct structTube_Frame rc_struct = { 0 }; Tube_Frame rc = & rc_struct; int status; memset (& rc_struct, 0, sizeof(rc_struct)); status = Tube_Frame_init (rc, my nCoefficients, thy length) && LPC_Frame_into_Tube_Frame_rc (me, rc) && Tube_Frames_rc_into_area (rc, thee); Tube_Frame_destroy (rc); return status; }
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; } }
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; }