Esempio 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;
}
Esempio n. 2
0
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;
}