mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-07 07:23:52 +00:00
[1.44.42]
Phoneme definitions. New keyword "prevoice", always add murmer before a voiced stop, not only after a vowel. Fixed bug in nextVowel() condition. Fixed bug is condition "isRhotic". Command line options. On Windows, -- means don't treat following arguments as options. --help output now should the espeak-data path. Tools->Lexicon. Redesign Lexicon processing for Russian and Bulgarian. Numbers. Fixes for Hungarian ordinal numbers. Fixed bug where double .. was ignored. Fixed bug in reporting word event lengths in callbacks. Fixed bug in reporting marker event positions in callbacks, when non-ascii text. SSML. Allow single as well as double quotes around strings. Fix bugs in SSML "prosody rate". Speed. Only use Sonic speedups greater than x2. Use custom eSpeak speed settings when Sonic speedup is used. Mbrola. Look for Mbrola voice also at /usr/share/mbrola/xx/xx espeakedit. Try "aplay" and then "play" to play sound. Languages: Kannada (kn) now in official release. Esperanto (eo) change prosody. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@257 d46cf337-b52f-0410-862d-fd96e6ae7743
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