Merge branch 'master' into build

This commit is contained in:
Reece Dunn
2011-03-14 22:39:19 +00:00
130 changed files with 4808 additions and 1934 deletions
+3 -2
View File
@@ -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
View File
@@ -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;
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+6 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+1
View File
@@ -63,6 +63,7 @@ static uint32_t total_samples_skipped;
//
static uint32_t last_play_position=0;
static uint32_t wave_samplerate;
//>
// wave_init
//
+7
View File
@@ -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);