mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
[1.29.04] Allow up to 10 parts in multiple-word entries in *_list files.
lang=hr: Recognize Roman numbers only when all-capitals. lang=en: Change to word-final [I] (phoneme [i]). git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@84 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+18
-17
@@ -5092,23 +5092,24 @@
|
||||
.group
|
||||
|
||||
// non-ascii characters with specified pronunciations
|
||||
é eI
|
||||
_) é I2
|
||||
ä E
|
||||
ë E
|
||||
ï i:
|
||||
ö 3:
|
||||
?5 ö VR
|
||||
ü u:
|
||||
ç s
|
||||
ß s
|
||||
_) ß (_ b'i:t@_
|
||||
č tS
|
||||
š S
|
||||
ş S
|
||||
ž Z
|
||||
þ T
|
||||
ð D
|
||||
é eI
|
||||
_) é I2
|
||||
ê E:
|
||||
ä E
|
||||
ë E
|
||||
ï i:
|
||||
ö 3:
|
||||
?5 ö VR
|
||||
ü u:
|
||||
ç s
|
||||
ß s
|
||||
_) ß (_ b'i:t@_
|
||||
č tS
|
||||
š S
|
||||
ş S
|
||||
ž Z
|
||||
þ T
|
||||
ð D
|
||||
|
||||
|
||||
\\ bakstroUk
|
||||
|
||||
+2
-2
@@ -169,10 +169,10 @@ _1M4 b'ilijUn
|
||||
?2 _0M4 b'ilijOna
|
||||
?2 _1M4 b'ilijOn
|
||||
_dpt _:z'a*Ez_
|
||||
|
||||
_roman @-*'imsko
|
||||
|
||||
// not Roman numerals
|
||||
vi ti
|
||||
// vi vi // not needed if only all-capitals are spoken as Roman numbers
|
||||
|
||||
|
||||
// Abbreviations
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,7 @@
|
||||
|
||||
[Setup]
|
||||
AppName=eSpeak
|
||||
AppVerName=eSpeak version 1.29.02
|
||||
AppVerName=eSpeak version 1.29.03
|
||||
|
||||
DefaultDirName={pf}\eSpeak
|
||||
DefaultGroupName=eSpeak
|
||||
@@ -159,7 +159,7 @@ begin
|
||||
|
||||
case lang1 of
|
||||
'af': value := $436;
|
||||
'bs': value := $141a;
|
||||
'bs': value := $41a; // should be $141a but Jaws crashes on startup
|
||||
'cs': value := $405;
|
||||
'cy': value := $452;
|
||||
'de': value := $407;
|
||||
|
||||
@@ -298,10 +298,100 @@ STDMETHODIMP CTTSEngObj::SetObjectToken(ISpObjectToken * pToken)
|
||||
//=== ISpTTSEngine Implementation ============================================
|
||||
//
|
||||
|
||||
#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer
|
||||
|
||||
static char *phoneme_names_en[] = {
|
||||
NULL,NULL,NULL," ",NULL,NULL,NULL,NULL,"'",",",
|
||||
"A:","a","V","0","aU","@","aI",
|
||||
"b","tS","d","D","E","3:","eI",
|
||||
"f","g","h","I","i:","dZ","k",
|
||||
"l","m","n","N","oU","OI","p",
|
||||
"r","s","S","t","T","U","u:",
|
||||
"v","w","j","z","Z",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
int CTTSEngObj::WritePhonemes(SPPHONEID *phons, wchar_t *pW)
|
||||
{//=========================================================
|
||||
int ph;
|
||||
int ix=2;
|
||||
int skip=0;
|
||||
int maxph = 49;
|
||||
char *p;
|
||||
int j;
|
||||
int lang;
|
||||
char **phoneme_names;
|
||||
char phbuf[200];
|
||||
espeak_VOICE *voice;
|
||||
|
||||
voice = espeak_GetCurrentVoice();
|
||||
lang = (voice->languages[1] << 8) + (voice->languages[2]);
|
||||
|
||||
phoneme_names = phoneme_names_en;
|
||||
maxph = 0;
|
||||
|
||||
if(lang == L('e','n'))
|
||||
{
|
||||
phoneme_names = phoneme_names_en;
|
||||
maxph = 49;
|
||||
}
|
||||
|
||||
if(maxph == 0)
|
||||
return(0);
|
||||
|
||||
strcpy(phbuf,"[[");
|
||||
while(((ph = *phons++) != 0) && (ix < (sizeof(phbuf) - 3)))
|
||||
{
|
||||
if(skip)
|
||||
{
|
||||
skip = 0;
|
||||
continue;
|
||||
}
|
||||
if(ph > maxph)
|
||||
continue;
|
||||
|
||||
p = phoneme_names[phons[0]]; // look at the phoneme after this one
|
||||
if(p != NULL)
|
||||
{
|
||||
if(p[0] == '\'')
|
||||
{
|
||||
phbuf[ix++] = '\''; // primary stress, put before the vowel, not after
|
||||
skip=1;
|
||||
}
|
||||
if(p[0] == ',')
|
||||
{
|
||||
phbuf[ix++] = ','; // secondary stress
|
||||
skip=1;
|
||||
}
|
||||
}
|
||||
|
||||
p = phoneme_names[ph]; // look at this phoneme
|
||||
|
||||
if(p != NULL)
|
||||
{
|
||||
strcpy(&phbuf[ix],p);
|
||||
ix += strlen(p);
|
||||
}
|
||||
}
|
||||
strcpy(&phbuf[ix],"]]");
|
||||
ix += 2;
|
||||
|
||||
if(pW != NULL)
|
||||
{
|
||||
for(j=0; j<=ix; j++)
|
||||
{
|
||||
pW[j] = phbuf[j];
|
||||
}
|
||||
}
|
||||
return(strlen(phbuf));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_start, ISpTTSEngineSite* pOutputSite, int *n_text)
|
||||
{//=============================================================================================================================
|
||||
{//============================================================================================================================
|
||||
|
||||
int action;
|
||||
int control;
|
||||
@@ -338,6 +428,7 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st
|
||||
|
||||
CheckActions(pOutputSite);
|
||||
sayas = 0;
|
||||
state = &pTextFragList->State;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
@@ -366,7 +457,6 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st
|
||||
}
|
||||
|
||||
// first set the volume, rate, pitch
|
||||
state = &pTextFragList->State;
|
||||
volume = (state->Volume * master_volume)/100;
|
||||
speed = ConvertRate(state->RateAdj);
|
||||
pitch = ConvertPitch(state->PitchAdj.MiddleAdj);
|
||||
@@ -467,6 +557,14 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SPVA_Pronounce:
|
||||
total += WritePhonemes(state->pPhoneIds, pW);
|
||||
if(pW != NULL)
|
||||
{
|
||||
pW += total;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -478,6 +576,7 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st
|
||||
*pW = 0;
|
||||
}
|
||||
*n_text = frag_count;
|
||||
|
||||
return(total);
|
||||
} // end of ProcessFragList
|
||||
|
||||
@@ -600,7 +699,7 @@ STDMETHODIMP CTTSEngObj::Speak( DWORD dwSpeakFlags,
|
||||
|
||||
if(size > 0)
|
||||
{
|
||||
espeak_Synth(TextBuf,0,0,POS_CHARACTER,0,espeakCHARS_WCHAR | espeakKEEP_NAMEDATA,NULL,NULL);
|
||||
espeak_Synth(TextBuf,0,0,POS_CHARACTER,0,espeakCHARS_WCHAR | espeakKEEP_NAMEDATA | espeakPHONEMES,NULL,NULL);
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
|
||||
+12
-5
@@ -384,12 +384,19 @@ int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
}
|
||||
length += n_flag_codes;
|
||||
|
||||
if((multiple_string != NULL) && (multiple_words > 0) && (multiple_words <= 4))
|
||||
if((multiple_string != NULL) && (multiple_words > 0))
|
||||
{
|
||||
dict_line[length++] = 40 + multiple_words;
|
||||
ix = multiple_string_end - multiple_string;
|
||||
memcpy(&dict_line[length],multiple_string,ix);
|
||||
length += ix;
|
||||
if(multiple_words > 10)
|
||||
{
|
||||
fprintf(f_log,"%5d: Two many parts in a multi-word entry: %d\n",linenum,multiple_words);
|
||||
}
|
||||
else
|
||||
{
|
||||
dict_line[length++] = 40 + multiple_words;
|
||||
ix = multiple_string_end - multiple_string;
|
||||
memcpy(&dict_line[length],multiple_string,ix);
|
||||
length += ix;
|
||||
}
|
||||
}
|
||||
dict_line[0] = length;
|
||||
|
||||
|
||||
+4
-3
@@ -36,7 +36,7 @@
|
||||
#include "translate.h"
|
||||
|
||||
|
||||
|
||||
int dictionary_skipwords;
|
||||
char dictionary_name[40];
|
||||
|
||||
extern MNEM_TAB mnem_flags[];
|
||||
@@ -2716,12 +2716,13 @@ int Translator::LookupDict2(char *word, char *word2, char *phonetic, unsigned in
|
||||
else
|
||||
if(flag > 40)
|
||||
{
|
||||
// flags 41,42,or 43 match more than one word
|
||||
// flags 41 to 50 match more than one word
|
||||
// This comes after the other flags
|
||||
n_chars = next - p;
|
||||
if(memcmp(word2,p,n_chars)==0)
|
||||
{
|
||||
dictionary_flags |= ((flag-40) << 5); // set (bits 5-7) to 1,2,or 3
|
||||
dictionary_flags |= FLAG_SKIPWORDS;
|
||||
dictionary_skipwords = (flag - 40);
|
||||
p = next;
|
||||
word_end = word2 + n_chars;
|
||||
}
|
||||
|
||||
@@ -214,9 +214,6 @@ int Translator::TranslateRoman(char *word, char *ph_out)
|
||||
static char *roman_numbers = "ixcmvld";
|
||||
static int roman_values[] = {1,10,100,1000,5,50,500};
|
||||
|
||||
if((langopts.numbers & NUM_ROMAN) == 0)
|
||||
return(0);
|
||||
|
||||
acc = 0;
|
||||
prev = 0;
|
||||
subtract = 0x7fff;
|
||||
|
||||
+11
-6
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.29.02 10.Sep.07";
|
||||
const char *version_string = "1.29.04 11.Sep.07";
|
||||
const int version_phdata = 0x012901;
|
||||
|
||||
int option_device_number = -1;
|
||||
@@ -204,7 +204,7 @@ static unsigned int LookupSound2(int index, unsigned int other_phcode, int contr
|
||||
{//================================================================================
|
||||
// control=1 get formant transition data only
|
||||
|
||||
int code;
|
||||
unsigned int code;
|
||||
unsigned int value, value2;
|
||||
|
||||
while((value = phoneme_index[index++]) != 0)
|
||||
@@ -223,12 +223,17 @@ static unsigned int LookupSound2(int index, unsigned int other_phcode, int contr
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if(control==0)
|
||||
seq_len_adjust = value2 >> 8;
|
||||
if(control==0)
|
||||
{
|
||||
seq_len_adjust = value2 >> 8;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(control==0)
|
||||
seq_len_adjust = -(value2 >> 8);
|
||||
if(control==0)
|
||||
{
|
||||
seq_len_adjust = value2 >> 8;
|
||||
seq_len_adjust = -seq_len_adjust;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if(control==0)
|
||||
|
||||
@@ -304,7 +304,7 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->langopts.max_initial_consonants = 5;
|
||||
tr->langopts.spelling_stress = 1;
|
||||
|
||||
tr->langopts.numbers = 0x1c0d + 0x4000 + NUM_ROMAN;
|
||||
tr->langopts.numbers = 0x1c0d + 0x4000 + NUM_ROMAN_UC;
|
||||
tr->langopts.numbers2 = 0x4a; // variant numbers before thousands,milliards
|
||||
tr->langopts.replace_chars = replace_cyrillic;
|
||||
tr->langopts.replacement_chars = replace_cyrillic_latin;
|
||||
|
||||
+14
-8
@@ -671,8 +671,12 @@ if((wmark > 0) && (wmark < 8))
|
||||
if(!found & ((word_flags & FLAG_UPPERS) != FLAG_FIRST_UPPER))
|
||||
{
|
||||
// either all upper or all lower case
|
||||
if((found = TranslateRoman(word,phonemes)) != 0)
|
||||
dictionary_flags |= FLAG_ABBREV; // don't spell capital Roman numbers as individual letters
|
||||
|
||||
if((langopts.numbers & NUM_ROMAN) || ((langopts.numbers & NUM_ROMAN_UC) && (word_flags & FLAG_ALL_UPPER)))
|
||||
{
|
||||
if((found = TranslateRoman(word,phonemes)) != 0)
|
||||
dictionary_flags |= FLAG_ABBREV; // don't spell capital Roman numbers as individual letters
|
||||
}
|
||||
}
|
||||
|
||||
if((wflags & FLAG_ALL_UPPER) && (clause_upper_count <= clause_lower_count) &&
|
||||
@@ -1233,7 +1237,8 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= FLAG_SKIPWORDS_1;
|
||||
flags |= FLAG_SKIPWORDS;
|
||||
dictionary_skipwords = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1562,7 +1567,7 @@ int Translator::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned i
|
||||
|
||||
int ix;
|
||||
unsigned int word;
|
||||
unsigned int new_c, c2;
|
||||
unsigned int new_c, c2, c_lower;
|
||||
int upper_case = 0;
|
||||
static int ignore_next = 0;
|
||||
|
||||
@@ -1578,16 +1583,16 @@ int Translator::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned i
|
||||
|
||||
// there is a list of character codes to be substituted with alternative codes
|
||||
|
||||
if(iswupper(c))
|
||||
if(iswupper(c_lower = c))
|
||||
{
|
||||
c = towlower(c);
|
||||
c_lower = towlower(c);
|
||||
upper_case = 1;
|
||||
}
|
||||
|
||||
new_c = 0;
|
||||
for(ix=0; (word = langopts.replace_chars[ix]) != 0; ix++)
|
||||
{
|
||||
if(c == (word & 0xffff))
|
||||
if(c_lower == (word & 0xffff))
|
||||
{
|
||||
if((word >> 16) == 0)
|
||||
{
|
||||
@@ -2217,7 +2222,8 @@ if((c == '/') && (langopts.testing & 2) && isdigit(next_in) && IsAlpha(prev_out)
|
||||
else
|
||||
{
|
||||
dict_flags = TranslateWord2(word, &words[ix], words[ix].pre_pause, words[ix+1].pre_pause);
|
||||
ix += ((dict_flags >> 5) & 7); // dictionary indicates skip next word(s)
|
||||
if(dict_flags & FLAG_SKIPWORDS)
|
||||
ix += dictionary_skipwords; // dictionary indicates skip next word(s)
|
||||
|
||||
if((dict_flags & FLAG_DOT) && (ix == word_count-1) && (terminator == CLAUSE_PERIOD))
|
||||
{
|
||||
|
||||
+6
-3
@@ -34,8 +34,7 @@
|
||||
|
||||
/* flags from word dictionary */
|
||||
// bits 0-3 stressed syllable, 7=unstressed
|
||||
#define FLAG_SKIPWORDS 0xe0 /* bits 5,6,7 number of words to skip */
|
||||
#define FLAG_SKIPWORDS_1 0x20
|
||||
#define FLAG_SKIPWORDS 0x80
|
||||
#define FLAG_PREPAUSE 0x100
|
||||
#define FLAG_ONLY 0x200
|
||||
#define BITNUM_FLAG_ONLY 9 // bit 9 is set
|
||||
@@ -277,7 +276,8 @@ typedef struct {
|
||||
unsigned char *length_mods;
|
||||
unsigned char *length_mods0;
|
||||
|
||||
#define NUM_ROMAN 0x20000
|
||||
#define NUM_ROMAN 0x20000
|
||||
#define NUM_ROMAN_UC 0x40000
|
||||
// bits0-1=which numbers routine to use.
|
||||
// bit2= thousands separator must be space
|
||||
// bit3= , decimal separator, not .
|
||||
@@ -293,6 +293,7 @@ typedef struct {
|
||||
// bits13-15 post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro)
|
||||
// bit16=dot after number indicates ordinal
|
||||
// bit17=recognize roman numbers
|
||||
// bit18=Roman numbers only if upper case
|
||||
|
||||
int numbers;
|
||||
|
||||
@@ -501,6 +502,8 @@ extern char ctrl_embedded; // to allow an alternative CTRL for embedded comma
|
||||
extern char *p_textinput;
|
||||
extern wchar_t *p_wchar_input;
|
||||
extern int ungot_char;
|
||||
extern int dictionary_skipwords;
|
||||
|
||||
extern int (* uri_callback)(int, const char *, const char *);
|
||||
extern int (* phoneme_callback)(const char *);
|
||||
extern void SetLengthMods(Translator *tr, int value);
|
||||
|
||||
Reference in New Issue
Block a user