Table espeakdata_voices_to_Table (FilesInMemory me) {
	try {
		autoTable thee = Table_createWithColumnNames (my size, U"id name");
		for (long ifile = 1; ifile <= my size; ifile++) {
			FileInMemory fim = (FileInMemory) my item[ifile];
			Table_setStringValue (thee.peek(), ifile, 1, fim -> d_id);
			const char *p = strstr (fim -> d_data, "name");
			if (p == NULL) continue;
			// copy the name part to the following new line
			char buf[40], *bufp = buf;
			long len = 0;
			while ((*bufp++ = *p++) != '\n' && len < 39) { len++; }
			// remove trailing white space
			*bufp = 0;
			while (ESPEAK_ISSPACE (buf[len]) && len > 0) {
				buf[len] = 0; len--;
			}
			// skip leading white space
			bufp = & buf[4];
			while (ESPEAK_ISSPACE (*bufp)) { *bufp++; }
			Table_setStringValue (thee.peek(), ifile, 2, Melder_peek8to32 (bufp));
			TableRow row = static_cast <TableRow> (thy rows -> item [ifile]);
			wint_t c0 = row -> cells [2]. string[0];
			row -> cells [2]. string[0] = towupper (c0);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (U"Espeakdata: voice table not initialized.");
	}
}
autoTable PairDistribution_to_Table (PairDistribution me) {
	try {
		autoTable thee = Table_createWithColumnNames (my pairs -> size, U"string1 string2 weight");
		for (long ipair = 1; ipair <= my pairs -> size; ipair ++) {
			PairProbability prob = static_cast <PairProbability> (my pairs -> item [ipair]);
			Table_setStringValue (thee.peek(), ipair, 1, prob -> string1);
			Table_setStringValue (thee.peek(), ipair, 2, prob -> string2);
			Table_setNumericValue (thee.peek(), ipair, 3, prob -> weight);
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not converted to Table.");
	}
}
Table PowerCepstrogram_to_Table_hillenbrand (PowerCepstrogram me, double pitchFloor, double pitchCeiling) {
	try {
		autoTable thee = Table_createWithColumnNames (my nx, L"time quefrency cpp f0");
		autoPowerCepstrum him = PowerCepstrum_create (my ymax, my ny);
		for (long i = 1; i <= my nx; i++) {
			for (long j = 1; j <= my ny; j++) {
				his z[1][j] = my z[j][i];
			}
			double qpeak, cpp = PowerCepstrum_getPeakProminence_hillenbrand (him.peek(), pitchFloor, pitchCeiling, &qpeak);
			double time = Sampled_indexToX (me, i);
			Table_setNumericValue (thee.peek(), i, 1, time);
			Table_setNumericValue (thee.peek(), i, 2, qpeak);
			Table_setNumericValue (thee.peek(), i, 3, cpp); // Cepstrogram_getCPPS depends on this index 3!!
			Table_setNumericValue (thee.peek(), i, 4, 1.0 / qpeak);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Table with cepstral peak prominence values created.");
	}
}
Exemple #4
0
Table Cepstrogram_to_Table_cpp (Cepstrogram me, double lowestQuefrency, double highestQuefrency, int interpolation, double qstartFit, double qendFit, int method) {
	try {
		autoTable thee = Table_createWithColumnNames (my nx, L"time quefrency cpp f0");
		autoCepstrum him = Cepstrum_create (my ymin, my ymax, my ny);
		for (long i = 1; i <= my nx; i++) {
			for (long j = 1; j <= my ny; j++) {
				his z[1][j] = my z[j][i];
			}
			double qpeak, cpp = Cepstrum_getPeakProminence (him.peek(), lowestQuefrency, highestQuefrency, interpolation,
				qstartFit, qendFit, method, &qpeak);
			double time = Sampled_indexToX (me, i);
			Table_setNumericValue (thee.peek(), i, 1, time);
			Table_setNumericValue (thee.peek(), i, 2, qpeak);
			Table_setNumericValue (thee.peek(), i, 3, cpp);
			Table_setNumericValue (thee.peek(), i, 4, 1.0 / qpeak);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Table with cepstral peak prominence values created.");
	}
}
Table PowerCepstrogram_to_Table_cpp (PowerCepstrogram me, double pitchFloor, double pitchCeiling, double deltaF0, int interpolation, double qstartFit, double qendFit, int lineType, int fitMethod) {
	try {
		autoTable thee = Table_createWithColumnNames (my nx, L"time quefrency cpp f0 rnr");
		autoPowerCepstrum him = PowerCepstrum_create (my ymax, my ny);
		for (long i = 1; i <= my nx; i++) {
			for (long j = 1; j <= my ny; j++) {
				his z[1][j] = my z[j][i];
			}
			double qpeak, z, cpp = PowerCepstrum_getPeakProminence (him.peek(), pitchFloor, pitchCeiling, interpolation,
				qstartFit, qendFit, lineType, fitMethod, &qpeak);
			double rnr = PowerCepstrum_getRNR (him.peek(), pitchFloor, pitchCeiling, deltaF0);
			double time = Sampled_indexToX (me, i);
			Table_setNumericValue (thee.peek(), i, 1, time);
			Table_setNumericValue (thee.peek(), i, 2, qpeak);
			Table_setNumericValue (thee.peek(), i, 3, cpp); // Cepstrogram_getCPPS depends on this index!!
			Table_setNumericValue (thee.peek(), i, 4, 1.0 / qpeak);
			Table_setNumericValue (thee.peek(), i, 5, rnr);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Table with cepstral peak prominence values created.");
	}
}
autoSound SpeechSynthesizer_to_Sound (SpeechSynthesizer me, const char32 *text, autoTextGrid *tg, autoTable *events) {
	try {
		int fsamp = espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0, nullptr, // 5000ms
			espeakINITIALIZE_PHONEME_EVENTS|espeakINITIALIZE_PHONEME_IPA);
		if (fsamp == -1) {
			Melder_throw (U"Internal espeak error.");
		}
		int synth_flags = espeakCHARS_WCHAR;
		if (my d_inputTextFormat == SpeechSynthesizer_INPUT_TAGGEDTEXT) {
			synth_flags |= espeakSSML;
		}
		if (my d_inputTextFormat != SpeechSynthesizer_INPUT_TEXTONLY) {
			synth_flags |= espeakPHONEMES;
		}
		option_phoneme_events = espeakINITIALIZE_PHONEME_EVENTS; // extern int option_phoneme_events;
		if (my d_outputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_IPA) {
			option_phoneme_events |= espeakINITIALIZE_PHONEME_IPA;
		}

		espeak_SetParameter (espeakRATE, my d_wordsPerMinute, 0);
		espeak_SetParameter (espeakPITCH, my d_pitchAdjustment, 0);
		espeak_SetParameter (espeakRANGE, my d_pitchRange, 0);
		const char32 *voiceLanguageCode = SpeechSynthesizer_getVoiceLanguageCodeFromName (me, my d_voiceLanguageName);
		const char32 *voiceVariantCode = SpeechSynthesizer_getVoiceVariantCodeFromName (me, my d_voiceVariantName);
		espeakdata_SetVoiceByName ((const char *) Melder_peek32to8 (voiceLanguageCode), 
			(const char *) Melder_peek32to8 (voiceVariantCode));

		espeak_SetParameter (espeakWORDGAP, my d_wordgap * 100, 0); // espeak wordgap is in units of 10 ms
		espeak_SetParameter (espeakCAPITALS, 0, 0);
		espeak_SetParameter (espeakPUNCTUATION, espeakPUNCT_NONE, 0);

		espeak_SetSynthCallback (synthCallback);

		my d_events = Table_createWithColumnNames (0, U"time type type-t t-pos length a-pos sample id uniq");

		#ifdef _WIN32
                wchar_t *textW = Melder_peek32toW (text);
                espeak_Synth (textW, wcslen (textW) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me);
		#else
                espeak_Synth (text, str32len (text) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me);
		#endif
				
		espeak_Terminate ();
		autoSound thee = buffer_to_Sound (my d_wav, my d_numberOfSamples, my d_internalSamplingFrequency);

		if (my d_samplingFrequency != my d_internalSamplingFrequency) {
			thee = Sound_resample (thee.get(), my d_samplingFrequency, 50);
		}
		my d_numberOfSamples = 0; // re-use the wav-buffer
		if (tg) {
			double xmin = Table_getNumericValue_Assert (my d_events.get(), 1, 1);
			if (xmin > thy xmin) {
				xmin = thy xmin;
			}
			double xmax = Table_getNumericValue_Assert (my d_events.get(), my d_events -> rows.size, 1);
			if (xmax < thy xmax) {
				xmax = thy xmax;
			}
			autoTextGrid tg1 = Table_to_TextGrid (my d_events.get(), text, xmin, xmax);
			*tg = TextGrid_extractPart (tg1.get(), thy xmin, thy xmax, 0);
		}
		if (events) {
			Table_setEventTypeString (my d_events.get());
			*events = my d_events.move();
		}
		my d_events.reset();
		return thee;
	} catch (MelderError) {
		espeak_Terminate ();
		Melder_throw (U"Text not played.");
	}
}
autoTable IntervalTiers_to_Table_textAlignmentment (IntervalTier target, IntervalTier source, EditCostsTable costs) {
	try {
		long numberOfTargetIntervals = target -> intervals.size;
		long numberOfSourceIntervals = source -> intervals.size;
		autoNUMvector<long> targetOrigin (1, numberOfTargetIntervals);
		autoNUMvector<long> sourceOrigin (1, numberOfSourceIntervals);
		autoStrings targets = IntervalTier_to_Strings_withOriginData (target, targetOrigin.peek());
		autoStrings sources = IntervalTier_to_Strings_withOriginData (source, sourceOrigin.peek());
		autoEditDistanceTable edit = EditDistanceTable_create (targets.peek(), sources.peek());
		if (costs != 0) {
			EditDistanceTable_setEditCosts (edit.peek(), costs);
			EditDistanceTable_findPath (edit.peek(), nullptr);
		}
		long pathLength = edit -> warpingPath -> pathLength;
		autoTable thee = Table_createWithColumnNames (pathLength - 1, U"targetInterval targetText targetStart targetEnd sourceInterval sourceText sourceStart sourceEnd operation");
		for (long i = 2; i <= pathLength; i++) {
			structPairOfInteger p = edit -> warpingPath -> path[i];
			structPairOfInteger p1 = edit -> warpingPath -> path[i - 1];
			double targetStart = NUMundefined, targetEnd =  NUMundefined;
			double sourceStart = NUMundefined, sourceEnd =  NUMundefined;
			const char32 * targetText = U"", *sourceText = U"";
			long targetInterval = p.y > 1 ? targetOrigin[p.y - 1] : 0;
			long sourceInterval = p.x > 1 ? sourceOrigin[p.x - 1] : 0;
			if (targetInterval > 0) {
				TextInterval ti = target -> intervals.at [targetInterval];
				targetStart = ti -> xmin;
				targetEnd =  ti -> xmax;
				targetText = ti -> text;
			}
			if (sourceInterval > 0) {
				TextInterval ti = source -> intervals.at [sourceInterval];
				sourceStart = ti -> xmin;
				sourceEnd =  ti -> xmax;
				sourceText = ti -> text;
			}
			long irow = i - 1;
			if (p.y == p1.y) { // deletion
				Table_setNumericValue (thee.peek(), irow, 1, 0);
				Table_setStringValue  (thee.peek(), irow, 2, U"");
				Table_setNumericValue (thee.peek(), irow, 3, NUMundefined);
				Table_setNumericValue (thee.peek(), irow, 4, NUMundefined);
				Table_setNumericValue (thee.peek(), irow, 5, sourceInterval);
				Table_setStringValue  (thee.peek(), irow, 6, sourceText);
				Table_setNumericValue (thee.peek(), irow, 7, sourceStart);
				Table_setNumericValue (thee.peek(), irow, 8, sourceEnd);
				Table_setStringValue  (thee.peek(), irow, 9, U"d");
			} else if (p.x == p1.x) { // insertion
				Table_setNumericValue (thee.peek(), irow, 1, targetInterval);
				Table_setStringValue  (thee.peek(), irow, 2, targetText);
				Table_setNumericValue (thee.peek(), irow, 3, targetStart);
				Table_setNumericValue (thee.peek(), irow, 4, targetEnd);
				Table_setNumericValue (thee.peek(), irow, 5, 0);
				Table_setStringValue  (thee.peek(), irow, 6, U"");
				Table_setNumericValue (thee.peek(), irow, 7, NUMundefined);
				Table_setNumericValue (thee.peek(), irow, 8, NUMundefined);
				Table_setStringValue  (thee.peek(), irow, 9, U"i");
			} else { // substitution ?
				Table_setNumericValue (thee.peek(), irow, 1, targetInterval);
				Table_setStringValue  (thee.peek(), irow, 2, targetText);
				Table_setNumericValue (thee.peek(), irow, 3, targetStart);
				Table_setNumericValue (thee.peek(), irow, 4, targetEnd);
				Table_setNumericValue (thee.peek(), irow, 5, sourceInterval);
				Table_setStringValue  (thee.peek(), irow, 6, sourceText);
				Table_setNumericValue (thee.peek(), irow, 7, sourceStart);
				Table_setNumericValue (thee.peek(), irow, 8, sourceEnd);
				Table_setStringValue  (thee.peek(), irow, 9, Melder_equ (targetText, sourceText) ? U" " : U"s");
			}
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (target, U" and ", source, U" not aligned.");
	}
}