mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-09 07:52:27 +00:00
Merge branch 'master' into build
This commit is contained in:
+3
-2
@@ -1,10 +1,11 @@
|
||||
# remove -fno-exceptions if it causes problems with stdio library on some platforms (ARM)
|
||||
|
||||
DATADIR=/usr/share/espeak-data
|
||||
|
||||
PREFIX=/usr
|
||||
BINDIR=$(PREFIX)/bin
|
||||
INCDIR=$(PREFIX)/include/espeak
|
||||
LIBDIR=$(PREFIX)/lib
|
||||
DATADIR=$(PREFIX)/share/espeak-data
|
||||
|
||||
RELEASE = 1.44
|
||||
BIN_NAME = speak
|
||||
@@ -88,7 +89,7 @@ $(BIN2_NAME): $(OBJS3) $(LIB_NAME)
|
||||
|
||||
|
||||
x_%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(USE_AUDIO) -Wall -fpic -fvisibility=hidden -pedantic \
|
||||
$(CXX) $(CXXFLAGS) $(USE_AUDIO) -D PATH_ESPEAK_DATA=\"$(DATADIR)\" -Wall -fpic -fvisibility=hidden -pedantic \
|
||||
-I. -D LIBRARY -c -fno-exceptions $< -o x_$*.o
|
||||
|
||||
$(LIB_NAME): $(OBJS2)
|
||||
|
||||
+14
-2
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -312,6 +312,7 @@ static keywtab_t keywords[] = {
|
||||
{"nonsyllabic",tPHONEME_FLAG, phNONSYLLABIC},
|
||||
{"lengthenstop",tPHONEME_FLAG, phLENGTHENSTOP},
|
||||
{"nopause", tPHONEME_FLAG, phNOPAUSE},
|
||||
{"prevoice", tPHONEME_FLAG, phPREVOICE},
|
||||
|
||||
{"flag1", tPHONEME_FLAG, phFLAG1},
|
||||
{"flag2", tPHONEME_FLAG, phFLAG2},
|
||||
@@ -375,8 +376,10 @@ int n_procs;
|
||||
int proc_addr[N_PROCS];
|
||||
char proc_names[40][N_PROCS];
|
||||
|
||||
#define MAX_PROG_BUF 2000
|
||||
USHORT *prog_out;
|
||||
USHORT prog_buf[2000];
|
||||
USHORT *prog_out_max;
|
||||
USHORT prog_buf[MAX_PROG_BUF+20];
|
||||
|
||||
|
||||
static const char *KeyToMnem(keywtab_t *ktab, int type, int value)
|
||||
@@ -1064,6 +1067,8 @@ static wxString CompileAllDictionaries()
|
||||
|
||||
static void error(const char *format, const char *string)
|
||||
{//======================================================
|
||||
if(string==NULL)
|
||||
string = "";
|
||||
fprintf(f_errors,"%4d: ",linenum-1);
|
||||
fprintf(f_errors,format,string);
|
||||
fprintf(f_errors,"\n");
|
||||
@@ -2259,6 +2264,12 @@ int CompileIf(int elif)
|
||||
|
||||
while(!finish)
|
||||
{
|
||||
if(prog_out >= prog_out_max)
|
||||
{
|
||||
error("Phoneme program too large", NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if((key = NextItem(tCONDITION)) < 0)
|
||||
error("Expected a condition, not '%s'",item_string);
|
||||
|
||||
@@ -2644,6 +2655,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
PHONEME_PROG_LOG phoneme_prog_log;
|
||||
|
||||
prog_out = prog_buf;
|
||||
prog_out_max = &prog_buf[MAX_PROG_BUF-1];
|
||||
if_level = 0;
|
||||
if_stack[0].returned = 0;
|
||||
after_if = 0;
|
||||
|
||||
@@ -2740,6 +2740,8 @@ void ApplySpecialAttribute(Translator *tr, char *phonemes, int dict_flags)
|
||||
|
||||
switch(tr->translator_name)
|
||||
{
|
||||
#ifdef deleted
|
||||
// this is now done in de_rules
|
||||
case L('d','e'):
|
||||
if(p_end[0] == PhonemeCode2('i',':'))
|
||||
{
|
||||
@@ -2750,6 +2752,7 @@ void ApplySpecialAttribute(Translator *tr, char *phonemes, int dict_flags)
|
||||
p_end[2] = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case L('r','o'):
|
||||
if(p_end[0] == PhonemeCode('j'))
|
||||
@@ -3249,6 +3252,10 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f
|
||||
{
|
||||
if(((c = *word1++)==0) || (c == ' '))
|
||||
break;
|
||||
|
||||
if((c=='.') && (length > 0) && (isdigit(word[length-1])))
|
||||
break; // needed for lang=hu, eg. "december 2.-ig"
|
||||
|
||||
word[length] = c;
|
||||
}
|
||||
word[length] = 0;
|
||||
|
||||
+12
-3
@@ -426,6 +426,9 @@ int main (int argc, char **argv)
|
||||
|
||||
if(c == '-')
|
||||
{
|
||||
if(p[0] == 0)
|
||||
break; // -- means don't interpret further - as commands
|
||||
|
||||
opt_string="";
|
||||
for(ix=0; ;ix++)
|
||||
{
|
||||
@@ -478,9 +481,15 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
printf("\n");
|
||||
printf("eSpeak text-to-speech: %s\n%s",espeak_Info(NULL),help_text);
|
||||
exit(0);
|
||||
{
|
||||
const char *version;
|
||||
const char *path_data;
|
||||
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 0, data_path, espeakINITIALIZE_DONT_EXIT);
|
||||
version = espeak_Info(&path_data);
|
||||
printf("\n");
|
||||
printf("eSpeak text-to-speech: %s Data at: %s\n%s", version, path_data, help_text);
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
|
||||
+84
-51
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2006 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -325,6 +325,7 @@ void Lexicon_It(int pass)
|
||||
char buf_out[200];
|
||||
char buf_error[200];
|
||||
char last_listx[200];
|
||||
int test;
|
||||
static const char *vowels1 = "aeiou";
|
||||
static const char *vowels2 = "aeou";
|
||||
|
||||
@@ -455,6 +456,7 @@ void Lexicon_It(int pass)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// translate
|
||||
TranslateWord(translator,&word1[1],0, NULL);
|
||||
DecodePhonemes(word_phonemes,phonemes);
|
||||
@@ -953,7 +955,10 @@ void Lexicon_Bg()
|
||||
}
|
||||
input_length = GetFileLength(buf);
|
||||
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"bg_listx_1");
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"bg_listx");
|
||||
remove(fname);
|
||||
CompileDictionary(path_dsource,"bg",NULL,NULL,0);
|
||||
|
||||
if((f_out = fopen(fname,"w")) == NULL)
|
||||
{
|
||||
wxLogError(_T("Can't write to: ")+wxString(fname,wxConvLocal));
|
||||
@@ -961,8 +966,8 @@ void Lexicon_Bg()
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"bg_log");
|
||||
f_log = fopen(fname,"w");
|
||||
// sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"bg_log");
|
||||
// f_log = fopen(fname,"w");
|
||||
|
||||
LoadVoice("bg",0);
|
||||
progress = new wxProgressDialog(_T("Lexicon"),_T(""),input_length);
|
||||
@@ -1089,11 +1094,13 @@ void Lexicon_Bg()
|
||||
|
||||
fclose(f_in);
|
||||
fclose(f_out);
|
||||
fclose(f_log);
|
||||
// fclose(f_log);
|
||||
|
||||
CompileDictionary(path_dsource,"bg",NULL,NULL,0);
|
||||
|
||||
|
||||
delete progress;
|
||||
sprintf(buf,"Lexicon: Input %d, Output %d, Failed %d",n_words,n_out,n_wrong);
|
||||
sprintf(buf,"Lexicon: Input %d, Output %d, $text %d",n_words,n_out,n_wrong);
|
||||
wxLogStatus(wxString(buf,wxConvLocal));
|
||||
} // end of Lexicon_Bg
|
||||
|
||||
@@ -1101,7 +1108,17 @@ void Lexicon_Bg()
|
||||
|
||||
void Lexicon_Ru()
|
||||
{//==============
|
||||
// compare stress markings in Russian RuLex file with lookup in ru_rules
|
||||
// compare stress markings in Russian RuLex file with lookup in ru_rules
|
||||
|
||||
// Input file contains a list of Russian words (UTF-8), one per line
|
||||
// Stress position can be indicated either by:
|
||||
// A $ sign and syllable number after the word, eg:
|
||||
// абажура $3
|
||||
// or by a + sign after the stressed vowel, eg:
|
||||
// абажу+ра
|
||||
|
||||
// espeakedit produces a file: dictsource/ru_listx and a log file dictsource/ru_log
|
||||
|
||||
int ix;
|
||||
char *p;
|
||||
int c;
|
||||
@@ -1110,12 +1127,14 @@ void Lexicon_Ru()
|
||||
FILE *f_log;
|
||||
FILE *f_roots;
|
||||
PHONEME_TAB *ph;
|
||||
int ph_code;
|
||||
int vcount;
|
||||
int ru_stress;
|
||||
int max_stress;
|
||||
int max_stress_posn;
|
||||
int n_words=0;
|
||||
int n_wrong=0;
|
||||
int n_errors=0;
|
||||
int wlength;
|
||||
int input_length;
|
||||
|
||||
@@ -1125,9 +1144,6 @@ void Lexicon_Ru()
|
||||
int len;
|
||||
int check_root;
|
||||
|
||||
int *p_unicode;
|
||||
int unicode[80];
|
||||
|
||||
char word[80];
|
||||
char word2[80];
|
||||
int counts[20][20][10];
|
||||
@@ -1136,8 +1152,8 @@ void Lexicon_Ru()
|
||||
char buf[200];
|
||||
char fname[sizeof(path_dsource)+20];
|
||||
|
||||
// KOI8-R codes for Russian vowels
|
||||
static unsigned char vowels[] = {0xa3,0xc0,0xc1,0xc5,0xc9,0xcf,0xd1,0xd5,0xd9,0xdc,0};
|
||||
// character codes for Russian vowels
|
||||
static unsigned short ru_vowels[] = {0x430,0x435,0x438,0x439,0x43e,0x443,0x44d,0x44e,0x44f,0x450,0x451,0};
|
||||
|
||||
typedef struct {
|
||||
const char *suffix;
|
||||
@@ -1190,7 +1206,12 @@ void Lexicon_Ru()
|
||||
}
|
||||
input_length = GetFileLength(buf);
|
||||
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"ru_listx_1");
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"ru_listx");
|
||||
remove(fname);
|
||||
|
||||
// compile ru_dict without ru_listx
|
||||
CompileDictionary(path_dsource,"ru",NULL,NULL,0);
|
||||
|
||||
if((f_out = fopen(fname,"w")) == NULL)
|
||||
{
|
||||
wxLogError(_T("Can't write to: ")+wxString(fname,wxConvLocal));
|
||||
@@ -1201,7 +1222,7 @@ void Lexicon_Ru()
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"ru_log");
|
||||
f_log = fopen(fname,"w");
|
||||
sprintf(fname,"%s%c%s",path_dsource,PATHSEP,"ru_roots_1");
|
||||
f_roots = fopen(fname,"w");
|
||||
// f_roots = fopen(fname,"w");
|
||||
|
||||
LoadVoice("ru",0);
|
||||
|
||||
@@ -1221,46 +1242,46 @@ void Lexicon_Ru()
|
||||
if(fgets(buf,sizeof(buf),f_in) == NULL)
|
||||
break;
|
||||
|
||||
if(isspace2(buf[0]))
|
||||
continue;
|
||||
if((p = strstr(buf,"//")) != NULL)
|
||||
*p = '\n'; // truncate at comment
|
||||
|
||||
// convert word from KOI8-R to UTF8
|
||||
p = buf;
|
||||
while((*p == ' ') || (*p == '\t')) p++;
|
||||
if(*p == '\n')
|
||||
continue; // blank line
|
||||
|
||||
ix = 0;
|
||||
wlength = 0;
|
||||
p_unicode = unicode;
|
||||
while(!isspace2(c = (*p++ & 0xff)))
|
||||
vcount = 0;
|
||||
ru_stress = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(c >= 0xa0)
|
||||
{
|
||||
c = KOI8_R[c-0xa0];
|
||||
*p_unicode++ = c;
|
||||
}
|
||||
p += utf8_in(&c, p);
|
||||
if(isspace(c))
|
||||
break;
|
||||
|
||||
|
||||
wlength++;
|
||||
ix += utf8_out(c,&word[ix]);
|
||||
if(lookupwchar(ru_vowels, c))
|
||||
vcount++;
|
||||
if(c == '+')
|
||||
ru_stress = vcount;
|
||||
else
|
||||
ix += utf8_out(c, &word[ix]);
|
||||
}
|
||||
word[ix] = 0;
|
||||
*p_unicode=0;
|
||||
|
||||
sprintf(word2," %s ",word);
|
||||
sprintf(word2," %s ",word); // surround word by spaces before calling TranslateWord()
|
||||
|
||||
// find the marked stress position
|
||||
vcount = 0;
|
||||
ru_stress = 0;
|
||||
while(*p == ' ') p++;
|
||||
|
||||
while((c = (*p++ & 0xff)) != '\n')
|
||||
// find the marked stress position, if it has not been marked by a + after the stressed vowel
|
||||
if(ru_stress == -1)
|
||||
{
|
||||
if(c == '+')
|
||||
while((*p == ' ') || (*p == '\t')) p++;
|
||||
sscanf(p,"$%d",&ru_stress);
|
||||
if(ru_stress == -1)
|
||||
{
|
||||
ru_stress = vcount;
|
||||
break;
|
||||
}
|
||||
if(strchr((char *)vowels,c) != NULL)
|
||||
{
|
||||
vcount++;
|
||||
n_errors++;
|
||||
fprintf(f_log,"%s",buf);
|
||||
continue; // stress position not found
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,13 +1296,13 @@ p_unicode = unicode;
|
||||
check_root = 0;
|
||||
|
||||
ph = phoneme_tab[phonPAUSE];
|
||||
for(p=word_phonemes; *p != 0; p++)
|
||||
for(p=word_phonemes; (ph_code = *p & 0xff) != 0; p++)
|
||||
{
|
||||
ph = phoneme_tab[(unsigned int)*p];
|
||||
ph = phoneme_tab[ph_code];
|
||||
if(ph == NULL)
|
||||
continue;
|
||||
|
||||
if(ph->type == phVOWEL)
|
||||
if((ph->type == phVOWEL) && (ph_code != phonSCHWA_SHORT))
|
||||
vcount++;
|
||||
if(ph->type == phSTRESS)
|
||||
{
|
||||
@@ -1300,6 +1321,7 @@ p_unicode = unicode;
|
||||
{
|
||||
fprintf(f_log,"%s\t $%d\t // %s\n",word,ru_stress,phonemes);
|
||||
}
|
||||
n_errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1309,7 +1331,14 @@ p_unicode = unicode;
|
||||
{
|
||||
n_wrong++;
|
||||
if((ru_stress==0) || (ru_stress > 7))
|
||||
{
|
||||
fprintf(f_out,"// "); // we only have $1 to $7 to indicate stress position
|
||||
if(f_log != NULL)
|
||||
{
|
||||
fprintf(f_log,"%s\t $%d\t // %s\n",word,ru_stress,phonemes);
|
||||
}
|
||||
n_errors++;
|
||||
}
|
||||
else
|
||||
check_root = 1;
|
||||
|
||||
@@ -1329,6 +1358,8 @@ p_unicode = unicode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef deleted
|
||||
if(check_root)
|
||||
{
|
||||
// does this word match any suffixes ?
|
||||
@@ -1351,13 +1382,14 @@ p_unicode = unicode;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fclose(f_in);
|
||||
fclose(f_out);
|
||||
fclose(f_roots);
|
||||
// fclose(f_roots);
|
||||
|
||||
sprintf(buf,"Lexicon: Total %d OK %d wrong %d",n_words,n_words-n_wrong,n_wrong);
|
||||
sprintf(buf,"Lexicon: Total %d OK %d fixed %d errors %d (see ru_log)",n_words,n_words-n_wrong,n_wrong,n_errors);
|
||||
if(gui_flag)
|
||||
{
|
||||
delete progress;
|
||||
@@ -1374,13 +1406,13 @@ p_unicode = unicode;
|
||||
#ifdef deleted
|
||||
// list tables of frequency of stress position for words of different syllable lengths
|
||||
int j,k;
|
||||
for(ix=0; ix<12; ix++)
|
||||
for(ix=2; ix<12; ix++)
|
||||
{
|
||||
fprintf(f_log,"%2d syl: ",ix);
|
||||
fprintf(f_log,"%2d syllables\n",ix);
|
||||
for(k=0; k<10; k++)
|
||||
{
|
||||
fprintf(f_log," %2d :",k);
|
||||
for(j=0; j<10; j++)
|
||||
for(j=1; j<=ix; j++)
|
||||
{
|
||||
fprintf(f_log,"%6d ",counts[ix][j][k]);
|
||||
}
|
||||
@@ -2273,7 +2305,8 @@ if(control==2)
|
||||
espeak_SetSynthCallback(TestSynthCallback);
|
||||
espeak_SetUriCallback(TestUriCallback);
|
||||
|
||||
espeak_Synth(textbuf, strlen(textbuf)+1, 0, POS_CHARACTER, 0, espeakSSML|espeakCHARS_UTF8, &unique_identifier, (void *)user_data);
|
||||
espeak_SetVoiceByName("en");
|
||||
espeak_Synth(textbuf, strlen(textbuf)+1, 0, POS_CHARACTER, 0, espeakSSML|espeakCHARS_UTF8, &unique_identifier, (void *)user_data);
|
||||
// espeak_Synth(text1, strlen(text1)+1, 0, POS_CHARACTER, 0, espeakSSML|espeakCHARS_UTF8, &unique_identifier, (void *)(user_data+1));
|
||||
|
||||
espeak_SetParameter(espeakPUNCTUATION, 1, 0);
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ wxMenuBar *MakeMenu(int type, const char *dict_name)
|
||||
vowelchart_menu->Append(MENU_VOWELCHART3, _("From directory of vowel files..."));
|
||||
|
||||
lexicon_menu = new wxMenu;
|
||||
lexicon_menu->Append(MENU_LEXICON_RU, _("Russian (lexicon.dict)"));
|
||||
lexicon_menu->Append(MENU_LEXICON_RU, _("Russian"));
|
||||
lexicon_menu->Append(MENU_LEXICON_BG, _("Bulgarian"));
|
||||
lexicon_menu->Append(MENU_LEXICON_DE, _("German"));
|
||||
lexicon_menu->Append(MENU_LEXICON_IT, _("Italian"));
|
||||
|
||||
+14
-9
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -768,7 +768,7 @@ static int CheckDotOrdinal(Translator *tr, char *word, char *word_end, WORD_TAB
|
||||
else
|
||||
utf8_in(&c2, &word_end[0]);
|
||||
|
||||
if((word_end[1] != 0) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || IsAlpha(c2)))
|
||||
if((word_end[0] != 0) && (word_end[1] != 0) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || IsAlpha(c2)))
|
||||
{
|
||||
// ordinal number is indicated by dot after the number
|
||||
// but not if the next word starts with an upper-case letter
|
||||
@@ -1089,7 +1089,7 @@ static int LookupThousands(Translator *tr, int value, int thousandplex, int thou
|
||||
return(1);
|
||||
|
||||
return(found_value);
|
||||
}
|
||||
} // end f LookupThousands
|
||||
|
||||
|
||||
static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
@@ -1395,7 +1395,15 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
}
|
||||
if(found == 0)
|
||||
{
|
||||
Lookup(tr, "_0C", ph_100);
|
||||
if(tensunits==0)
|
||||
{
|
||||
// special form for exact hundreds?
|
||||
found = Lookup(tr, "_0C0", ph_100);
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
Lookup(tr, "_0C", ph_100);
|
||||
}
|
||||
}
|
||||
|
||||
if(((tr->langopts.numbers & NUM_1900) != 0) && (hundreds == 19))
|
||||
@@ -1671,13 +1679,10 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
{
|
||||
// this is an ordinal suffix
|
||||
ordinal = 2;
|
||||
flags[0] |= FLAG_SKIPWORDS;
|
||||
skipwords = 1;
|
||||
}
|
||||
}
|
||||
if(ordinal)
|
||||
{
|
||||
flags[0] |= FLAG_SKIPWORDS;
|
||||
skipwords = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -54,8 +54,9 @@
|
||||
#define phNONSYLLABIC 0x100000 // don't count this vowel as a syllable when finding the stress position
|
||||
#define phLONG 0x200000
|
||||
#define phLENGTHENSTOP 0x400000 // make the pre-pause slightly longer
|
||||
#define phRHOTIC 0x800000
|
||||
#define phRHOTIC 0x800000 // bit 23
|
||||
#define phNOPAUSE 0x1000000
|
||||
#define phPREVOICE 0x2000000 // for voiced stops
|
||||
|
||||
#define phFLAG1 0x10000000
|
||||
#define phFLAG2 0x20000000
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
PHONEME_LIST *plist3_inserted = NULL;
|
||||
PHONEME_LIST ph_list3[N_PHONEME_LIST];
|
||||
|
||||
static PHONEME_LIST2 ph_list2_null = {0,0,0,0,0};
|
||||
static PHONEME_LIST2 ph_list2_null = {0,0,0,0,0,0};
|
||||
PHONEME_LIST2 *plist2 = &ph_list2_null;
|
||||
|
||||
plist2 = ph_list2;
|
||||
|
||||
+14
-9
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -101,6 +101,7 @@ static const unsigned short punct_chars[] = {',','.','?','!',':',';',
|
||||
0x1366,
|
||||
0x1367,
|
||||
0x1368,
|
||||
0x10fb, // Georgian paragraph
|
||||
|
||||
0x3001, // ideograph comma
|
||||
0x3002, // ideograph period
|
||||
@@ -142,7 +143,8 @@ static const unsigned int punct_attributes [] = { 0,
|
||||
CLAUSE_COLON, // Ethiopic colon
|
||||
CLAUSE_COLON, // Ethiopic preface colon
|
||||
CLAUSE_QUESTION, // Ethiopic question mark
|
||||
CLAUSE_PERIOD, // Ethiopic paragraph
|
||||
CLAUSE_PARAGRAPH, // Ethiopic paragraph
|
||||
CLAUSE_PARAGRAPH, // Georgian paragraph
|
||||
|
||||
CLAUSE_COMMA+0x8000, // ideograph comma
|
||||
CLAUSE_PERIOD+0x8000, // ideograph period
|
||||
@@ -884,7 +886,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
if(punct_count==1)
|
||||
{
|
||||
// sprintf(buf,"%s %s %s",tone_punct_on,punctname,tone_punct_off);
|
||||
sprintf(buf,"%s",punctname);
|
||||
sprintf(buf," %s",punctname); // we need the space before punctname, to ensure it doesn't merge with the previous word (eg. "2.-a")
|
||||
}
|
||||
else
|
||||
if(punct_count < 4)
|
||||
@@ -900,7 +902,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf,"%s %d %s",
|
||||
sprintf(buf," %s %d %s",
|
||||
punctname,punct_count,punctname);
|
||||
}
|
||||
}
|
||||
@@ -1193,7 +1195,7 @@ static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name)
|
||||
while(iswspace(*pw)) pw++;
|
||||
if(*pw == '=') pw++;
|
||||
while(iswspace(*pw)) pw++;
|
||||
if(*pw == '"')
|
||||
if((*pw == '"') || (*pw == '\'')) // allow single-quotes ?
|
||||
return(pw+1);
|
||||
else
|
||||
return(empty);
|
||||
@@ -1215,7 +1217,7 @@ static int attrcmp(const wchar_t *string1, const char *string2)
|
||||
for(ix=0; (string1[ix] == string2[ix]) && (string1[ix] != 0); ix++)
|
||||
{
|
||||
}
|
||||
if((string1[ix]=='"') && (string2[ix]==0))
|
||||
if(((string1[ix]=='"') || (string1[ix]=='\'')) && (string2[ix]==0))
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
@@ -1284,7 +1286,7 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
{//=============================================================================
|
||||
int sign = 0;
|
||||
wchar_t *tail;
|
||||
float value;
|
||||
double value;
|
||||
|
||||
while(iswspace(*pw)) pw++;
|
||||
if(*pw == '+')
|
||||
@@ -1297,7 +1299,7 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
pw++;
|
||||
sign = -1;
|
||||
}
|
||||
value = (float)wcstod(pw,&tail);
|
||||
value = (double)wcstod(pw,&tail);
|
||||
if(tail == pw)
|
||||
{
|
||||
// failed to find a number, return 100%
|
||||
@@ -1324,7 +1326,10 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
|
||||
if(param_type == espeakRATE)
|
||||
{
|
||||
*value_out = (int)(value * 100);
|
||||
if(sign == 0)
|
||||
*value_out = (int)(value * 100);
|
||||
else
|
||||
*value_out = 100 + (int)(sign * value * 100);
|
||||
return(2); // percentage
|
||||
}
|
||||
|
||||
|
||||
+37
-13
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "translate.h"
|
||||
|
||||
extern int GetAmplitude(void);
|
||||
extern void DoSonicSpeed(int value);
|
||||
|
||||
|
||||
// convert from words-per-minute to internal speed factor
|
||||
@@ -140,27 +141,54 @@ void SetSpeed(int control)
|
||||
int s1;
|
||||
int wpm;
|
||||
int wpm2;
|
||||
double sonic;
|
||||
|
||||
speed.loud_consonants = 0;
|
||||
speed.min_sample_len = 450;
|
||||
speed.lenmod_factor = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change
|
||||
speed.lenmod2_factor = 100;
|
||||
speed.min_pause = 5;
|
||||
|
||||
wpm = embedded_value[EMBED_S];
|
||||
if(control == 2)
|
||||
wpm = embedded_value[EMBED_S2];
|
||||
|
||||
// fast_settings[0] wpm where speedup starts
|
||||
// fast_settings[1] wpm for maximum espeak speed
|
||||
// fast_settings[2] maximum espeak speed
|
||||
if(voice->speed_percent > 0)
|
||||
{
|
||||
wpm = (wpm * voice->speed_percent)/100;
|
||||
}
|
||||
|
||||
sonicSpeed = 1.0;
|
||||
if(wpm > speed.fast_settings[0])
|
||||
if(control & 2)
|
||||
{
|
||||
DoSonicSpeed(1 * 1024);
|
||||
}
|
||||
if((wpm > 450) || ((wpm > speed.fast_settings[0]) && (wpm > 350)))
|
||||
{
|
||||
wpm2 = wpm;
|
||||
wpm = speed.fast_settings[2];
|
||||
// Maybe we can do better than a 10 wpm fudge factor?
|
||||
sonicSpeed = ((double)wpm2 + 10)/wpm;
|
||||
wpm = 175;
|
||||
|
||||
// set special eSpeak speed parameters for Sonic use
|
||||
// The eSpeak output will be speeded up by at least x2
|
||||
x = 73;
|
||||
if(control & 1)
|
||||
{
|
||||
speed1 = (x * voice->speedf1)/256;
|
||||
speed2 = (x * voice->speedf2)/256;
|
||||
speed3 = (x * voice->speedf3)/256;
|
||||
}
|
||||
if(control & 2)
|
||||
{
|
||||
sonic = ((double)wpm2)/wpm;
|
||||
DoSonicSpeed((int)(sonic * 1024));
|
||||
speed.pause_factor = 85;
|
||||
speed.clause_pause_factor = 80;
|
||||
speed.min_pause = 22;
|
||||
speed.min_sample_len = 450*2;
|
||||
speed.wav_factor = 211;
|
||||
speed.lenmod_factor = 210;
|
||||
speed.lenmod2_factor = 170;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,10 +201,6 @@ void SetSpeed(int control)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(voice->speed_percent > 0)
|
||||
{
|
||||
wpm = (wpm * voice->speed_percent)/100;
|
||||
}
|
||||
if(wpm > 450)
|
||||
wpm = 450;
|
||||
|
||||
|
||||
+5
-1
@@ -542,6 +542,9 @@ int main (int argc, char **argv)
|
||||
|
||||
if(c == '-')
|
||||
{
|
||||
if(p[0] == 0)
|
||||
break; // -- means don't interpret further - as commands
|
||||
|
||||
opt_string="";
|
||||
for(ix=0; ;ix++)
|
||||
{
|
||||
@@ -593,7 +596,8 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
printf("\nspeak text-to-speech: %s\n%s",version_string,help_text);
|
||||
init_path(argv[0],data_path);
|
||||
printf("\nspeak text-to-speech: %s Data at: %s\n%s",version_string,path_home,help_text);
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
|
||||
+14
-7
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -370,8 +370,8 @@ static void init_path(const char *path)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int initialise(void)
|
||||
{//========================
|
||||
static int initialise(int control)
|
||||
{//===============================
|
||||
int param;
|
||||
int result;
|
||||
|
||||
@@ -382,7 +382,10 @@ static int initialise(void)
|
||||
if(result == -1)
|
||||
{
|
||||
fprintf(stderr,"Failed to load espeak-data\n");
|
||||
exit(1);
|
||||
if((control & espeakINITIALIZE_DONT_EXIT) == 0)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr,"Wrong version of espeak-data 0x%x (expects 0x%x) at %s\n",result,version_phdata,path_home);
|
||||
@@ -745,7 +748,7 @@ ENTER("espeak_Initialize");
|
||||
#endif
|
||||
|
||||
init_path(path);
|
||||
initialise();
|
||||
initialise(options);
|
||||
select_output(output_type);
|
||||
|
||||
if(f_logespeak)
|
||||
@@ -1222,8 +1225,12 @@ ESPEAK_API espeak_ERROR espeak_Terminate(void)
|
||||
return EE_OK;
|
||||
} // end of espeak_Terminate
|
||||
|
||||
ESPEAK_API const char *espeak_Info(void *)
|
||||
{//=======================================
|
||||
ESPEAK_API const char *espeak_Info(const char **ptr)
|
||||
{//=================================================
|
||||
if(ptr != NULL)
|
||||
{
|
||||
*ptr = path_home;
|
||||
}
|
||||
return(version_string);
|
||||
}
|
||||
|
||||
|
||||
+32
-24
@@ -28,6 +28,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define ESPEAK_API __declspec(dllexport)
|
||||
#else
|
||||
#define ESPEAK_API
|
||||
#endif
|
||||
|
||||
#define ESPEAK_API_REVISION 6
|
||||
/*
|
||||
Revision 2
|
||||
@@ -157,11 +163,13 @@ typedef enum {
|
||||
EE_NOT_FOUND=2
|
||||
} espeak_ERROR;
|
||||
|
||||
#define espeakINITIALIZE_PHONEME_EVENTS 0x0001
|
||||
#define espeakINITIALIZE_DONT_EXIT 0x8000
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *path, int options);
|
||||
ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *path, int options);
|
||||
/* Must be called before any synthesis functions are called.
|
||||
output: the audio data can either be played by eSpeak or passed back by the SynthCallback function.
|
||||
|
||||
@@ -169,8 +177,8 @@ int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *pat
|
||||
|
||||
path: The directory which contains the espeak-data directory, or NULL for the default location.
|
||||
|
||||
options: bit 0: 1=allow espeakEVENT_PHONEME events.
|
||||
|
||||
options: bit 0: 1=allow espeakEVENT_PHONEME events.
|
||||
bit 15: 1=don't exit if espeak_data is not found (used for --help)
|
||||
|
||||
Returns: sample rate in Hz, or -1 (EE_INTERNAL_ERROR).
|
||||
*/
|
||||
@@ -180,7 +188,7 @@ typedef int (t_espeak_callback)(short*, int, espeak_EVENT*);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void espeak_SetSynthCallback(t_espeak_callback* SynthCallback);
|
||||
ESPEAK_API void espeak_SetSynthCallback(t_espeak_callback* SynthCallback);
|
||||
/* Must be called before any synthesis functions are called.
|
||||
This specifies a function in the calling program which is called when a buffer of
|
||||
speech sound data has been produced.
|
||||
@@ -208,7 +216,7 @@ int SynthCallback(short *wav, int numsamples, espeak_EVENT *events);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void espeak_SetUriCallback(int (*UriCallback)(int, const char*, const char*));
|
||||
ESPEAK_API void espeak_SetUriCallback(int (*UriCallback)(int, const char*, const char*));
|
||||
/* This function may be called before synthesis functions are used, in order to deal with
|
||||
<audio> tags. It specifies a callback function which is called when an <audio> element is
|
||||
encountered and allows the calling program to indicate whether the sound file which
|
||||
@@ -249,7 +257,7 @@ int UriCallback(int type, const char *uri, const char *base);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Synth(const void *text,
|
||||
ESPEAK_API espeak_ERROR espeak_Synth(const void *text,
|
||||
size_t size,
|
||||
unsigned int position,
|
||||
espeak_POSITION_TYPE position_type,
|
||||
@@ -305,7 +313,7 @@ espeak_ERROR espeak_Synth(const void *text,
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Synth_Mark(const void *text,
|
||||
ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text,
|
||||
size_t size,
|
||||
const char *index_mark,
|
||||
unsigned int end_position,
|
||||
@@ -329,7 +337,7 @@ espeak_ERROR espeak_Synth_Mark(const void *text,
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Key(const char *key_name);
|
||||
ESPEAK_API espeak_ERROR espeak_Key(const char *key_name);
|
||||
/* Speak the name of a keyboard key.
|
||||
If key_name is a single character, it speaks the name of the character.
|
||||
Otherwise, it speaks key_name as a text string.
|
||||
@@ -343,7 +351,7 @@ espeak_ERROR espeak_Key(const char *key_name);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Char(wchar_t character);
|
||||
ESPEAK_API espeak_ERROR espeak_Char(wchar_t character);
|
||||
/* Speak the name of the given character
|
||||
|
||||
Return: EE_OK: operation achieved
|
||||
@@ -388,7 +396,7 @@ typedef enum {
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative);
|
||||
ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative);
|
||||
/* Sets the value of the specified parameter.
|
||||
relative=0 Sets the absolute value of the parameter.
|
||||
relative=1 Sets a relative value of the parameter.
|
||||
@@ -425,7 +433,7 @@ espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int rela
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int espeak_GetParameter(espeak_PARAMETER parameter, int current);
|
||||
ESPEAK_API int espeak_GetParameter(espeak_PARAMETER parameter, int current);
|
||||
/* current=0 Returns the default value of the specified parameter.
|
||||
current=1 Returns the current value of the specified parameter, as set by SetParameter()
|
||||
*/
|
||||
@@ -433,7 +441,7 @@ int espeak_GetParameter(espeak_PARAMETER parameter, int current);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
|
||||
ESPEAK_API espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
|
||||
/* Specified a list of punctuation characters whose names are to be spoken when the
|
||||
value of the Punctuation parameter is set to "some".
|
||||
|
||||
@@ -448,7 +456,7 @@ espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void espeak_SetPhonemeTrace(int value, FILE *stream);
|
||||
ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream);
|
||||
/* Controls the output of phoneme symbols for the text
|
||||
value=0 No phoneme output (default)
|
||||
value=1 Output the translated phoneme symbols for the text
|
||||
@@ -461,7 +469,7 @@ void espeak_SetPhonemeTrace(int value, FILE *stream);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void espeak_CompileDictionary(const char *path, FILE *log, int flags);
|
||||
ESPEAK_API void espeak_CompileDictionary(const char *path, FILE *log, int flags);
|
||||
/* Compile pronunciation dictionary for a language which corresponds to the currently
|
||||
selected voice. The required voice should be selected before calling this function.
|
||||
|
||||
@@ -514,7 +522,7 @@ typedef struct {
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec);
|
||||
ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec);
|
||||
/* Reads the voice files from espeak-data/voices and creates an array of espeak_VOICE pointers.
|
||||
The list is terminated by a NULL pointer
|
||||
|
||||
@@ -526,7 +534,7 @@ const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_SetVoiceByName(const char *name);
|
||||
ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name);
|
||||
/* Searches for a voice with a matching "name" field. Language is not considered.
|
||||
"name" is a UTF8 string.
|
||||
|
||||
@@ -539,7 +547,7 @@ espeak_ERROR espeak_SetVoiceByName(const char *name);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
|
||||
ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
|
||||
/* An espeak_VOICE structure is used to pass criteria to select a voice. Any of the following
|
||||
fields may be set:
|
||||
|
||||
@@ -559,7 +567,7 @@ espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_VOICE *espeak_GetCurrentVoice(void);
|
||||
ESPEAK_API espeak_VOICE *espeak_GetCurrentVoice(void);
|
||||
/* Returns the espeak_VOICE data for the currently selected voice.
|
||||
This is not affected by temporary voice changes caused by SSML elements such as <voice> and <s>
|
||||
*/
|
||||
@@ -567,7 +575,7 @@ espeak_VOICE *espeak_GetCurrentVoice(void);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Cancel(void);
|
||||
ESPEAK_API espeak_ERROR espeak_Cancel(void);
|
||||
/* Stop immediately synthesis and audio output of the current text. When this
|
||||
function returns, the audio output is fully stopped and the synthesizer is ready to
|
||||
synthesize a new message.
|
||||
@@ -580,14 +588,14 @@ espeak_ERROR espeak_Cancel(void);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int espeak_IsPlaying(void);
|
||||
ESPEAK_API int espeak_IsPlaying(void);
|
||||
/* Returns 1 if audio is played, 0 otherwise.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Synchronize(void);
|
||||
ESPEAK_API espeak_ERROR espeak_Synchronize(void);
|
||||
/* This function returns when all data have been spoken.
|
||||
Return: EE_OK: operation achieved
|
||||
EE_INTERNAL_ERROR.
|
||||
@@ -596,7 +604,7 @@ espeak_ERROR espeak_Synchronize(void);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
espeak_ERROR espeak_Terminate(void);
|
||||
ESPEAK_API espeak_ERROR espeak_Terminate(void);
|
||||
/* last function to be called.
|
||||
Return: EE_OK: operation achieved
|
||||
EE_INTERNAL_ERROR.
|
||||
@@ -606,8 +614,8 @@ espeak_ERROR espeak_Terminate(void);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
const char *espeak_Info(void* ptr);
|
||||
ESPEAK_API const char *espeak_Info(const char **path_data);
|
||||
/* Returns the version number string.
|
||||
The parameter is for future use, and should be set to NULL
|
||||
path_data returns the path to espeak_data
|
||||
*/
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -17,6 +17,8 @@
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SPEECH_H
|
||||
#define SPEECH_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -41,7 +43,7 @@
|
||||
//#define USE_PULSEAUDIO
|
||||
#define USE_NANOSLEEP
|
||||
#define __cdecl
|
||||
#define ESPEAK_API extern "C"
|
||||
//#define ESPEAK_API extern "C"
|
||||
|
||||
#ifdef LIBRARY
|
||||
#define USE_ASYNC
|
||||
@@ -85,3 +87,4 @@ int GetFileLength(const char *filename);
|
||||
char *Alloc(int size);
|
||||
void Free(void *ptr);
|
||||
|
||||
#endif // SPEECH_H
|
||||
|
||||
@@ -133,14 +133,18 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
|
||||
sprintf(path,"%s/mbrola/%s",path_home,mbrola_voice);
|
||||
#ifdef PLATFORM_POSIX
|
||||
// if not found, then also look in
|
||||
// usr/share/mbrola/xx, /usr/share/mbrola/xx/xx, /usr/share/mbrola/voices/xx
|
||||
if(GetFileLength(path) <= 0)
|
||||
{
|
||||
// mbrola voice file not found, look in /usr/share
|
||||
sprintf(path,"/usr/share/mbrola/%s",mbrola_voice);
|
||||
}
|
||||
if(GetFileLength(path) <= 0)
|
||||
{
|
||||
// mbrola voice file not found, look in /usr/share
|
||||
sprintf(path,"/usr/share/mbrola/%s/%s",mbrola_voice,mbrola_voice);
|
||||
}
|
||||
if(GetFileLength(path) <= 0)
|
||||
{
|
||||
sprintf(path,"/usr/share/mbrola/voices/%s",mbrola_voice);
|
||||
}
|
||||
#endif
|
||||
|
||||
+11
-9
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.44.19 20.Dec.10";
|
||||
const char *version_string = "1.44.42 12.Mar.11";
|
||||
const int version_phdata = 0x014415;
|
||||
|
||||
int option_device_number = -1;
|
||||
@@ -496,7 +496,7 @@ void LoadConfig(void)
|
||||
else
|
||||
if(memcmp(buf,"pa_device",9)==0)
|
||||
{
|
||||
sscanf(&buf[7],"%d",&option_device_number);
|
||||
sscanf(&buf[10],"%d",&option_device_number);
|
||||
}
|
||||
else
|
||||
if(memcmp(buf,"soundicon",9)==0)
|
||||
@@ -617,6 +617,13 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
if(plist[0].sourceix)
|
||||
return(false);
|
||||
}
|
||||
if(which==7)
|
||||
{
|
||||
// nextPh2 not word boundary
|
||||
if((plist[1].sourceix) || (plist[2].sourceix))
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(which==6)
|
||||
{
|
||||
// nextVowel, not word boundary
|
||||
@@ -628,16 +635,11 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(which==7)
|
||||
{
|
||||
// nextPh2 not word boundary
|
||||
if((plist[1].sourceix) || (plist[2].sourceix))
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
which = ph_position[which];
|
||||
}
|
||||
|
||||
plist_this = plist;
|
||||
plist = &plist[which-1];
|
||||
|
||||
|
||||
+14
-2
@@ -200,7 +200,10 @@ int PauseLength(int pause, int control)
|
||||
else
|
||||
len = (pause * speed.wav_factor)/256;
|
||||
|
||||
if(len < 5) len = 5; // mS, limit the amount to which pauses can be shortened
|
||||
if(len < speed.min_pause)
|
||||
{
|
||||
len = speed.min_pause; // mS, limit the amount to which pauses can be shortened
|
||||
}
|
||||
return(len);
|
||||
}
|
||||
|
||||
@@ -1215,6 +1218,15 @@ void DoMarker(int type, int char_posn, int length, int value)
|
||||
} // end of DoMarker
|
||||
|
||||
|
||||
void DoSonicSpeed(int value)
|
||||
{//=========================
|
||||
// value, multiplier * 1024
|
||||
wcmdq[wcmdq_tail][0] = WCMD_SONIC_SPEED;
|
||||
wcmdq[wcmdq_tail][1] = value;
|
||||
WcmdqInc();
|
||||
} // end of DoSonicSpeed
|
||||
|
||||
|
||||
void DoVoiceChange(voice_t *v)
|
||||
{//===========================
|
||||
// allocate memory for a copy of the voice data, and free it in wavegenfill()
|
||||
@@ -1459,7 +1471,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
}
|
||||
}
|
||||
|
||||
if((prev->type==phVOWEL) || (prev->ph->phflags & phVOWEL2))
|
||||
if((prev->type==phVOWEL) || (prev->ph->phflags & phVOWEL2) || (ph->phflags & phPREVOICE))
|
||||
{
|
||||
// a period of voicing before the release
|
||||
InterpretPhoneme(NULL, 0x01, p, &phdata);
|
||||
|
||||
+3
-1
@@ -334,7 +334,7 @@ typedef struct {
|
||||
// phflags
|
||||
#define i_isSibilant 0x45 // bit 5 in phflags
|
||||
#define i_isPalatal 0x49 // bit 9 in phflags
|
||||
#define i_isRhotic 0x56 // bit 22 in phflags
|
||||
#define i_isRhotic 0x57 // bit 23 in phflags
|
||||
#define i_isFlag1 0x5c
|
||||
#define i_isFlag2 0x5d
|
||||
#define i_isFlag3 0x5e
|
||||
@@ -362,6 +362,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
int pause_factor;
|
||||
int clause_pause_factor;
|
||||
int min_pause;
|
||||
int wav_factor;
|
||||
int lenmod_factor;
|
||||
int lenmod2_factor;
|
||||
@@ -448,6 +449,7 @@ extern unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1];
|
||||
#define WCMD_EMBEDDED 12
|
||||
#define WCMD_MBROLA_DATA 13
|
||||
#define WCMD_FMT_AMPLITUDE 14
|
||||
#define WCMD_SONIC_SPEED 15
|
||||
|
||||
|
||||
|
||||
|
||||
+73
-18
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -40,21 +40,29 @@
|
||||
#define L_grc 0x677263 // grc Ancient Greek
|
||||
#define L_jbo 0x6a626f // jbo Lojban
|
||||
#define L_pap 0x706170 // pap Papiamento]
|
||||
#define L_qvi 0x717669 // qvi Kichwa
|
||||
#define L_shs 0x736873 // shs Shuswap / Secwepemctsin
|
||||
#define L_zhy 0x7a6879 // zhy
|
||||
|
||||
// start of unicode pages for character sets
|
||||
#define OFFSET_GREEK 0x380
|
||||
#define OFFSET_GREEK 0x380
|
||||
#define OFFSET_CYRILLIC 0x420
|
||||
#define OFFSET_ARMENIAN 0x530
|
||||
#define OFFSET_ARABIC 0x600
|
||||
#define OFFSET_ARABIC 0x600
|
||||
#define OFFSET_THAANA 0x780 // Divehi/Maldives
|
||||
#define OFFSET_DEVANAGARI 0x900
|
||||
#define OFFSET_BENGALI 0x980
|
||||
#define OFFSET_BENGALI 0x980
|
||||
#define OFFSET_GURMUKHI 0xa00
|
||||
#define OFFSET_TAMIL 0xb80
|
||||
#define OFFSET_KANNADA 0xc80
|
||||
#define OFFSET_GUJARATI 0xa80
|
||||
#define OFFSET_ORIYA 0xb00
|
||||
#define OFFSET_TAMIL 0xb80
|
||||
#define OFFSET_TELUGU 0xc00
|
||||
#define OFFSET_KANNADA 0xc80
|
||||
#define OFFSET_MALAYALAM 0xd00
|
||||
#define OFFSET_KOREAN 0x1100
|
||||
#define OFFSET_SINHALA 0x0d80
|
||||
#define OFFSET_GEORGIAN 0x1080
|
||||
|
||||
#define OFFSET_KOREAN 0x1100
|
||||
|
||||
static void Translator_Russian(Translator *tr);
|
||||
|
||||
@@ -106,7 +114,7 @@ static Translator* NewTranslator(void)
|
||||
{//===================================
|
||||
Translator *tr;
|
||||
int ix;
|
||||
static const unsigned char stress_amps2[] = {17,17, 20,20, 20,22, 22,20 };
|
||||
static const unsigned char stress_amps2[] = {18,18, 20,20, 20,22, 22,20 };
|
||||
static const short stress_lengths2[8] = {182,140, 220,220, 220,240, 260,280};
|
||||
static const wchar_t empty_wstring[1] = {0};
|
||||
static const wchar_t punct_in_word[2] = {'\'', 0}; // allow hyphen within words
|
||||
@@ -334,6 +342,9 @@ Translator *SelectTranslator(const char *name)
|
||||
static const unsigned char stress_amps_sk[8] = {17,17, 20,20, 20,22, 22,21 };
|
||||
static const short stress_lengths_sk[8] = {190,190, 210,210, 0,0, 210,210};
|
||||
|
||||
static const short stress_lengths_ta[8] = {200, 200, 210, 210, 0, 0, 230, 230};
|
||||
static const unsigned char stress_amps_ta[8] = {18,18, 18,18, 20,20, 22,22 };
|
||||
|
||||
// convert name string into a word of up to 4 characters, for the switch()
|
||||
while(*name != 0)
|
||||
name2 = (name2 << 8) + *name++;
|
||||
@@ -446,14 +457,15 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
case L('d','e'):
|
||||
{
|
||||
static const short stress_lengths_de[8] = {150,130, 200,200, 0, 0, 250,260};
|
||||
static const short stress_lengths_de[8] = {150,130, 200,200, 0, 0, 270,270};
|
||||
static const unsigned char stress_amps_de[] = {20,20, 20,20, 20,22, 22,20 };
|
||||
SetupTranslator(tr, stress_lengths_de, stress_amps_de);
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.word_gap = 0x8; // don't use linking phonemes
|
||||
tr->langopts.vowel_pause = 0x30;
|
||||
tr->langopts.param[LOPT_PREFIXES] = 1;
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x10; // devoice at end of word
|
||||
tr->langopts.param[LOPT_LONG_VOWEL_THRESHOLD] = 175/2;
|
||||
memcpy(tr->stress_lengths,stress_lengths_de,sizeof(tr->stress_lengths));
|
||||
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_ALLOW_SPACE | NUM_ORDINAL_DOT | NUM_ROMAN;
|
||||
SetLetterVowel(tr,'y');
|
||||
@@ -461,6 +473,20 @@ Translator *SelectTranslator(const char *name)
|
||||
}
|
||||
break;
|
||||
|
||||
case L('d','v'): // Divehi (Maldives)
|
||||
{
|
||||
SetupTranslator(tr,stress_lengths_ta,stress_amps_ta);
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
tr->letter_bits_offset = OFFSET_THAANA;
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
|
||||
SetLetterBitsRange(tr,LETTERGP_B,0x26,0x30); // vowel signs, and virama
|
||||
tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000
|
||||
tr->langopts.numbers = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case L('e','n'):
|
||||
{
|
||||
static const short stress_lengths_en[8] = {182,140, 220,220, 0,0, 248,275};
|
||||
@@ -522,7 +548,7 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
case L('e','o'):
|
||||
{
|
||||
static const short stress_lengths_eo[8] = {145, 145, 230, 170, 0, 0, 360, 370};
|
||||
static const short stress_lengths_eo[8] = {150, 150, 230, 180, 0, 0, 300, 320};
|
||||
static const unsigned char stress_amps_eo[] = {16,14, 20,20, 20,22, 22,21 };
|
||||
static const wchar_t eo_char_apostrophe[2] = {'l',0};
|
||||
|
||||
@@ -531,11 +557,11 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->charset_a0 = charsets[3]; // ISO-8859-3
|
||||
tr->char_plus_apostrophe = eo_char_apostrophe;
|
||||
|
||||
tr->langopts.word_gap = 1;
|
||||
// tr->langopts.word_gap = 1;
|
||||
tr->langopts.vowel_pause = 2;
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x6 | 0x10;
|
||||
tr->langopts.unstressed_wd1 = 3;
|
||||
// tr->langopts.unstressed_wd1 = 3;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED | NUM_ALLOW_SPACE | NUM_ROMAN;
|
||||
@@ -583,7 +609,6 @@ Translator *SelectTranslator(const char *name)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case L('e','u'): // basque
|
||||
{
|
||||
static const short stress_lengths_eu[8] = {200, 200, 200, 200, 0, 0, 210, 230}; // very weak stress
|
||||
@@ -604,6 +629,9 @@ Translator *SelectTranslator(const char *name)
|
||||
break;
|
||||
|
||||
|
||||
case L('e','t'): // Estonian
|
||||
tr->charset_a0 = charsets[4]; // ISO-8859-4
|
||||
// drop through to Finnish
|
||||
case L('f','i'): // Finnish
|
||||
{
|
||||
static const unsigned char stress_amps_fi[8] = {18,16, 22,22, 20,22, 22,22 };
|
||||
@@ -824,6 +852,26 @@ SetLengthMods(tr,3); // all equal
|
||||
}
|
||||
break;
|
||||
|
||||
case L('k','a'): // Georgian
|
||||
{
|
||||
// character codes offset by 0x1080
|
||||
static const char ka_vowels[] = {0x50,0x54,0x58,0x5d,0x63,0x75,0x77,0};
|
||||
static const char ka_consonants[] = {0x51,0x52,0x53,0x55,0x56,0x57,0x59,0x5a,0x5b,0x5c,0x5e,0x5f,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x76,0};
|
||||
SetupTranslator(tr,stress_lengths_ta,stress_amps_ta);
|
||||
memset(tr->letter_bits,0,sizeof(tr->letter_bits));
|
||||
SetLetterBits(tr,LETTERGP_A,ka_vowels);
|
||||
SetLetterBits(tr,LETTERGP_C,ka_consonants);
|
||||
SetLetterBits(tr,LETTERGP_VOWEL2,ka_vowels);
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = S_FINAL_NO_2;
|
||||
tr->letter_bits_offset = OFFSET_GEORGIAN;
|
||||
// tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
tr->langopts.max_initial_consonants = 7;
|
||||
tr->langopts.numbers = NUM_VIGESIMAL | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED |NUM_OMIT_1_THOUSAND | NUM_DFRACTION_5;
|
||||
}
|
||||
break;
|
||||
|
||||
case L('k','o'): // Korean, TEST
|
||||
{
|
||||
static const char ko_ivowels[] = {0x63,0x64,0x67,0x68,0x6d,0x72,0x74,0x75,0}; // y and i vowels
|
||||
@@ -913,7 +961,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x10; // devoice at end of word
|
||||
SetLetterVowel(tr,'y');
|
||||
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_ALLOW_SPACE | NUM_1900 | NUM_ORDINAL_DOT;
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_ALLOW_SPACE | NUM_1900 | NUM_ORDINAL_DOT;
|
||||
tr->langopts.ordinal_indicator = "e";
|
||||
tr->langopts.stress_flags = S_FIRST_PRIMARY;
|
||||
memcpy(tr->stress_lengths,stress_lengths_nl,sizeof(tr->stress_lengths));
|
||||
@@ -1083,6 +1131,7 @@ SetLengthMods(tr,3); // all equal
|
||||
break;
|
||||
|
||||
case L('s','w'): // Swahili
|
||||
case L('t','n'): // Setswana
|
||||
{
|
||||
static const short stress_lengths_sw[8] = {160, 170, 200, 200, 0, 0, 320, 340};
|
||||
static const unsigned char stress_amps_sw[] = {16,12, 19,19, 20,22, 22,21 };
|
||||
@@ -1103,15 +1152,14 @@ SetLengthMods(tr,3); // all equal
|
||||
case L('m','l'): // Malayalam
|
||||
case L('k','n'): // Kannada
|
||||
case L('m','r'): // Marathi
|
||||
case L('t','e'): // Telugu
|
||||
{
|
||||
static const short stress_lengths_ta[8] = {200, 200, 210, 210, 0, 0, 230, 230};
|
||||
static const unsigned char stress_amps_ta[8] = {18,18, 18,18, 20,20, 22,22 };
|
||||
|
||||
SetupTranslator(tr,stress_lengths_ta,stress_amps_ta);
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
|
||||
tr->langopts.spelling_stress = 1;
|
||||
tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000
|
||||
|
||||
if(name2 == L('t','a'))
|
||||
@@ -1127,6 +1175,7 @@ SetLengthMods(tr,3); // all equal
|
||||
if(name2 == L('m','l'))
|
||||
{
|
||||
tr->letter_bits_offset = OFFSET_MALAYALAM;
|
||||
tr->langopts.numbers = NUM_OMIT_1_THOUSAND;
|
||||
}
|
||||
else
|
||||
if(name2 == L('k','n'))
|
||||
@@ -1134,6 +1183,12 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->letter_bits_offset = OFFSET_KANNADA;
|
||||
tr->langopts.numbers = 0x1;
|
||||
}
|
||||
else
|
||||
if(name2 == L('t','e'))
|
||||
{
|
||||
tr->letter_bits_offset = OFFSET_TELUGU;
|
||||
tr->langopts.numbers = 0x1;
|
||||
}
|
||||
tr->langopts.param[LOPT_WORD_MERGE] = 1; // don't break vowels betwen words
|
||||
SetIndicLetters(tr); // call this after setting OFFSET_
|
||||
}
|
||||
|
||||
+59
-13
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -395,6 +395,9 @@ int IsAlpha(unsigned int c)
|
||||
if((c >= 0x300) && (c <= 0x36f))
|
||||
return(1); // combining accents
|
||||
|
||||
if((c >= 0x780) && (c <= 0x7b1))
|
||||
return(1); // taani/divehi (maldives)
|
||||
|
||||
if((c >= 0x1100) && (c <= 0x11ff))
|
||||
return(1); //Korean jamo
|
||||
|
||||
@@ -760,10 +763,11 @@ int ChangeEquivalentPhonemes(Translator *tr, int lang2, char *phonemes)
|
||||
|
||||
|
||||
|
||||
int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wtab)
|
||||
{//===========================================================================
|
||||
// word1 is terminated by space (0x20) character
|
||||
|
||||
char *word1;
|
||||
int word_length;
|
||||
int ix;
|
||||
char *p;
|
||||
@@ -781,7 +785,9 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
char unpron_phonemes[N_WORD_PHONEMES];
|
||||
char end_phonemes[N_WORD_PHONEMES];
|
||||
char word_copy[N_WORD_BYTES];
|
||||
char prefix_chars[41];
|
||||
char word_copy2[N_WORD_BYTES];
|
||||
int word_copy_length;
|
||||
char prefix_chars[0x3f + 2];
|
||||
int found=0;
|
||||
int end_flags;
|
||||
char c_temp; // save a character byte while we temporarily replace it with space
|
||||
@@ -795,6 +801,7 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
int emphasize_allcaps = 0;
|
||||
int wflags;
|
||||
int wmark;
|
||||
int was_unpronouncable = 0;
|
||||
WORD_TAB wtab_null[8];
|
||||
|
||||
// translate these to get pronunciations of plural 's' suffix (different forms depending on
|
||||
@@ -831,6 +838,7 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
}
|
||||
|
||||
// count the length of the word
|
||||
word1 = word_start;
|
||||
if(*word1 == ' ') word1++; // possibly a dot was replaced by space: $dot
|
||||
wordx = word1;
|
||||
|
||||
@@ -842,6 +850,9 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
word_length++;
|
||||
}
|
||||
|
||||
word_copy_length = wordx - word_start;
|
||||
memcpy(word_copy2, word_start, word_copy_length);
|
||||
|
||||
spell_word = 0;
|
||||
|
||||
if(option_sayas == SAYAS_KEY)
|
||||
@@ -958,8 +969,12 @@ if((wmark > 0) && (wmark < 8))
|
||||
|
||||
if((tr->langopts.numbers & NUM_ROMAN) || ((tr->langopts.numbers & NUM_ROMAN_CAPITALS) && (wflags & FLAG_ALL_UPPER)))
|
||||
{
|
||||
if((found = TranslateRoman(tr, word1, phonemes, wtab)) != 0)
|
||||
dictionary_flags[0] |= FLAG_ABBREV; // prevent emphasis if capitals
|
||||
if((wflags & FLAG_LAST_WORD) || !(wtab[1].flags & FLAG_NOSPACE))
|
||||
{
|
||||
// don't use Roman number if this word is not separated from the next word (eg. "XLTest")
|
||||
if((found = TranslateRoman(tr, word1, phonemes, wtab)) != 0)
|
||||
dictionary_flags[0] |= FLAG_ABBREV; // prevent emphasis if capitals
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1011,6 +1026,7 @@ if((wmark > 0) && (wmark < 8))
|
||||
{
|
||||
// This word looks "unpronouncable", so speak letters individually until we
|
||||
// find a remainder that we can pronounce.
|
||||
was_unpronouncable = FLAG_WAS_UNPRONOUNCABLE;
|
||||
emphasize_allcaps = 0;
|
||||
|
||||
if(wordx[0] == '\'')
|
||||
@@ -1084,10 +1100,10 @@ if((wmark > 0) && (wmark < 8))
|
||||
|
||||
found = 0;
|
||||
confirm_prefix = 1;
|
||||
while(end_type & SUFX_P)
|
||||
for (int loopcount = 0; (loopcount < 50) && (end_type & SUFX_P); loopcount++)
|
||||
{
|
||||
// Found a standard prefix, remove it and retranslate
|
||||
|
||||
// loopcount guards against an endless loop
|
||||
if(confirm_prefix && !(end_type & SUFX_B))
|
||||
{
|
||||
int end2;
|
||||
@@ -1484,6 +1500,8 @@ if(dictionary_flags2[0] & FLAG_ABBREV)
|
||||
ApplySpecialAttribute2(tr,word_phonemes,dictionary_flags[0]);
|
||||
}
|
||||
|
||||
dictionary_flags[0] |= was_unpronouncable;
|
||||
memcpy(word_start, word_copy2, word_copy_length);
|
||||
return(dictionary_flags[0]);
|
||||
} // end of TranslateWord
|
||||
|
||||
@@ -1709,10 +1727,11 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
{
|
||||
char *p2;
|
||||
int ok = 1;
|
||||
int flags2 = 0;
|
||||
unsigned int flags2[2];
|
||||
int c_word2;
|
||||
char ph_buf[N_WORD_PHONEMES];
|
||||
|
||||
flags2[0] = 0;
|
||||
sylimit = tr->langopts.param[LOPT_COMBINE_WORDS];
|
||||
|
||||
// LANG=cs,sk
|
||||
@@ -1729,12 +1748,15 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
if(ok != 0)
|
||||
{
|
||||
strcpy(ph_buf,word_phonemes);
|
||||
flags2 = TranslateWord(translator, p2+1, 0, wtab+1);
|
||||
|
||||
flags2[0] = TranslateWord(translator, p2+1, 0, wtab+1);
|
||||
if(flags2[0] & FLAG_WAS_UNPRONOUNCABLE)
|
||||
ok = 0;
|
||||
|
||||
if(sylimit & 0x100)
|
||||
{
|
||||
// only if the second word has $alt attribute
|
||||
if((flags2 & FLAG_ALT_TRANS) == 0)
|
||||
if((flags2[0] & FLAG_ALT_TRANS) == 0)
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
@@ -1765,7 +1787,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
else
|
||||
{
|
||||
if(flags == 0)
|
||||
flags = flags2; // no flags for the combined word, so use flags from the second word eg. lang-hu "nem december 7-e"
|
||||
flags = flags2[0]; // no flags for the combined word, so use flags from the second word eg. lang-hu "nem december 7-e"
|
||||
flags |= FLAG_SKIPWORDS;
|
||||
dictionary_skipwords = 1;
|
||||
}
|
||||
@@ -2288,6 +2310,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int cc;
|
||||
unsigned int source_index=0;
|
||||
unsigned int prev_source_index=0;
|
||||
int source_index_word=0;
|
||||
int prev_in;
|
||||
int prev_out=' ';
|
||||
int prev_out2;
|
||||
@@ -2329,6 +2352,11 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int tone;
|
||||
int tone2;
|
||||
|
||||
if(tr==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
p_textinput = (unsigned char *)vp_input;
|
||||
p_wchar_input = (wchar_t *)vp_input;
|
||||
|
||||
@@ -2431,7 +2459,7 @@ p = source;
|
||||
words[0].flags = 0;
|
||||
finished = 0;
|
||||
|
||||
for(j=0; charix[j]==0; j++);
|
||||
for(j=0; charix[j]<=0; j++);
|
||||
words[0].sourceix = charix[j];
|
||||
k = 0;
|
||||
while(charix[j] != 0)
|
||||
@@ -2774,6 +2802,13 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
else
|
||||
if(c == '.')
|
||||
{
|
||||
if(prev_out == '.')
|
||||
{
|
||||
// multiple dots, separate by spaces. Note >3 dots has been replaced by elipsis
|
||||
c = ' ';
|
||||
space_inserted = 1;
|
||||
}
|
||||
else
|
||||
if(!(words[word_count-1].flags & FLAG_NOSPACE) && IsAlpha(prev_in))
|
||||
{
|
||||
// dot after a word, with space following, probably an abbreviation
|
||||
@@ -2878,9 +2913,20 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
|
||||
if(space_inserted)
|
||||
{
|
||||
words[word_count].length = source_index - words[word_count].sourceix;
|
||||
// count the number of characters since the start of the word
|
||||
j = 0;
|
||||
k = source_index - 1;
|
||||
while((k >= source_index_word) && (charix[k] != 0))
|
||||
{
|
||||
if(charix[k] > 0) // don't count initial bytes of multi-byte character
|
||||
j++;
|
||||
k--;
|
||||
}
|
||||
words[word_count].length = j;
|
||||
}
|
||||
|
||||
source_index_word = source_index;
|
||||
|
||||
// end of 'word'
|
||||
sbuf[ix++] = ' ';
|
||||
|
||||
|
||||
+2
-6
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
|
||||
* Copyright (C) 2005 to 2011 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
#define FLAG_ALLOW_DOT 0x01000000 // ignore '.' after word (abbreviation)
|
||||
#define FLAG_NEEDS_DOT 0x02000000 // only if the word is followed by a dot
|
||||
|
||||
#define FLAG_WAS_UNPRONOUNCABLE 0x04000000 // the unpronounceable routine was used
|
||||
#define FLAG_MAX3 0x08000000 // limit to 3 repeats
|
||||
#define FLAG_PAUSE1 0x10000000 // shorter prepause
|
||||
#define FLAG_TEXTMODE 0x20000000 // word translates to replacement text, not phonemes
|
||||
@@ -485,10 +485,6 @@ typedef struct {
|
||||
|
||||
|
||||
|
||||
#define NUM_SEP_DOT 0x0008 // . , for thousands and decimal separator
|
||||
#define NUM_SEP_SPACE 0x1000 // allow space as thousands separator (in addition to langopts.thousands_sep)
|
||||
#define NUM_DEC_IT 0x2000 // (LANG=it) speak post-decimal-point digits as a combined number not as single digits
|
||||
|
||||
typedef struct
|
||||
{//===========
|
||||
|
||||
|
||||
+13
-2
@@ -130,10 +130,15 @@ void PlayWavFile(const char *fname)
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
wxSound(wxString(fname,wxConvLocal)).Play(wxSOUND_SYNC);
|
||||
#else
|
||||
sprintf(command,"play %s",fname);
|
||||
// wxSound(wxString(fname,wxConvLocal)).Play(wxSOUND_SYNC); // This gives a click at the start of each play
|
||||
sprintf(command,"aplay %s",fname);
|
||||
if(system(command) == -1)
|
||||
{
|
||||
wxLogError(_T("Failed to run system command:\n\n"+wxString(command,wxConvLocal)));
|
||||
sprintf(command,"play %s",fname);
|
||||
if(system(command) == -1)
|
||||
{
|
||||
wxLogError(_T("Failed to run system command:\n\n"+wxString(command,wxConvLocal)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -409,6 +414,12 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
|
||||
static int n_ph_list;
|
||||
static PHONEME_LIST ph_list[N_PH_LIST+1];
|
||||
|
||||
if(translator==NULL)
|
||||
{
|
||||
wxLogError(_T("Voice not set"));
|
||||
return;
|
||||
}
|
||||
|
||||
option_phonemes = 0;
|
||||
|
||||
switch(event.GetId())
|
||||
|
||||
+3
-1
@@ -411,7 +411,7 @@ void VoiceReset(int tone_only)
|
||||
voice->samplerate = 22050;
|
||||
memset(voice->klattv,0,sizeof(voice->klattv));
|
||||
|
||||
speed.fast_settings[0] = 350;
|
||||
speed.fast_settings[0] = 400;
|
||||
speed.fast_settings[1] = 800;
|
||||
speed.fast_settings[2] = 175;
|
||||
|
||||
@@ -1506,6 +1506,8 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found)
|
||||
}
|
||||
|
||||
// index the sorted list by the required variant number
|
||||
if(ix2 == 0)
|
||||
return(NULL);
|
||||
vp = voices2[voice_select2.variant % ix2];
|
||||
|
||||
if(vp->variant != 0)
|
||||
|
||||
@@ -63,6 +63,7 @@ static uint32_t total_samples_skipped;
|
||||
//
|
||||
static uint32_t last_play_position=0;
|
||||
|
||||
static uint32_t wave_samplerate;
|
||||
//>
|
||||
// wave_init
|
||||
//
|
||||
|
||||
@@ -1965,6 +1965,10 @@ int WavegenFill2(int fill_zeros)
|
||||
if((wdata.amplitude_fmt = q[1]) == 0)
|
||||
wdata.amplitude_fmt = 100; // percentage, but value=0 means 100%
|
||||
break;
|
||||
|
||||
case WCMD_SONIC_SPEED:
|
||||
sonicSpeed = (double)q[1] / 1024;
|
||||
break;
|
||||
}
|
||||
|
||||
if(result==0)
|
||||
@@ -1999,6 +2003,9 @@ static int SpeedUp(short *outbuf, int length_in, int length_out, int end_of_text
|
||||
sonicWriteShortToStream(sonicSpeedupStream, outbuf, length_in);
|
||||
}
|
||||
|
||||
if(sonicSpeedupStream == NULL)
|
||||
return(0);
|
||||
|
||||
if(end_of_text)
|
||||
{
|
||||
sonicFlushStream(sonicSpeedupStream);
|
||||
|
||||
Reference in New Issue
Block a user