mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-11 00:26:08 +00:00
[1.47.14]
Language changes: an, en, es, fa, gu, it, pt, ta, te. Voice files: added attribute 'dictdialect', eg: dictdialect en-us uses the US English voice to speak words or rules which are marked with _^_EN git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@366 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+9
-4
@@ -235,6 +235,7 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
|
||||
unsigned char rb;
|
||||
unsigned char c;
|
||||
char *p;
|
||||
char *p_end;
|
||||
int ix;
|
||||
int match_type;
|
||||
int finished=0;
|
||||
@@ -245,10 +246,10 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
|
||||
int condition_num=0;
|
||||
int at_start = 0;
|
||||
const char *name;
|
||||
char buf[60];
|
||||
char buf_pre[60];
|
||||
char buf[200];
|
||||
char buf_pre[200];
|
||||
char suffix[20];
|
||||
static char output[60];
|
||||
static char output[80];
|
||||
|
||||
static char symbols[] =
|
||||
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
|
||||
@@ -367,6 +368,8 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
|
||||
*p = 0;
|
||||
|
||||
p = output;
|
||||
p_end = p + sizeof(output) - 1;
|
||||
|
||||
if(linenum > 0)
|
||||
{
|
||||
sprintf(p,"%5d:\t",linenum);
|
||||
@@ -381,12 +384,14 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
|
||||
{
|
||||
if(at_start)
|
||||
*p++ = '_';
|
||||
while(--ix >= 0)
|
||||
while((--ix >= 0) && (p < p_end-3))
|
||||
*p++ = buf_pre[ix];
|
||||
*p++ = ')';
|
||||
*p++ = ' ';
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
buf[p_end - p] = 0; // prevent overflow in output[]
|
||||
strcat(p,buf);
|
||||
ix = strlen(output);
|
||||
while(ix < 8)
|
||||
|
||||
+22
-9
@@ -526,7 +526,7 @@ unsigned short ipa1[96] = {
|
||||
};
|
||||
|
||||
#define N_PHON_OUT 500 // realloc increment
|
||||
static char *phon_out_buf = NULL;
|
||||
static char *phon_out_buf = NULL; // passes the result of GetTranslatedPhonemeString()
|
||||
static int phon_out_size = 0;
|
||||
|
||||
|
||||
@@ -663,6 +663,16 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)
|
||||
use_ipa = phoneme_mode & 0x10;
|
||||
use_tie = phoneme_mode & 0x0f;
|
||||
|
||||
if(phon_out_buf == NULL)
|
||||
{
|
||||
phon_out_size = N_PHON_OUT;
|
||||
if((phon_out_buf = (char *)realloc(phon_out_buf, phon_out_size)) == NULL)
|
||||
{
|
||||
phon_out_size = 0;
|
||||
return("");
|
||||
}
|
||||
}
|
||||
|
||||
if(use_tie >= 3)
|
||||
{
|
||||
// separate individual phonemes with underscores
|
||||
@@ -670,6 +680,7 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)
|
||||
use_tie = 0;
|
||||
}
|
||||
|
||||
|
||||
for(ix=1; ix<(n_phoneme_list-2); ix++)
|
||||
{
|
||||
buf = phon_buf;
|
||||
@@ -2911,9 +2922,10 @@ int TransposeAlphabet(Translator *tr, char *text)
|
||||
int acc;
|
||||
int pairs_start;
|
||||
const short *pairs_list;
|
||||
char buf[N_WORD_BYTES];
|
||||
int bufix;
|
||||
char buf[N_WORD_BYTES+1];
|
||||
|
||||
|
||||
p2 = buf;
|
||||
offset = tr->transpose_min - 1;
|
||||
min = tr->transpose_min;
|
||||
max = tr->transpose_max;
|
||||
@@ -2921,6 +2933,7 @@ int TransposeAlphabet(Translator *tr, char *text)
|
||||
|
||||
pairs_start = max - min + 2;
|
||||
|
||||
bufix = 0;
|
||||
do {
|
||||
p += utf8_in(&c,p);
|
||||
if(c != 0)
|
||||
@@ -2929,30 +2942,30 @@ int TransposeAlphabet(Translator *tr, char *text)
|
||||
{
|
||||
if(map == NULL)
|
||||
{
|
||||
*p2++ = c - offset;
|
||||
buf[bufix++] = c - offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the code from the transpose map
|
||||
if(map[c - min] > 0)
|
||||
{
|
||||
*p2++ = map[c - min];
|
||||
buf[bufix++] = map[c - min];
|
||||
}
|
||||
else
|
||||
{
|
||||
p2 += utf8_out(c,p2);
|
||||
all_alpha=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p2 += utf8_out(c,p2);
|
||||
all_alpha=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (c != 0);
|
||||
*p2 = 0;
|
||||
} while ((c != 0) && (bufix < N_WORD_BYTES));
|
||||
buf[bufix] = 0;
|
||||
|
||||
if(all_alpha)
|
||||
{
|
||||
|
||||
@@ -92,10 +92,6 @@ int frame_x, frame_y, frame_w, frame_h;
|
||||
|
||||
int adding_page = 0; // fix for wxWidgets (2,8,7) bug, adding first page to a wxNotebook gives emptystring for GetPageTex() in Notebook_Page_Changed event.
|
||||
|
||||
wxFont FONT_SMALL(8,wxSWISS,wxNORMAL,wxNORMAL);
|
||||
wxFont FONT_MEDIUM(9,wxSWISS,wxNORMAL,wxNORMAL);
|
||||
wxFont FONT_NORMAL(10,wxSWISS,wxNORMAL,wxNORMAL);
|
||||
|
||||
IMPLEMENT_APP(MyApp)
|
||||
|
||||
wxString AppName = _T("espeakedit");
|
||||
|
||||
+7
-6
@@ -110,11 +110,6 @@ extern TranslDlg *transldlg;
|
||||
extern wchar_t ipa1[256];
|
||||
|
||||
|
||||
|
||||
extern wxFont FONT_SMALL;
|
||||
extern wxFont FONT_MEDIUM;
|
||||
extern wxFont FONT_NORMAL;
|
||||
|
||||
enum {
|
||||
MENU_QUIT = 1,
|
||||
MENU_SPECTRUM,
|
||||
@@ -183,5 +178,11 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
|
||||
// wxWidgets 3 name changes
|
||||
#if wxCHECK_VERSION(3, 0, 0)
|
||||
#define wxOPEN wxFD_OPEN
|
||||
#define wxSAVE wxFD_SAVE
|
||||
#define WXK_PRIOR WXK_PAGEUP
|
||||
#define WXK_NEXT WXK_PAGEDOWN
|
||||
#endif
|
||||
|
||||
|
||||
+9
-9
@@ -1407,7 +1407,7 @@ static int LookupThousands(Translator *tr, int value, int thousandplex, int thou
|
||||
} // end f LookupThousands
|
||||
|
||||
|
||||
static int LookupNum2(Translator *tr, int value, const int control, char *ph_out)
|
||||
static int LookupNum2(Translator *tr, int value, int thousandplex, const int control, char *ph_out)
|
||||
{//=============================================================================
|
||||
// Lookup a 2 digit number
|
||||
// control bit 0: ordinal number
|
||||
@@ -1506,8 +1506,8 @@ static int LookupNum2(Translator *tr, int value, const int control, char *ph_out
|
||||
else
|
||||
{
|
||||
// followed by hundreds or thousands etc
|
||||
if(tr->langopts.numbers2 & NUM2_ORDINAL_AND_THOUSANDS)
|
||||
sprintf(string, "_%do", value);
|
||||
if((tr->langopts.numbers2 & NUM2_ORDINAL_AND_THOUSANDS) && (thousandplex <= 1))
|
||||
sprintf(string, "_%do", value); // LANG=TA
|
||||
else
|
||||
sprintf(string, "_%da", value);
|
||||
found = Lookup(tr, string, ph_digits);
|
||||
@@ -1615,8 +1615,8 @@ static int LookupNum2(Translator *tr, int value, const int control, char *ph_out
|
||||
else if(((control & 2) == 0) || ((tr->langopts.numbers & NUM_SWAP_TENS) != 0))
|
||||
{
|
||||
// followed by hundreds or thousands (or tens)
|
||||
if(tr->langopts.numbers2 & NUM2_ORDINAL_AND_THOUSANDS)
|
||||
sprintf(string, "_%do", units);
|
||||
if((tr->langopts.numbers2 & NUM2_ORDINAL_AND_THOUSANDS) && (thousandplex <= 1))
|
||||
sprintf(string, "_%do", units); // LANG=TA, only for 100s, 1000s
|
||||
else
|
||||
sprintf(string, "_%da", units);
|
||||
found = Lookup(tr, string, ph_digits);
|
||||
@@ -1792,7 +1792,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
x = 8; // use variant (feminine) for before thousands and millions
|
||||
if(tr->translator_name == L('m','l'))
|
||||
x = 0x208;
|
||||
LookupNum2(tr, hundreds/10, x, ph_digits);
|
||||
LookupNum2(tr, hundreds/10, thousandplex, x, ph_digits);
|
||||
}
|
||||
|
||||
if(tr->langopts.numbers2 & 0x200)
|
||||
@@ -1875,7 +1875,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
|
||||
if(say_one_hundred != 0)
|
||||
{
|
||||
LookupNum2(tr, hundreds, 0, ph_digits);
|
||||
LookupNum2(tr, hundreds, thousandplex, 0, ph_digits);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1934,7 +1934,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
x |= 0x208; // use #f form for both tens and units
|
||||
}
|
||||
|
||||
if(LookupNum2(tr, tensunits, x | (control & 0x100), buf2) != 0)
|
||||
if(LookupNum2(tr, tensunits, thousandplex, x | (control & 0x100), buf2) != 0)
|
||||
{
|
||||
if(tr->langopts.numbers & NUM_SINGLE_AND)
|
||||
ph_hundred_and[0] = 0; // don't put 'and' after 'hundred' if there's 'and' between tens and units
|
||||
@@ -2362,7 +2362,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
{
|
||||
// speak any remaining decimal fraction digits individually
|
||||
value = word[n_digits++] - '0';
|
||||
LookupNum2(tr, value, 2, buf1);
|
||||
LookupNum2(tr, value, 0, 2, buf1);
|
||||
len = strlen(ph_out);
|
||||
sprintf(&ph_out[len],"%c%s", phonEND_WORD, buf1);
|
||||
}
|
||||
|
||||
+8
-3
@@ -732,8 +732,12 @@ void sync_espeak_SetPunctuationList(const wchar_t *punctlist)
|
||||
my_unique_identifier = 0;
|
||||
my_user_data = NULL;
|
||||
|
||||
wcsncpy(option_punctlist, punctlist, N_PUNCTLIST);
|
||||
option_punctlist[N_PUNCTLIST-1] = 0;
|
||||
option_punctlist[0] = 0;
|
||||
if(punctlist != NULL)
|
||||
{
|
||||
wcsncpy(option_punctlist, punctlist, N_PUNCTLIST);
|
||||
option_punctlist[N_PUNCTLIST-1] = 0;
|
||||
}
|
||||
} // end of sync_espeak_SetPunctuationList
|
||||
|
||||
|
||||
@@ -792,8 +796,9 @@ ENTER("espeak_Initialize");
|
||||
}
|
||||
|
||||
// buflength is in mS, allocate 2 bytes per sample
|
||||
if(buf_length == 0)
|
||||
if((buf_length == 0) || (output_type == AUDIO_OUTPUT_PLAYBACK) || (output_type == AUDIO_OUTPUT_SYNCH_PLAYBACK))
|
||||
buf_length = 200;
|
||||
|
||||
outbuf_size = (buf_length * samplerate)/500;
|
||||
outbuf = (unsigned char*)realloc(outbuf,outbuf_size);
|
||||
if((out_start = outbuf) == NULL)
|
||||
|
||||
@@ -187,6 +187,8 @@ ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, cons
|
||||
output: the audio data can either be played by eSpeak or passed back by the SynthCallback function.
|
||||
|
||||
buflength: The length in mS of sound buffers passed to the SynthCallback function.
|
||||
Value=0 gives a default of 200mS.
|
||||
This paramater is only used for AUDIO_OUTPUT_RETRIEVAL and AUDIO_OUTPUT_SYNCHRONOUS modes.
|
||||
|
||||
path: The directory which contains the espeak-data directory, or NULL for the default location.
|
||||
|
||||
|
||||
+9
-6
@@ -50,7 +50,7 @@ wxBrush BRUSH_MARKER[N_MARKERS] = {
|
||||
wxBrush(wxColour(200,0,255),wxSOLID),
|
||||
wxBrush(wxColour(200,0,255),wxSOLID),
|
||||
wxBrush(wxColour(255,0,200),wxSOLID) };
|
||||
|
||||
|
||||
#define DRAWPEAKWIDTH 2000
|
||||
#define PEAKSHAPEW 256
|
||||
|
||||
@@ -86,7 +86,7 @@ float SpectTilt(int value, int freq)
|
||||
}
|
||||
else
|
||||
{
|
||||
return(sqrt(y));
|
||||
return(sqrt(y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,9 @@ SpectFrame::SpectFrame(SpectFrame *copy)
|
||||
|
||||
int ix;
|
||||
|
||||
FONT_SMALL = wxFont(8, wxSWISS, wxNORMAL, wxNORMAL); // wxWidgets 3, Font creation needs a GTK+ Window
|
||||
FONT_MEDIUM = wxFont(9, wxSWISS, wxNORMAL, wxNORMAL);
|
||||
|
||||
selected = 0;
|
||||
keyframe = 0;
|
||||
spect = NULL;
|
||||
@@ -210,7 +213,7 @@ int SpectFrame::ImportSPC2(wxInputStream& stream, float &time_acc)
|
||||
|
||||
stream.Read(&cy,44);
|
||||
size = SPC2_size_cycle(&cy);
|
||||
|
||||
|
||||
p = (CYCLE *)malloc(size);
|
||||
if(p == NULL)
|
||||
{
|
||||
@@ -218,14 +221,14 @@ int SpectFrame::ImportSPC2(wxInputStream& stream, float &time_acc)
|
||||
}
|
||||
stream.SeekI(-44,wxFromCurrent);
|
||||
stream.Read(p,size);
|
||||
|
||||
|
||||
time = time_acc;
|
||||
len = cy.length / 15625.0;
|
||||
time_acc += len;
|
||||
pitch = float(cy.pitch) / 16.0;
|
||||
nx = cy.n_harm;
|
||||
dx = pitch;
|
||||
|
||||
|
||||
for(ix=0; ix<7; ix++)
|
||||
{
|
||||
peaks[ix].pkfreq = cy.peak_data[ix].freq * peak_factor[ix];
|
||||
@@ -244,7 +247,7 @@ int SpectFrame::ImportSPC2(wxInputStream& stream, float &time_acc)
|
||||
}
|
||||
if(((cy.flags & 0x80)==0) && (peaks[1].pkheight > 0))
|
||||
keyframe = 1;
|
||||
|
||||
|
||||
if(cy.flags & 0x08)
|
||||
markers |= 4;
|
||||
if(cy.flags & 0x10)
|
||||
|
||||
@@ -171,6 +171,8 @@ public:
|
||||
private:
|
||||
void DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitude, double scalex);
|
||||
|
||||
wxFont FONT_SMALL;
|
||||
wxFont FONT_MEDIUM;
|
||||
};
|
||||
|
||||
class SpectSeq
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.47.13 22.Oct.13";
|
||||
const char *version_string = "1.47.14 29.Nov.13";
|
||||
const int version_phdata = 0x014709;
|
||||
|
||||
int option_device_number = -1;
|
||||
|
||||
@@ -1046,7 +1046,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels
|
||||
tr->langopts.param[LOPT_REDUCE] = 1; // reduce vowels even if phonemes are specified in it_list
|
||||
tr->langopts.param[LOPT_ALT] = 2; // call ApplySpecialAttributes2() if a word has $alt or $alt2
|
||||
tr->langopts.numbers = NUM_SINGLE_VOWEL | NUM_OMIT_1_HUNDRED |NUM_DECIMAL_COMMA | NUM_ROMAN | NUM_DFRACTION_1;
|
||||
tr->langopts.numbers = NUM_SINGLE_VOWEL | NUM_OMIT_1_HUNDRED |NUM_DECIMAL_COMMA | NUM_ROMAN | NUM_DFRACTION_1 | NUM_ROMAN_CAPITALS | NUM_ROMAN_AFTER;
|
||||
tr->langopts.accents = 2; // Say "Capital" after the letter.
|
||||
SetLetterVowel(tr,'y');
|
||||
}
|
||||
|
||||
+33
-2
@@ -409,7 +409,7 @@ int IsAlpha(unsigned int c)
|
||||
if(c == 0x0605)
|
||||
return(1);
|
||||
|
||||
if((c >= 0x64b) && (c <= 0x65e))
|
||||
if((c == 0x670) || ((c >= 0x64b) && (c <= 0x65e)))
|
||||
return(1); // arabic vowel marks
|
||||
|
||||
if((c >= 0x300) && (c <= 0x36f))
|
||||
@@ -1714,8 +1714,26 @@ int SetTranslator2(const char *new_language)
|
||||
{//=========================================
|
||||
// Set translator2 to a second language
|
||||
int new_phoneme_tab;
|
||||
const char *new_phtab_name;
|
||||
int bitmap;
|
||||
int dialect = 0;
|
||||
|
||||
if((new_phoneme_tab = SelectPhonemeTableName(new_language)) >= 0)
|
||||
new_phtab_name = new_language;
|
||||
if((bitmap = translator->langopts.dict_dialect) != 0)
|
||||
{
|
||||
if((bitmap & (1 << DICTDIALECT_EN_US)) && (strcmp(new_language, "en") == 0))
|
||||
{
|
||||
new_phtab_name = "en-us";
|
||||
dialect = DICTDIALECT_EN_US;
|
||||
}
|
||||
if((bitmap & (1 << DICTDIALECT_ES_LA)) && (strcmp(new_language, "es") == 0))
|
||||
{
|
||||
new_phtab_name = "es-la";
|
||||
dialect = DICTDIALECT_ES_LA;
|
||||
}
|
||||
}
|
||||
|
||||
if((new_phoneme_tab = SelectPhonemeTableName(new_phtab_name)) >= 0)
|
||||
{
|
||||
if((translator2 != NULL) && (strcmp(new_language,translator2_language) != 0))
|
||||
{
|
||||
@@ -1735,6 +1753,19 @@ int SetTranslator2(const char *new_language)
|
||||
new_phoneme_tab = -1;
|
||||
translator2_language[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dialect == DICTDIALECT_EN_US)
|
||||
{
|
||||
// en-us
|
||||
translator2->dict_condition = 0x48; // bits 3, 6
|
||||
translator2->langopts.param[LOPT_REDUCE_T] = 1;
|
||||
}
|
||||
if(dialect == DICTDIALECT_ES_LA)
|
||||
{
|
||||
translator2->dict_condition = 0x04; // bit 2
|
||||
}
|
||||
}
|
||||
translator2->phoneme_tab_ix = new_phoneme_tab;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,6 +558,10 @@ typedef struct {
|
||||
int max_lengthmod;
|
||||
int lengthen_tonic; // lengthen the tonic syllable
|
||||
int suffix_add_e; // replace a suffix (which has the SUFX_E flag) with this character
|
||||
|
||||
#define DICTDIALECT_EN_US 1 // bit number
|
||||
#define DICTDIALECT_ES_LA 2
|
||||
int dict_dialect; // bitmap, use a dialect for foreign words
|
||||
} LANGUAGE_OPTIONS;
|
||||
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ enum {
|
||||
V_SPEED,
|
||||
V_DICTMIN,
|
||||
V_ALPHABET2,
|
||||
V_DICTDIALECT,
|
||||
|
||||
// these need a phoneme table to have been specified
|
||||
V_REPLACE,
|
||||
@@ -162,6 +163,7 @@ static MNEM_TAB keyword_tab[] = {
|
||||
{"speed", V_SPEED},
|
||||
{"dict_min", V_DICTMIN},
|
||||
{"alphabet2", V_ALPHABET2},
|
||||
{"dictdialect", V_DICTDIALECT},
|
||||
|
||||
// these just set a value in langopts.param[]
|
||||
{"l_dieresis", 0x100+LOPT_DIERESES},
|
||||
@@ -175,6 +177,13 @@ static MNEM_TAB keyword_tab[] = {
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static MNEM_TAB dict_dialects[] = {
|
||||
{"en-us", DICTDIALECT_EN_US},
|
||||
{"es-la", DICTDIALECT_ES_LA},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
#define N_VOICE_VARIANTS 12
|
||||
const char variants_either[N_VOICE_VARIANTS] = {1,2,12,3,13,4,14,5,11,0};
|
||||
const char variants_male[N_VOICE_VARIANTS] = {1,2,3,4,5,6,0};
|
||||
@@ -1028,6 +1037,21 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
}
|
||||
break;
|
||||
|
||||
case V_DICTDIALECT:
|
||||
// specify a dialect to use for foreign words, eg, en-us for _^_EN
|
||||
if(sscanf(p, "%s", name1) == 1)
|
||||
{
|
||||
if((ix = LookupMnem(dict_dialects, name1)) > 0)
|
||||
{
|
||||
langopts->dict_dialect |= (1 << ix);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "dictdialect name '%s' not recognized\n", name1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if((key & 0xff00) == 0x100)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user