mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-11 00:26:08 +00:00
Merge branch 'master' into build
This commit is contained in:
+2
-2
@@ -524,7 +524,7 @@ step=1; // TEST
|
||||
{
|
||||
multiple_numeric_hyphen = 1;
|
||||
}
|
||||
else
|
||||
// else // ???
|
||||
{
|
||||
flag_codes[n_flag_codes++] = BITNUM_FLAG_HYPHENATED;
|
||||
}
|
||||
@@ -739,7 +739,7 @@ step=1; // TEST
|
||||
ix = multiple_string_end - multiple_string;
|
||||
if(multiple_numeric_hyphen)
|
||||
{
|
||||
dict_line[length++] = ' ';
|
||||
dict_line[length++] = ' '; // ???
|
||||
}
|
||||
memcpy(&dict_line[length],multiple_string,ix);
|
||||
length += ix;
|
||||
|
||||
+3
-3
@@ -1185,8 +1185,8 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
switch(tr->langopts.stress_rule)
|
||||
{
|
||||
case 8:
|
||||
// stress on first syllable, unless it is a light syllable
|
||||
if(syllable_weight[1] > 0)
|
||||
// stress on first syllable, unless it is a light syllable followed by a heavy syllable
|
||||
if((syllable_weight[1] > 0) || (syllable_weight[2] == 0))
|
||||
break;
|
||||
// else drop through to case 1
|
||||
case 1:
|
||||
@@ -3250,7 +3250,7 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f
|
||||
}
|
||||
}
|
||||
|
||||
for(length=0; length<N_WORD_BYTES; length++)
|
||||
for(length=0; length<(N_WORD_BYTES-1); length++)
|
||||
{
|
||||
if(((c = *word1++)==0) || (c == ' '))
|
||||
break;
|
||||
|
||||
+12
-1
@@ -171,6 +171,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
// set consonant clusters to all voiced or all unvoiced
|
||||
// Regressive
|
||||
int type;
|
||||
int word_end_devoice = 0;
|
||||
voicing = 0;
|
||||
|
||||
for(j=n_ph_list2-1; j>=0; j--)
|
||||
@@ -190,7 +191,12 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
{
|
||||
// LANG=Russian, [v] amd [v;] don't cause regression, or [R^]
|
||||
if((ph->mnemonic == 'v') || (ph->mnemonic == ((';'<<8)+'v')) || ((ph->mnemonic & 0xff)== 'R'))
|
||||
type = phLIQUID;
|
||||
{
|
||||
if(word_end_devoice == 1)
|
||||
voicing = 0;
|
||||
else
|
||||
type = phLIQUID;
|
||||
}
|
||||
}
|
||||
|
||||
if((type==phSTOP) || type==(phFRICATIVE))
|
||||
@@ -231,6 +237,8 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
voicing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
word_end_devoice = 0;
|
||||
if(plist2[j].sourceix)
|
||||
{
|
||||
if(regression & 0x04)
|
||||
@@ -242,7 +250,10 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
{
|
||||
// devoice word-final consonants, unless propagating voiced
|
||||
if(voicing == 0)
|
||||
{
|
||||
voicing = 1;
|
||||
word_end_devoice = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-11
@@ -364,10 +364,10 @@ int towlower2(unsigned int c)
|
||||
{
|
||||
c = 0x131; // I -> ı
|
||||
}
|
||||
}
|
||||
#ifdef __WIN32__
|
||||
if(c == 0x130) // uppercase i-dot
|
||||
return('i');
|
||||
}
|
||||
#ifdef __WIN32__
|
||||
if(c == 0x130) // uppercase i-dot
|
||||
return('i');
|
||||
#endif
|
||||
return(towlower(c));
|
||||
}
|
||||
@@ -901,14 +901,21 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
else
|
||||
if(punct_count < 4)
|
||||
{
|
||||
sprintf(buf,"\001+10S");
|
||||
buf[0] = 0;
|
||||
if(embedded_value[EMBED_S] < 300)
|
||||
sprintf(buf,"\001+10S"); // Speak punctuation name faster, unless we are already speaking fast. It would upset Sonic SpeedUp
|
||||
|
||||
while(punct_count-- > 0)
|
||||
{
|
||||
sprintf(buf2," %s",punctname);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
sprintf(buf2," \001-10S");
|
||||
strcat(buf, buf2);
|
||||
|
||||
if(embedded_value[EMBED_S] < 300)
|
||||
{
|
||||
sprintf(buf2," \001-10S");
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2000,6 +2007,15 @@ terminator=0; // ?? Sentence intonation, but no pause ??
|
||||
} // end of ProcessSsmlTag
|
||||
|
||||
|
||||
static void RemoveChar(char *p)
|
||||
{//=======================
|
||||
// Replace a UTF-8 character by spaces
|
||||
int c;
|
||||
|
||||
memset(p, ' ', utf8_in(&c, p));
|
||||
} // end of RemoveChar
|
||||
|
||||
|
||||
static MNEM_TAB xml_char_mnemonics[] = {
|
||||
{"gt",'>'},
|
||||
{"lt", 0xe000 + '<'}, // private usage area, to avoid confusion with XML tag
|
||||
@@ -2354,6 +2370,15 @@ f_input = f_in; // for GetC etc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(c1 == 0xd4d)
|
||||
{
|
||||
// Malayalam virama, check if next character is Zero-width-joiner
|
||||
if(c2 == 0x200d)
|
||||
{
|
||||
c1 = 0xd4e; // use this unofficial code for chillu-virama
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(iswupper(c1))
|
||||
@@ -2408,8 +2433,9 @@ f_input = f_in; // for GetC etc
|
||||
UngetC(c2);
|
||||
|
||||
if(end_clause_after_tag)
|
||||
ix = end_clause_index; // delete clause-end punctiation
|
||||
|
||||
{
|
||||
RemoveChar(&buf[end_clause_index]); // delete clause-end punctiation
|
||||
}
|
||||
buf[ix] = ' ';
|
||||
buf[ix+1] = 0;
|
||||
if(parag > 3)
|
||||
@@ -2485,7 +2511,7 @@ if(option_ssml) parag=1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || Eof())) // don't check for '-' because if prevent recognizing ':-)'
|
||||
if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || Eof() || (c2 == ctrl_embedded))) // don't check for '-' because it prevents recognizing ':-)'
|
||||
// if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || (c2=='-') || Eof()))
|
||||
{
|
||||
// note: (c2='?') is for when a smart-quote has been replaced by '?'
|
||||
@@ -2682,7 +2708,7 @@ if(option_ssml) parag=1;
|
||||
}
|
||||
if(end_clause_after_tag)
|
||||
{
|
||||
ix = end_clause_index; // delete clause-end punctuation
|
||||
RemoveChar(&buf[end_clause_index]); // delete clause-end punctiation
|
||||
}
|
||||
buf[ix] = ' ';
|
||||
buf[ix+1] = 0;
|
||||
@@ -2707,6 +2733,7 @@ void InitText2(void)
|
||||
int param;
|
||||
|
||||
ungot_char = 0;
|
||||
ungot_char2 = 0;
|
||||
|
||||
n_ssml_stack =1;
|
||||
n_param_stack = 1;
|
||||
|
||||
+4
-1
@@ -141,6 +141,7 @@ void SetSpeed(int control)
|
||||
int s1;
|
||||
int wpm;
|
||||
int wpm2;
|
||||
int wpm_value;
|
||||
double sonic;
|
||||
|
||||
speed.loud_consonants = 0;
|
||||
@@ -153,6 +154,8 @@ void SetSpeed(int control)
|
||||
if(control == 2)
|
||||
wpm = embedded_value[EMBED_S2];
|
||||
|
||||
wpm_value = wpm;
|
||||
|
||||
if(voice->speed_percent > 0)
|
||||
{
|
||||
wpm = (wpm * voice->speed_percent)/100;
|
||||
@@ -162,7 +165,7 @@ void SetSpeed(int control)
|
||||
{
|
||||
DoSonicSpeed(1 * 1024);
|
||||
}
|
||||
if((wpm > 450) || ((wpm > speed.fast_settings[0]) && (wpm > 350)))
|
||||
if((wpm_value > 450) || ((wpm_value > speed.fast_settings[0]) && (wpm > 350)))
|
||||
{
|
||||
wpm2 = wpm;
|
||||
wpm = 175;
|
||||
|
||||
@@ -151,7 +151,10 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
#endif
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
if(load_MBR() == FALSE) // load mbrola.dll
|
||||
return(EE_INTERNAL_ERROR);
|
||||
{
|
||||
fprintf(stderr, "Can't load mbrola.dll\n");
|
||||
return(EE_INTERNAL_ERROR);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(init_MBR(path) != 0) // initialise the required mbrola voice
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.45.12 01.Apr.11";
|
||||
const char *version_string = "1.45.04 25.Apr.11";
|
||||
const int version_phdata = 0x014500;
|
||||
|
||||
int option_device_number = -1;
|
||||
|
||||
@@ -385,6 +385,7 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
case L('a','r'): // Arabic
|
||||
tr->letter_bits_offset = OFFSET_ARABIC;
|
||||
tr->langopts.numbers = NUM_SWAP_TENS | NUM_AND_UNITS | NUM_HUNDRED_AND | NUM_OMIT_1_HUNDRED | NUM_AND_HUNDRED | NUM_THOUSAND_AND | NUM_OMIT_1_THOUSAND;
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
break;
|
||||
|
||||
@@ -393,7 +394,7 @@ Translator *SelectTranslator(const char *name)
|
||||
SetCyrillicLetters(tr);
|
||||
SetLetterVowel(tr,0x2a);
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 0x432; // [v] don't count this character at start of word
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x10; // devoice at end of word
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x17; // devoice at end of word, and change voicing to match a following consonant (except v)
|
||||
tr->langopts.param[LOPT_REDUCE] = 2;
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_OMIT_1_HUNDRED | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_SINGLE_AND | NUM_ROMAN | NUM_ROMAN_ORDINAL | NUM_ROMAN_CAPITALS ;
|
||||
@@ -470,7 +471,8 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x10; // devoice at end of word
|
||||
tr->langopts.param[LOPT_LONG_VOWEL_THRESHOLD] = 175/2;
|
||||
|
||||
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;
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_ALLOW_SPACE | NUM_ORDINAL_DOT | NUM_ROMAN;
|
||||
// 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');
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 2; // use de_rules for unpronouncable rules
|
||||
}
|
||||
@@ -1218,6 +1220,7 @@ SetLengthMods(tr,3); // all equal
|
||||
}
|
||||
tr->langopts.param[LOPT_WORD_MERGE] = 1; // don't break vowels betwen words
|
||||
SetIndicLetters(tr); // call this after setting OFFSET_
|
||||
SetLetterBitsRange(tr,LETTERGP_B,0x4e,0x4e); // chillu-virama (unofficial)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+9
-4
@@ -122,7 +122,7 @@ static const unsigned short brackets[] = {
|
||||
static const unsigned short breaks[] = {'_', 0};
|
||||
|
||||
// treat these characters as spaces, in addition to iswspace()
|
||||
static const wchar_t chars_space[] = {0x2500,0}; // box drawing horiz
|
||||
// static const wchar_t chars_space[] = {0x2500,0x2501,0}; // box drawing horiz
|
||||
|
||||
|
||||
// Translate character codes 0xA0 to 0xFF into their unicode values
|
||||
@@ -432,8 +432,10 @@ int IsSpace(unsigned int c)
|
||||
{//========================
|
||||
if(c == 0)
|
||||
return(0);
|
||||
if(wcschr(chars_space,c))
|
||||
return(1);
|
||||
if((c >= 0x2500) && (c < 0x25a0))
|
||||
return(1); // box drawing characters
|
||||
// if(wcschr(chars_space,c))
|
||||
// return(1);
|
||||
return(iswspace(c));
|
||||
}
|
||||
|
||||
@@ -867,6 +869,8 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
}
|
||||
|
||||
word_copy_length = wordx - word_start;
|
||||
if(word_copy_length >= N_WORD_BYTES)
|
||||
word_copy_length = N_WORD_BYTES-1;
|
||||
memcpy(word_copy2, word_start, word_copy_length);
|
||||
|
||||
spell_word = 0;
|
||||
@@ -3017,7 +3021,8 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
else
|
||||
{
|
||||
ix += utf8_out(c,&sbuf[ix]); // sbuf[ix++] = c;
|
||||
if((ix < (N_TR_SOURCE - 4)))
|
||||
ix += utf8_out(c,&sbuf[ix]); // sbuf[ix++] = c;
|
||||
}
|
||||
if(pre_pause_add > pre_pause)
|
||||
pre_pause = pre_pause_add;
|
||||
|
||||
+23
-15
@@ -1540,14 +1540,32 @@ static int SetWithRange0(int value, int max)
|
||||
}
|
||||
|
||||
|
||||
static void SetPitchFormants()
|
||||
{//===========================
|
||||
int ix;
|
||||
int factor;
|
||||
int pitch_value;
|
||||
|
||||
// adjust formants to give better results for a different voice pitch
|
||||
if((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
|
||||
pitch_value = MAX_PITCH_VALUE;
|
||||
|
||||
factor = 256 + (25 * (pitch_value - 50))/50;
|
||||
for(ix=0; ix<=5; ix++)
|
||||
{
|
||||
wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256;
|
||||
}
|
||||
factor = embedded_value[EMBED_T]*3;
|
||||
wvoice->height[0] = (wvoice->height2[0] * (256 - factor*2))/256;
|
||||
wvoice->height[1] = (wvoice->height2[1] * (256 - factor))/256;
|
||||
}
|
||||
|
||||
|
||||
void SetEmbedded(int control, int value)
|
||||
{//=====================================
|
||||
// there was an embedded command in the text at this point
|
||||
int sign=0;
|
||||
int command;
|
||||
int ix;
|
||||
int factor;
|
||||
int pitch_value;
|
||||
|
||||
command = control & 0x1f;
|
||||
if((control & 0x60) == 0x60)
|
||||
@@ -1570,18 +1588,7 @@ void SetEmbedded(int control, int value)
|
||||
case EMBED_T:
|
||||
WavegenSetEcho(); // and drop through to case P
|
||||
case EMBED_P:
|
||||
// adjust formants to give better results for a different voice pitch
|
||||
if((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
|
||||
pitch_value = MAX_PITCH_VALUE;
|
||||
|
||||
factor = 256 + (25 * (pitch_value - 50))/50;
|
||||
for(ix=0; ix<=5; ix++)
|
||||
{
|
||||
wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256;
|
||||
}
|
||||
factor = embedded_value[EMBED_T]*3;
|
||||
wvoice->height[0] = (wvoice->height2[0] * (256 - factor*2))/256;
|
||||
wvoice->height[1] = (wvoice->height2[1] * (256 - factor))/256;
|
||||
SetPitchFormants();
|
||||
break;
|
||||
|
||||
case EMBED_A: // amplitude
|
||||
@@ -1618,6 +1625,7 @@ void WavegenSetVoice(voice_t *v)
|
||||
option_harmonic1 = 6;
|
||||
}
|
||||
WavegenSetEcho();
|
||||
SetPitchFormants();
|
||||
MarkerEvent(espeakEVENT_SAMPLERATE,0,wvoice->samplerate,out_ptr);
|
||||
// WVoiceChanged(wvoice);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user