[1.47.11c]

Change API function: espeak_TextToPhonemes().
Fix bug: number following a non-ascii character could cause crash.


git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@361 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
jonsd
2013-05-31 19:18:18 +00:00
parent 500d2c9525
commit b5035d73f8
19 changed files with 215 additions and 164 deletions
+99 -97
View File
@@ -526,6 +526,10 @@ unsigned short ipa1[96] = {
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x303,0x7f
};
#define N_PHON_OUT 500
static char *phon_out_buf = NULL;
static int phon_out_size = 0;
char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa, int *flags)
{//===================================================================================================
@@ -629,8 +633,8 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int phoneme_mode)
{//===============================================================================
const char *GetTranslatedPhonemeString(int phoneme_mode)
{//=======================================================
/* Called after a clause has been translated into phonemes, in order
to display the clause in phoneme mnemonic form.
@@ -640,7 +644,6 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int phoneme_mode
int ix;
unsigned int len;
unsigned int max_len;
int phon_out_ix=0;
int stress;
int c;
@@ -668,108 +671,107 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int phoneme_mode
use_tie = 0;
}
if(phon_out != NULL)
for(ix=1; ix<(n_phoneme_list-2); ix++)
{
for(ix=1; ix<(n_phoneme_list-2); ix++)
buf = phon_buf;
plist = &phoneme_list[ix];
WritePhMnemonic(phon_buf2, plist->ph, plist, use_ipa, &flags);
if(plist->newword)
*buf++ = ' ';
else
{
buf = phon_buf;
plist = &phoneme_list[ix];
WritePhMnemonic(phon_buf2, plist->ph, plist, use_ipa, &flags);
if(plist->newword)
*buf++ = ' ';
else
if((separate_phonemes != 0) && (ix > 1))
{
if((separate_phonemes != 0) && (ix > 1))
utf8_in(&c, phon_buf2);
if((c < 0x2b0) || (c > 0x36f)) // not if the phoneme starts with a superscript letter
{
utf8_in(&c, phon_buf2);
if((c < 0x2b0) || (c > 0x36f)) // not if the phoneme starts with a superscript letter
{
*buf++ = separate_phonemes;
}
*buf++ = separate_phonemes;
}
}
if(plist->synthflags & SFLAG_SYLLABLE)
{
if((stress = plist->stresslevel) > 1)
{
c = 0;
if(stress > 5) stress = 5;
if(use_ipa)
{
c = 0x2cc; // ipa, secondary stress
if(stress > 3)
c = 0x02c8; // ipa, primary stress
}
else
{
c = stress_chars[stress];
}
if(c != 0)
{
buf += utf8_out(c, buf);
// if(separate_phonemes)
// *buf++ = separate_phonemes;
}
}
}
flags = 0;
count = 0;
for(p=phon_buf2; *p != 0;)
{
p += utf8_in(&c, p);
if(use_tie > 0)
{
// look for non-inital alphabetic character, but not diacritic, superscript etc.
if((count>0) && !(flags & (1 << (count-1))) && ((c < 0x2b0) || (c > 0x36f)) && iswalpha2(c))
{
buf += utf8_out(char_tie[use_tie-1], buf);
}
}
buf += utf8_out(c, buf);
count++;
}
if(plist->ph->code != phonSWITCH)
{
if(plist->synthflags & SFLAG_LENGTHEN)
{
buf = WritePhMnemonic(buf, phoneme_tab[phonLENGTHEN], NULL, use_ipa, NULL);
}
if((plist->synthflags & SFLAG_SYLLABLE) && (plist->type != phVOWEL))
{
// syllablic consonant
buf = WritePhMnemonic(buf, phoneme_tab[phonSYLLABIC], NULL, use_ipa, NULL);
}
if(plist->tone_ph > 0)
{
buf = WritePhMnemonic(buf, phoneme_tab[plist->tone_ph], NULL, use_ipa, NULL);
}
}
len = buf - phon_buf;
max_len = (n_phon_out - phon_out_ix - 5); // allow for " ..." and zero byte terminator
if(len > max_len)
{
strcpy(&phon_buf[max_len], " ...");
len = max_len + 4;
}
phon_buf[len] = 0;
strcpy(&phon_out[phon_out_ix], phon_buf);
phon_out_ix += len;
if(len > max_len)
{
break;
}
}
phon_out[phon_out_ix] = 0;
if(plist->synthflags & SFLAG_SYLLABLE)
{
if((stress = plist->stresslevel) > 1)
{
c = 0;
if(stress > 5) stress = 5;
if(use_ipa)
{
c = 0x2cc; // ipa, secondary stress
if(stress > 3)
c = 0x02c8; // ipa, primary stress
}
else
{
c = stress_chars[stress];
}
if(c != 0)
{
buf += utf8_out(c, buf);
// if(separate_phonemes)
// *buf++ = separate_phonemes;
}
}
}
flags = 0;
count = 0;
for(p=phon_buf2; *p != 0;)
{
p += utf8_in(&c, p);
if(use_tie > 0)
{
// look for non-inital alphabetic character, but not diacritic, superscript etc.
if((count>0) && !(flags & (1 << (count-1))) && ((c < 0x2b0) || (c > 0x36f)) && iswalpha2(c))
{
buf += utf8_out(char_tie[use_tie-1], buf);
}
}
buf += utf8_out(c, buf);
count++;
}
if(plist->ph->code != phonSWITCH)
{
if(plist->synthflags & SFLAG_LENGTHEN)
{
buf = WritePhMnemonic(buf, phoneme_tab[phonLENGTHEN], NULL, use_ipa, NULL);
}
if((plist->synthflags & SFLAG_SYLLABLE) && (plist->type != phVOWEL))
{
// syllablic consonant
buf = WritePhMnemonic(buf, phoneme_tab[phonSYLLABIC], NULL, use_ipa, NULL);
}
if(plist->tone_ph > 0)
{
buf = WritePhMnemonic(buf, phoneme_tab[plist->tone_ph], NULL, use_ipa, NULL);
}
}
len = buf - phon_buf;
if((phon_out_ix + len) >= phon_out_size)
{
// enlarge the phoneme buffer
phon_out_size = phon_out_ix + len + N_PHON_OUT;
if((phon_out_buf = (char *)realloc(phon_out_buf, phon_out_size)) == NULL)
{
phon_out_size = 0;
return("");
}
}
phon_buf[len] = 0;
strcpy(&phon_out_buf[phon_out_ix], phon_buf);
phon_out_ix += len;
}
phon_out_buf[phon_out_ix] = 0;
return(phon_out_buf);
} // end of GetTranslatedPhonemeString
+15 -11
View File
@@ -1831,17 +1831,24 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
}
else
{
if((!found) && (tensunits == 0))
if((hundreds==1) && (tr->langopts.numbers2 & NUM2_OMIT_1_HUNDRED_ONLY) && ((control & 1)==0))
{
// is there a special pronunciation for exactly n00 ?
sprintf(string,"_%dC0",hundreds);
found = Lookup(tr, string, ph_digits);
// only look for special 100 if there are previous thousands
}
if(!found)
else
{
sprintf(string,"_%dC",hundreds);
found = Lookup(tr, string, ph_digits); // is there a specific pronunciation for n-hundred ?
if((!found) && (tensunits == 0))
{
// is there a special pronunciation for exactly n00 ?
sprintf(string,"_%dC0",hundreds);
found = Lookup(tr, string, ph_digits);
}
if(!found)
{
sprintf(string,"_%dC",hundreds);
found = Lookup(tr, string, ph_digits); // is there a specific pronunciation for n-hundred ?
}
}
if(found)
@@ -1855,9 +1862,6 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
{
if((tr->langopts.numbers & NUM_OMIT_1_HUNDRED) != 0)
say_one_hundred = 0;
if(((tr->langopts.numbers2 & NUM2_OMIT_1_HUNDRED_ONLY) != 0) && ((control & 1)==0))
say_one_hundred = 0;
}
if(say_one_hundred != 0)
+5 -4
View File
@@ -1164,14 +1164,15 @@ ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream)
} // end of espeak_SetPhonemes
ESPEAK_API void espeak_TextToPhonemes(const void *text, char *buffer, int size, int textmode, int phonememode)
{//==============================================================================================================
ESPEAK_API const char *espeak_TextToPhonemes(const void **textptr, int textmode, int phonememode)
{//=================================================================================================
/* phoneme_mode bits 0-3: 0=only phoneme names, 1=ties, 2=ZWJ, 3=underscore separator
bits 4-7: 0=eSpeak phoneme names, 1=IPA
*/
option_multibyte = textmode & 7;
TranslateClause(translator, NULL, text, NULL, NULL);
GetTranslatedPhonemeString(buffer, size, phonememode);
*textptr = TranslateClause(translator, NULL, *textptr, NULL, NULL);
return(GetTranslatedPhonemeString(phonememode));
}
+4 -1
View File
@@ -34,7 +34,7 @@
#define ESPEAK_API
#endif
#define ESPEAK_API_REVISION 7
#define ESPEAK_API_REVISION 9
/*
Revision 2
Added parameter "options" to eSpeakInitialize()
@@ -58,6 +58,9 @@ Revision 7 24.Dec.2011
Revision 8 26.Apr.2013
Added function espeak_TextToPhonemes().
Revision 9 30.May.2013
Changed function espeak_TextToPhonemes().
*/
/********************/
/* Initialization */
+1 -1
View File
@@ -35,7 +35,7 @@
#include "translate.h"
#include "wave.h"
const char *version_string = "1.47.11b 28.May.13";
const char *version_string = "1.47.11c 31.May.13";
const int version_phdata = 0x014709;
int option_device_number = -1;
+4 -3
View File
@@ -1865,6 +1865,7 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control)
char *voice_change;
static FILE *f_text=NULL;
static const void *p_text=NULL;
const char *phon_out;
if(control == 4)
{
@@ -1957,14 +1958,14 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control)
if(option_phonemes >= 3)
phoneme_mode = 0x10 + option_phonemes-3; // 0x10=ipa, 0x11=ipa with tie, 0x12=ipa with ZWJ, 0x13=ipa with separators
GetTranslatedPhonemeString(translator->phon_out, sizeof(translator->phon_out), phoneme_mode);
phon_out = GetTranslatedPhonemeString(phoneme_mode);
if(option_phonemes > 0)
{
fprintf(f_trans,"%s\n",translator->phon_out);
fprintf(f_trans,"%s\n",phon_out);
}
if(phoneme_callback != NULL)
{
phoneme_callback(translator->phon_out);
phoneme_callback(phon_out);
}
}
+1 -1
View File
@@ -1484,7 +1484,7 @@ SetLengthMods(tr,3); // all equal
if(name2 == L('m','l'))
{
tr->letter_bits_offset = OFFSET_MALAYALAM;
tr->langopts.numbers = NUM_OMIT_1_THOUSAND;
tr->langopts.numbers = NUM_OMIT_1_THOUSAND | NUM_OMIT_1_HUNDRED;
tr->langopts.numbers2 = NUM2_OMIT_1_HUNDRED_ONLY;
}
else
+2 -2
View File
@@ -3041,7 +3041,7 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
c = ' ';
pre_pause_add = 4;
}
else if((prev_out == ' ') && IsAlpha(sbuf[ix-2]) && !IsAlpha(prev_in))
else if((prev_out == ' ') && IsAlpha(prev_out2) && !IsAlpha(prev_in))
{
// insert extra space between a word + space + hyphen, to distinguish 'a -2' from 'a-2'
sbuf[ix++] = ' ';
@@ -3139,7 +3139,7 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
decimal_sep_count = 1;
}
}
else if((prev_out == ' ') && IsAlpha(sbuf[ix-2]) && !IsAlpha(prev_in))
else if((prev_out == ' ') && IsAlpha(prev_out2) && !IsAlpha(prev_in))
{
// insert extra space between a word and a number, to distinguish 'a 2' from 'a2'
sbuf[ix++] = ' ';
+1 -2
View File
@@ -581,7 +581,6 @@ typedef struct
const char *transpose_map;
char dictionary_name[40];
char phon_out[500];
char phonemes_repeat[20];
int phonemes_repeat_count;
int phoneme_tab_ix;
@@ -723,7 +722,7 @@ int iswlower2(int c);
int iswupper2(int c);
int towlower2(unsigned int c);
int towupper2(unsigned int c);
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int phoneme_mode);
const char *GetTranslatedPhonemeString(int phoneme_mode);
const char *WordToString2(unsigned int word);
ALPHABET *AlphabetFromChar(int c);
ALPHABET *AlphabetFromName(const char *name);
+4 -3
View File
@@ -406,6 +406,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
int translate_text = 0;
char buf[1000];
char phon_out[N_PH_LIST*2];
const char *phon_out2;
int clause_tone;
int clause_count;
int use_ipa = 0;
@@ -495,11 +496,11 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
CalcPitches(translator,clause_tone);
CalcLengths(translator);
GetTranslatedPhonemeString(translator->phon_out, sizeof(translator->phon_out), use_ipa);
phon_out2 = GetTranslatedPhonemeString(use_ipa);
if(clause_count++ > 0)
strcat(phon_out," ||");
strcat(phon_out,translator->phon_out);
t_phonetic->SetValue(wxString(translator->phon_out,wxConvUTF8));
strcat(phon_out, phon_out2);
t_phonetic->SetValue(wxString(phon_out2, wxConvUTF8));
if((n_ph_list + n_phoneme_list) >= N_PH_LIST)
{