summaryrefslogtreecommitdiffstats
path: root/pico
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2009-08-26 18:53:55 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2009-08-27 12:16:54 -0700
commitd434f44285f109dfbda5a4e821b89f53d2050ca7 (patch)
treeedab7e8b6a61f7f1dfe3cf32d51d4d0e8de9e2b4 /pico
parentb66af797d17d7cc7372697901633060b82448208 (diff)
downloadexternal_svox-d434f44285f109dfbda5a4e821b89f53d2050ca7.zip
external_svox-d434f44285f109dfbda5a4e821b89f53d2050ca7.tar.gz
external_svox-d434f44285f109dfbda5a4e821b89f53d2050ca7.tar.bz2
Integrate SVOX patch to pre-process camelCase'd text before sending
it to the synthesizer.
Diffstat (limited to 'pico')
-rw-r--r--pico/tts/com_svox_picottsengine.cpp163
1 files changed, 159 insertions, 4 deletions
diff --git a/pico/tts/com_svox_picottsengine.cpp b/pico/tts/com_svox_picottsengine.cpp
index 0c4b5fc..41cfcdf 100644
--- a/pico/tts/com_svox_picottsengine.cpp
+++ b/pico/tts/com_svox_picottsengine.cpp
@@ -583,6 +583,157 @@ static char * doAddProperties( const char * str )
}
+/** get_tok
+ * Searches for tokens in a string
+ * @str - text to be processed
+ * @pos - position of first character to be searched in str
+ * @textlen - postion of last character to be searched
+ * @tokstart - address of a variable to receive the start of the token found
+ * @tokstart - address of a variable to receive the length of the token found
+ * return : 1=token found, 0=token not found
+ * notes : the token separator set could be enlarged adding characters in "seps"
+*/
+static int get_tok(const char * str , int pos, int textlen, int *tokstart, int *toklen)
+{
+ const char * seps = " ";
+
+ /*look for start*/
+ while ((pos<textlen) && (strchr(seps,str[pos]) != NULL)) {
+ pos++;
+ }
+ if (pos == textlen) {
+ /*no characters != seps found whithin string*/
+ return 0;
+ }
+ *tokstart = pos;
+ /*look for end*/
+ while ((pos<textlen) && (strchr(seps,str[pos]) == NULL)) {
+ pos++;
+ }
+ *toklen = pos - *tokstart;
+ return 1;
+}/*get_tok*/
+
+
+/** get_sub_tok
+ * Searches for subtokens in a token having a compound structure with camel case like "xxxYyyy"
+ * @str - text to be processed
+ * @pos - position of first character to be searched in str
+ * @textlen - postion of last character to be searched in str
+ * @tokstart - address of a variable to receive the start of the sub token found
+ * @tokstart - address of a variable to receive the length of the sub token found
+ * return : 1=sub token found, 0=sub token not found
+ * notes : the sub token separator set could be enlarged adding characters in "seps"
+*/
+static int get_sub_tok(const char * str , int pos, int textlen, int *tokstart, int *toklen) {
+
+ const char * seps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ if (pos == textlen) {
+ return 0;
+ }
+
+ /*first char != space*/
+ *tokstart = pos;
+ /*finding first non separator*/
+ while ((pos < textlen) && (strchr(seps, str[pos]) != NULL)) {
+ pos++;
+ }
+ if (pos == textlen) {
+ /*characters all in seps found whithin string : return full token*/
+ *toklen = pos - *tokstart;
+ return 1;
+ }
+ /*pos should be pointing to first non seps and more chars are there*/
+ /*finding first separator*/
+ while ((pos < textlen) && (strchr(seps, str[pos]) == NULL)) {
+ pos++;
+ }
+ if (pos == textlen) {
+ /*transition non seps->seps not found : return full token*/
+ *toklen = pos - *tokstart;
+ return 1;
+ }
+ *toklen = pos - *tokstart;
+ return 1;
+}/*get_sub_tok*/
+
+
+/** doCamelCase
+ * Searches for tokens having a compound structure with camel case and transforms them as follows :
+ * "XxxxYyyy" -->> "Xxxx Yyyy",
+ * "xxxYyyy" -->> "xxx Yyyy",
+ * "XXXYyyy" -->> "XXXYyyy"
+ * etc....
+ * The calling function is responsible for freeing the returned string.
+ * @str - text to be processed
+ * return new string with text processed
+*/
+static char * doCamelCase( const char * str )
+{
+ int textlen; /* input string length */
+ int totlen; /* output string length */
+ int tlen_2, nsubtok; /* nuber of subtokens */
+ int toklen, tokstart; /*legnth and start of generic token*/
+ int stoklen, stokstart; /*legnth and start of generic sub-token*/
+ int pos, tokpos, outpos; /*postion of current char in input string and token and output*/
+ char *data; /*pointer of the returned string*/
+
+ pos = 0;
+ tokpos = 0;
+ toklen = 0;
+ stoklen = 0;
+ tlen_2 = 0;
+ totlen = 0;
+
+ textlen = strlen(str) + 1;
+
+ /*counting characters after sub token splitting including spaces*/
+ //while ((pos<textlen) && (str[pos]!=0)) {
+ while (get_tok(str, pos, textlen, &tokstart, &toklen)) {
+ tokpos = tokstart;
+ tlen_2 = 0;
+ nsubtok = 0;
+ while (get_sub_tok(str, tokpos, tokstart+toklen, &stokstart, &stoklen)) {
+ totlen += stoklen;
+ tlen_2 += stoklen;
+ tokpos = stokstart + stoklen;
+ nsubtok += 1;
+ }
+ totlen += nsubtok; /*add spaces between subtokens*/
+ pos = tokstart + tlen_2;
+ }
+ //}
+ /* Allocate the return string */
+ data = (char *) malloc( totlen ); /* allocate string */
+ if (!data) {
+ return NULL;
+ }
+ memset(data, 0, totlen); /* clear it */
+ outpos = 0;
+ pos = 0;
+ /*copying characters*/
+ //while ((pos<textlen) && (str[pos]!=0)) {
+ while (get_tok (str, pos, textlen, &tokstart, &toklen)) {
+ tokpos = tokstart;
+ tlen_2 = 0;
+ nsubtok = 0;
+ while (get_sub_tok(str, tokpos, tokstart+toklen, &stokstart, &stoklen)) {
+ strncpy(&(data[outpos]), &(str[stokstart]), stoklen);
+ outpos += stoklen;
+ strncpy(&(data[outpos]), " ", 1);
+ tlen_2 += stoklen;
+ outpos += 1;
+ tokpos = stokstart + stoklen;
+ }
+ pos=tokstart+tlen_2;
+ }
+ //}
+ data[outpos] = 0;
+ return data;
+}/*doCamelCase*/
+
+
/** createPhonemeString
* Wrap all individual words in <phoneme> tags.
* The Pico <phoneme> tag only supports one word in each tag,
@@ -834,7 +985,7 @@ void CnvIPAPnt( const char16_t IPnt, char * XPnt )
int cnvIpaToXsampa( const char16_t * ipaString, size_t ipaStringSize, char ** outXsampaString )
{
size_t xsize; /* size of result */
- int ipidx; /* index into IPA string */
+ size_t ipidx; /* index into IPA string */
char * XPnt; /* short XSAMPA char sequence */
/* Convert an IPA string to an XSAMPA string and store the xsampa string in *outXsampaString.
@@ -1269,6 +1420,7 @@ tts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t
int err;
int cbret;
pico_Char * inp = NULL;
+ char * expanded_text = NULL;
pico_Char * local_text = NULL;
short outbuf[MAX_OUTBUF_SIZE/2];
pico_Int16 bytes_sent, bytes_recv, text_remaining, out_data_type;
@@ -1338,8 +1490,11 @@ tts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t
return TTS_FAILURE;
}
} else {
+ /* camelCase pre-processing */
+ expanded_text = doCamelCase(text);
/* Add property tags to the string - if any. */
- local_text = (pico_Char *) doAddProperties( text );
+ local_text = (pico_Char *) doAddProperties( expanded_text );
+ free( expanded_text );
if (!local_text) {
LOGE("Failed to allocate memory for text string");
return TTS_FAILURE;
@@ -1354,7 +1509,7 @@ tts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t
/* synthesis loop */
while (text_remaining) {
-
+
if (picoSynthAbort) {
ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT );
break;
@@ -1378,7 +1533,7 @@ tts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t
break;
}
/* Retrieve the samples and add them to the buffer. */
- ret = pico_getData( picoEngine, (void *) outbuf, MAX_OUTBUF_SIZE, &bytes_recv,
+ ret = pico_getData( picoEngine, (void *) outbuf, MAX_OUTBUF_SIZE, &bytes_recv,
&out_data_type );
if (bytes_recv) {
if ((bufused + bytes_recv) <= bufferSize) {