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; }
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"); } }