Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stress marks to phoneme events #1700

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

rotemdan
Copy link

@rotemdan rotemdan commented Apr 5, 2023

I've added stress marks to phoneme events.

The implications of this are large for using eSpeak-ng as a phonemizer. It means that it's now possible to get accurate mappings between the phonemized word and the original word (up till now it was pretty much impossible). This is huge for many applications that use it as a side-tool.

I have tested this for several weeks now, with many languages, and it seems to work correctly and produce results that should be identical to calling espeak_TextToPhonemes when the phonemes are in IPA mode (I haven't tested Kirshenbaum phoneme names though, but they should work as well - it's just that I'm using it via Emscripten and the IPA output flag is "burned" into the code).

This is the main method I've added to output the phoneme names with stress marks:

char *WritePhMnemonicWithStress(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa, int *flags) {
	if (plist->synthflags & SFLAG_SYLLABLE) {
		unsigned char stress = plist->stresslevel;

		if (stress > 1) {
			int c = 0;

			if (stress > STRESS_IS_PRIORITY) {
				stress = STRESS_IS_PRIORITY;
			}

			if (use_ipa) {
				c = 0x2cc; // ipa, secondary stress

				if (stress > STRESS_IS_SECONDARY) {
					c = 0x02c8; // ipa, primary stress
				}
			} else {
				const char stress_chars[] = "==,,''";

				c = stress_chars[stress];
			}

			if (c != 0) {
				phon_out += utf8_out(c, phon_out);
			}
		}
	}

	return WritePhMnemonic(phon_out, ph, plist, use_ipa, flags);
}

(The local constant const char stress_chars[] = "==,,''"; is somewhat of a "hack". This should be a global constant, but I didn't want to modify other methods to use this)

That method is based, almost exactly, on a code fragment I found in GetTranslatedPhonemeString:

		if (plist->synthflags & SFLAG_SYLLABLE) {
			if ((stress = plist->stresslevel) > 1) {
				c = 0;
				if (stress > STRESS_IS_PRIORITY) stress = STRESS_IS_PRIORITY;

				if (use_ipa) {
					c = 0x2cc; // ipa, secondary stress
					if (stress > STRESS_IS_SECONDARY)
						c = 0x02c8; // ipa, primary stress
				} else
					c = stress_chars[stress];

				if (c != 0)
					buf += utf8_out(c, buf);
			}
		}

However, the way it's done now - it's a minor breaking change.

I guess it would be better to enable this feature via a flag, but I don't have sufficient knowledge of the codebase to implement something like that.

I'll give this code to you people to decide how and if you want to integrate it.

I have more code to contribute: For example: I've enhanced the Emscripten port to support events (and phoneme events in particular), and I've tested it extensively for more than 6 months now.

@sthibaul sthibaul force-pushed the add-phoneme-event-stress-marks branch from b075864 to 4e6e7c9 Compare September 3, 2023 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant