Exemplo n.º 1
0
static void Run(const SUttProcessor *self, SUtterance *utt,
				s_erc *error)
{
	SG2P *g2p = NULL;
	SLexicon *lexicon = NULL;
	SAddendum *addendum = NULL;
	SSyllabification *syllab = NULL;
	const SRelation *wordRel;
	SRelation *syllableRel = NULL;
	SRelation *sylStructRel = NULL;
	SRelation *segmentRel = NULL;
	SItem *wordItem;
	char *downcase_word;
	SList *phones;
	s_bool syllabified;
	SList *syllablesPhones;
	SItem *sylStructureWordItem;
	SItem *syllableItem;
	SItem *sylStructSylItem;
	SItem *segmentItem;
	SIterator *sylItr = NULL;
	SIterator *phoneItr = NULL;
	const SObject *phone;
	s_bool is_present;


	S_CLR_ERR(error);
	s_get_lexical_objects(self, utt, &g2p, &lexicon, &addendum, &syllab, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"s_get_lexical_objects\" failed"))
		goto quit_error;

	/* we require the word relation */
	is_present = SUtteranceRelationIsPresent(utt, "Word", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceRelationIsPresent\" failed"))
		goto quit_error;

	if (!is_present)
	{
		S_CTX_ERR(error, S_FAILURE,
				  "Run",
				  "Failed to find 'Word' relation in utterance");
		goto quit_error;
	}

	wordRel = SUtteranceGetRelation(utt, "Word", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceGetRelation\" failed"))
		goto quit_error;

	/* create relations */
	syllableRel = SUtteranceNewRelation(utt, "Syllable", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceNewRelation\" failed"))
		goto quit_error;

	sylStructRel = SUtteranceNewRelation(utt, "SylStructure", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceNewRelation\" failed"))
		goto quit_error;

	segmentRel = SUtteranceNewRelation(utt, "Segment", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceNewRelation\" failed"))
		goto quit_error;

	/* start at the first item in the word relation, cast away
	 * const, we want to add daughter items.
	 * iterate over the word relation and fill in the
	 * phones and the associated structure.
	 */
	wordItem = (SItem*)SRelationHead(wordRel, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SRelationHead\" failed"))
		goto quit_error;

	while (wordItem != NULL)
	{
		/* get word and downcase it */
		downcase_word = s_strlwr(s_strdup(SItemGetName(wordItem, error), error), error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Failed to down-case word item"))
			goto quit_error;

		if  (downcase_word == NULL || s_strcmp(downcase_word, "", error) == 0)
			goto continue_cycle;

		phones = NULL;
		syllabified = FALSE;

		/* get phone sequence for word */
		if (addendum != NULL)
		{
			phones = S_ADDENDUM_CALL(addendum, get_word)(addendum,
														 downcase_word,
														 NULL,
														 &syllabified,
														 error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to method \"get_word\" (SAddendum) failed"))
				goto quit_error;
		}

		if ((phones == NULL) && (lexicon != NULL))
		{
			phones = S_LEXICON_CALL(lexicon, get_word)(lexicon,
													   downcase_word,
													   NULL,
													   &syllabified,
													   error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to method \"get_word\" (SLexicon) failed"))
				goto quit_error;
		}

		if ((phones == NULL) && (g2p != NULL))
		{
			phones = S_G2P_CALL(g2p, apply)(g2p, downcase_word, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to method \"apply\" (SG2P) failed"))
				goto quit_error;
		}

		if (phones == NULL)
		{
			S_CTX_ERR(error, S_FAILURE,
					  "Run",
					  "Failed to get phone sequence for word '%s'", downcase_word);
			S_FREE(downcase_word);
			continue;
		}

		S_FREE(downcase_word);

		/* syllabify phone sequence */
		if (syllabified == FALSE)
		{
			if (syllab != NULL)
			{
				syllablesPhones = S_SYLLABIFICATION_CALL(syllab, syllabify)(syllab,
																			wordItem,
																			phones,
																			error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to method \"syllabify\" failed"))
					goto quit_error;

				S_DELETE(phones, "Run", error);
			}
			else
			{
				syllablesPhones = S_LIST(S_NEW(SListList, error));
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Failed to create new 'SList' object"))
					goto quit_error;

				SListAppend(syllablesPhones, S_OBJECT(phones), error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to \"SListAppend\" failed"))
					goto quit_error;
			}
		}
		else
			syllablesPhones = (SList*)phones;

		/* create new syllable structure word item, shares content
		 * with word item.
		 */
		sylStructureWordItem = SRelationAppend(sylStructRel, wordItem, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Call to \"SRelationAppend\" failed"))
			goto quit_error;

		/* iterate over syllables */
		sylItr = S_ITERATOR_GET(syllablesPhones, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Call to \"S_ITERATOR_GET\" failed"))
			goto quit_error;

		while (sylItr != NULL)
		{
			/* new item in syllable relation */
			syllableItem = SRelationAppend(syllableRel, NULL, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SRelationAppend\" failed"))
				goto quit_error;

			SItemSetName(syllableItem, "syl", error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SItemSetName\" failed"))
				goto quit_error;

			/* daughter of above item, but in SylStructure */
			sylStructSylItem = SItemAddDaughter(sylStructureWordItem, syllableItem, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SItemAddDaughter\" failed"))
				goto quit_error;

			/* iterate over phones and add segments */
			phoneItr = S_ITERATOR_GET((SList*)SIteratorObject(sylItr, error), error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"S_ITERATOR_GET/SIteratorObject\" failed"))
				goto quit_error;

			while (phoneItr != NULL)
			{
				phone = SIteratorObject(phoneItr, error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to \"SIteratorObject\" failed"))
					goto quit_error;

				segmentItem = SRelationAppend(segmentRel, NULL, error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to \"SRelationAppend\" failed"))
					goto quit_error;

				SItemSetName(segmentItem, SObjectGetString(phone, error), error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to \"SItemSetName/SObjectGetString\" failed"))
					goto quit_error;

				SItemAddDaughter(sylStructSylItem, segmentItem, error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to \"SItemAddDaughter\" failed"))
					goto quit_error;

				phoneItr = SIteratorNext(phoneItr);
			}


			sylItr = SIteratorNext(sylItr);
		}

		S_DELETE(syllablesPhones, "Run", error);
continue_cycle:
		wordItem = SItemNext(wordItem, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Call to \"SItemNext\" failed"))
			goto quit_error;
	}

	/* here all is OK */
	return;


	/* error clean-up code */
quit_error:
	if (syllableRel != NULL)
	{
		SUtteranceDelRelation(utt, "Syllable", error);
		S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceDelRelation\" failed");
	}

	if (sylStructRel != NULL)
	{
		SUtteranceDelRelation(utt, "SylStructure", error);
		S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceDelRelation\" failed");
	}

	if (segmentRel != NULL)
	{
		SUtteranceDelRelation(utt, "Segment", error);
		S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceDelRelation\" failed");
	}

	if (sylItr != NULL)
		S_DELETE(sylItr, "Run", error);

	if (phoneItr != NULL)
		S_DELETE(phoneItr, "Run", error);

	self = NULL;
}
Exemplo n.º 2
0
static void Run(const SUttProcessor *self, SUtterance *utt,
				s_erc *error)
{
	const SRelation *wordRel;
	SItem *wordItem;
	const SItem *tokenItem;
	s_bool is_present;
	const char *end_punc;
	SRelation *phraseRelation = NULL;
	SItem *phraseItem = NULL;
	const char *post_punc;
	SRelation *sentenceRelation = NULL;
	SItem *sentenceItem = NULL;


	S_CLR_ERR(error);

	/* we require the word relation */
	is_present = SUtteranceRelationIsPresent(utt, "Word", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceRelationIsPresent\" failed"))
		goto quit_error;

	if (!is_present)
	{
		S_CTX_ERR(error, S_FAILURE,
				  "Run",
				  "Failed to find 'Word' relation in utterance");
		goto quit_error;
	}

	wordRel = SUtteranceGetRelation(utt, "Word", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceGetRelation\" failed"))
		goto quit_error;

	/* get phrasing symbols */
	s_get_phrasing_symbols(self, &end_punc, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"s_get_phrasing_symbols\" failed"))
		goto quit_error;

	/* create Phrase relation */
	phraseRelation = SUtteranceNewRelation(utt, "Phrase", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceNewRelation\" failed"))
		goto quit_error;

	/* create Sentence relation */
	sentenceRelation = SUtteranceNewRelation(utt, "Sentence", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceNewRelation\" failed"))
		goto quit_error;

	/* start at the first item in the word relation, cast away
	 * const, we want to add daughter items
	 */
	wordItem = (SItem*)SRelationHead(wordRel, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SRelationHead\" failed"))
		goto quit_error;

	while (wordItem != NULL)
	{
		SItem *lastWordInToken;
		SItem *wordAsToken;


		if (phraseItem == NULL)
		{
			/* if phrase item is NULL, create a new phrase item (NULL
			 * shared content) that is appended to phrase
			 * relation. Will happen in first pass.
			 */
			sentenceItem = SRelationAppend(sentenceRelation, NULL, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SRelationAppend\" failed"))
				goto quit_error;

			/* Added on top a sentence item, for now is one on one with the phrase item
			 * */
			phraseItem = SRelationAppend(phraseRelation, NULL, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SRelationAppend\" failed"))
				goto quit_error;

			/* add an item name, NB, no break */
			SItemSetString(phraseItem, "name", "NB", error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SItemSetString\" failed"))
				goto quit_error;

			SItemAddDaughter(sentenceItem, phraseItem, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SItemAddDaughter\" failed"))
				goto quit_error;
		}

		/* Create a daughter item for the phrase item. Shared content
		 * is the word item.
		 */
		SItemAddDaughter(phraseItem, wordItem, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Call to \"SItemAddDaughter\" failed"))
			goto quit_error;

		/* get word as in Token relation */
		wordAsToken = SItemAs(wordItem, "Token", error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Failed to get word item's as in Token relation"))
			goto quit_error;

		/*
		 * get word's token which is the parent of wordAsToken.
		 */
		tokenItem = SItemParent(wordAsToken, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Failed to get word item's token item"))
			goto quit_error;

		/* get last word in token */
		lastWordInToken = SItemLastDaughter(tokenItem, error);
		if (S_CHK_ERR(error, S_CONTERR,
			"Run",
		"Failed to get last daughter of token item"))
			goto quit_error;

		/* check if the next token is punctuation */
		is_present = FALSE;
		tokenItem = SItemNext(tokenItem, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Call to \"SItemNext\" failed"))
			goto quit_error;
		if (tokenItem != NULL)
		{
			is_present = SItemFeatureIsPresent(tokenItem, "IsPunctuation", error);
			if (S_CHK_ERR(error, S_CONTERR,
						"Run",
						"Call to \"SItemFeatureIsPresent\" failed"))
				goto quit_error;
			if (is_present)
			{
				sint32 value = SItemGetInt(tokenItem, "IsPunctuation", error);
				if (S_CHK_ERR(error, S_CONTERR,
							"Run",
							"Call to \"SItemGetInt\" failed"))
					goto quit_error;
				is_present = (value > 0);
			}
		}

		if ((is_present) && (wordAsToken == lastWordInToken))
		{
			char *ptr;


			post_punc = SItemGetName(tokenItem, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"SItemGetName\" failed"))
				goto quit_error;

			/* check if it is in the end_punc list */
			ptr = s_strpbrk(post_punc, end_punc, error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "Run",
						  "Call to \"s_strpbrk\" failed"))
				goto quit_error;

			if (ptr != NULL)
			{
				/* add a phrase break */
				SItemSetString(phraseItem, "name", "BB", error);
				if (S_CHK_ERR(error, S_CONTERR,
							  "Run",
							  "Call to \"SItemSetString\" failed"))
					goto quit_error;

				/* set to NULL so that a new phrase item is created */
				phraseItem = NULL;
			}
		}

		wordItem = SItemNext(wordItem, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "Run",
					  "Call to \"SItemNext\" failed"))
			goto quit_error;
	}

	/* here all is OK */
	return;

	/* error clean-up code */
quit_error:
	if (phraseRelation != NULL)
	{
		SUtteranceDelRelation(utt, "Phrase", error);
		S_CHK_ERR(error, S_CONTERR,
				  "Run",
				  "Call to \"SUtteranceDelRelation\" failed");
	}
}