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; }
int main(int argc, char **argv) { s_erc error = S_SUCCESS; /* the syllabification can be started from the voice */ const SVoice *voice = NULL; SRelation *wordRel = NULL; SUtterance *utt = NULL; SItem *wordItem = NULL; SList *phones = NULL; SList *syllablesPhones = NULL; char* buffer = NULL; size_t buffer_size = 0; ssize_t buffer_length = 0; /* Config type will handle the command line input */ struct Config config = {0}; SPCT_PRINT_AND_WAIT("parsing options, press ENTER\n"); parse_arguments(&argc, argv, &config); SPCT_PRINT_AND_WAIT("going to initialize speect, press ENTER\n"); /* * initialize speect */ error = speect_init(NULL); if (error != S_SUCCESS) { printf("Failed to initialize Speect\n"); return 1; } SPCT_PRINT_AND_WAIT("initialized speect, loading voice, press ENTER\n"); /* load voice */ voice = s_vm_load_voice(config.voicefile, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"s_vm_load_voice\" failed")) goto quit; SPCT_PRINT_AND_WAIT("loaded voice, doing syllabification, press ENTER\n"); const SUttProcessor *uttProc = SVoiceGetUttProc(voice, "LexLookup", &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"SVoiceGetUttProc\" failed")) goto quit; utt = S_NEW(SUtterance, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"S_NEW\" failed")) goto quit; /* Utterance initialization */ SUtteranceInit(&utt, voice, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"SUtteranceInit\" failed")) goto quit; /* Create new relation */ wordRel = SUtteranceNewRelation(utt, "Word", &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"NewRelation\" failed")) goto quit; wordItem = SRelationAppend(wordRel, NULL, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"SRelationAppend\" failed")) goto quit; SItemSetName(wordItem, "", &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"SItemSetName\" failed")) goto quit; SPCT_PRINT_AND_WAIT("load syllabification function, press ENTER\n"); SSyllabification* syllab = (SSyllabification*)SVoiceGetData(voice , "syllabification", &error); if (syllab == NULL) { syllab = (SSyllabification*)SMapGetObjectDef(uttProc -> features , "_syll_func", NULL, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"SMapGetObjectDef\" failed")) goto quit; } SPCT_PRINT_AND_WAIT("everything ready to perform syllabification, press ENTER\n"); char inter_buffer[MAX_PHONEME_LENGTH+1] = {0}; buffer_length = getline(&buffer, &buffer_size, stdin); while (buffer_length != -1) { phones = S_LIST(S_NEW(SListList, &error)); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"S_NEW\" failed")) goto quit; int j = 0; while (buffer[j] != '\0') { int k; int inter_buffer_c; if (!isspace(buffer[j])) { inter_buffer[0] = buffer[j]; k = j + 1; inter_buffer_c = 1; while (!isspace(buffer[k]) && inter_buffer_c < MAX_PHONEME_LENGTH) { inter_buffer[inter_buffer_c] = buffer[k]; inter_buffer_c++; k++; } j += (inter_buffer_c - 1); inter_buffer[inter_buffer_c] = '\0'; /* for each phoneme in the line, put it in 'ph' */ SObject* ph = SObjectSetString(inter_buffer, &error); /* then add ph to the phoneme list */ SListAppend(phones, ph, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to \"SListAppend\" failed")) goto quit; } j++; } SPCT_PRINT_AND_WAIT("run syllabification on next phones string, press ENTER\n"); syllablesPhones = NULL; syllablesPhones = S_SYLLABIFICATION_CALL(syllab, syllabify)(syllab, wordItem, phones, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to method \"syllabify\" failed")) goto quit; /* PRINT LOOP */ uint32 k = 0; SIterator *itr_syllablesPhones = S_ITERATOR_GET(syllablesPhones, &error); if (S_CHK_ERR(&error, S_CONTERR, "Run", "Execution of \"S_ITERATOR_GET\" failed")) goto quit; size_t syllables_list_size = SListSize(syllablesPhones, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to method \"SListSize\" failed")) goto quit; while (itr_syllablesPhones != NULL) { const SList* syl_list = (const SList*) SIteratorObject(itr_syllablesPhones, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to method \"SIteratorObject\" failed")) goto quit; size_t syl_list_size = SListSize(syl_list, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to method \"SListSize\" failed")) goto quit; uint32 l = 0; SIterator *itr_syl_list = S_ITERATOR_GET(syl_list, &error); while (itr_syl_list != NULL) { const SObject* ph = SIteratorObject(itr_syl_list, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to method \"SIteratorObject\" failed")) goto quit; const char* phone_string = SObjectGetString(ph, &error); if (S_CHK_ERR(&error, S_CONTERR, "main", "Call to method \"SObjectGetString\" failed")) goto quit; fprintf(stdout, "%s", phone_string); if (l < syl_list_size - 1){ fprintf(stdout, " "); } itr_syl_list = SIteratorNext(itr_syl_list); l++; } if (k < syllables_list_size - 1) { fprintf(stdout, " - "); } itr_syllablesPhones = SIteratorNext(itr_syllablesPhones); k++; } fprintf(stdout, "\n"); if (syllablesPhones != NULL) S_DELETE(syllablesPhones, "main", &error); if (phones != NULL) S_DELETE(phones, "main", &error); phones = NULL; buffer_length = getline(&buffer, &buffer_size, stdin); } quit: SPCT_PRINT_AND_WAIT("deleting iteration support structures, press ENTER\n"); if (buffer != NULL) free(buffer); if (phones != NULL) S_DELETE(phones, "main", &error); if (syllablesPhones != NULL) S_DELETE(syllablesPhones, "main", &error); SPCT_PRINT_AND_WAIT("deleting utterance, press ENTER\n"); if (utt != NULL) S_DELETE(utt, "main", &error); SPCT_PRINT_AND_WAIT("deleting voice, press ENTER\n"); if (voice != NULL) S_DELETE(voice, "main", &error); SPCT_PRINT_AND_WAIT("quitting speect, press ENTER\n"); /* * quit speect */ error = speect_quit(); if (error != S_SUCCESS) { printf("Call to 'speect_quit' failed\n"); return 1; } SPCT_PRINT_AND_WAIT("done, press ENTER\n"); return 0; }