mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-14 01:32:29 +00:00
[1.39.36]
*_list files: add attribute $max3 to limit repetitions of a symbol to 3. -v command option, if the voice-name is not found, lookup using it as a language name. Windows: allow longer path names for espeak-data. -m option: Ignore text within <script> and <style> tags. Reduce default pitch to 80-117. WavegenCloseSound() check if there remain items to be spoken and re-open the sound channel. Reduce voicing before voiced plosives. Corrections to mbrola translation for lang=hi. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@205 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+3
-1
@@ -297,7 +297,8 @@ static keywtab_t keywords[] = {
|
||||
{"f4", 0x300000a},
|
||||
{"paus", 0x300000b},
|
||||
{"colr=",0x300000c},
|
||||
{"amp=", 0x300000d},
|
||||
{"amp=", 0x300000d}, // set rms of 1st frame as fraction of rms of 2nd frame (1/30ths)
|
||||
|
||||
{"", -1}
|
||||
};
|
||||
|
||||
@@ -1286,6 +1287,7 @@ void Compile::VowelTransition(int which, unsigned int *trans)
|
||||
vcolour = NextItem(tNUMBER);
|
||||
break;
|
||||
case 13:
|
||||
// set rms of 1st frame as fraction of rms of 2nd frame (1/30ths)
|
||||
rms = (Range(NextItem(tNUMBER), 1, 0, 31) & 0x1f) | 0x20;
|
||||
flags |= 1;
|
||||
break;
|
||||
|
||||
@@ -90,6 +90,7 @@ MNEM_TAB mnem_flags[] = {
|
||||
{"$alt2", 21},
|
||||
|
||||
|
||||
{"$max3", 27}, // limit to 3 repetitions
|
||||
{"$brk", 28}, // a shorter $pause
|
||||
{"$text", 29}, // word translates to replcement text, not phonemes
|
||||
|
||||
|
||||
+51
-1
@@ -684,6 +684,7 @@ int Translator::IsLetterGroup(char *word, int group, int pre)
|
||||
// match the word against a list of utf-8 strings
|
||||
char *p;
|
||||
char *w;
|
||||
int len;
|
||||
|
||||
p = letterGroups[group];
|
||||
if(p == NULL)
|
||||
@@ -691,14 +692,26 @@ int Translator::IsLetterGroup(char *word, int group, int pre)
|
||||
|
||||
while(*p != RULE_GROUP_END)
|
||||
{
|
||||
w = word;
|
||||
if(pre)
|
||||
{
|
||||
len = strlen(p);
|
||||
w = word - len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = word;
|
||||
}
|
||||
while(*p == *w)
|
||||
{
|
||||
w++;
|
||||
p++;
|
||||
}
|
||||
if(*p == 0)
|
||||
{
|
||||
if(pre)
|
||||
return(len);
|
||||
return(w-word); // matched a complete string
|
||||
}
|
||||
|
||||
while(*p++ != 0); // skip to end of string
|
||||
}
|
||||
@@ -1023,6 +1036,7 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int
|
||||
|
||||
unsigned char vowel_stress[N_WORD_PHONEMES/2];
|
||||
char syllable_weight[N_WORD_PHONEMES/2];
|
||||
char vowel_length[N_WORD_PHONEMES/2];
|
||||
unsigned char phonetic[N_WORD_PHONEMES];
|
||||
|
||||
static char consonant_types[16] = {0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0};
|
||||
@@ -1079,6 +1093,7 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int
|
||||
// long vowel, increase syllable weight
|
||||
weight++;
|
||||
}
|
||||
vowel_length[ix] = weight;
|
||||
|
||||
if(lengthened) p++; // advance over phonLENGTHEN
|
||||
|
||||
@@ -1150,6 +1165,14 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int
|
||||
}
|
||||
}
|
||||
}
|
||||
if(langopts.stress_flags & 0x80000)
|
||||
{
|
||||
// stress on last syllable if it has a long vowel, but previous syllable has a short vowel
|
||||
if(vowel_length[vowel_count - 1] > vowel_length[vowel_count - 2])
|
||||
{
|
||||
stressed_syllable = vowel_count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(vowel_stress[stressed_syllable] == 1)
|
||||
{
|
||||
@@ -2547,6 +2570,10 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char
|
||||
}
|
||||
p += (wc_bytes-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
phonemes_repeat_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2590,6 +2617,7 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char
|
||||
// any language specific changes ?
|
||||
ApplySpecialAttribute(phonemes,dict_flags0);
|
||||
memcpy(p_start,word_copy,strlen(word_copy));
|
||||
|
||||
return(0);
|
||||
} /* end of TranslateRules */
|
||||
|
||||
@@ -3127,6 +3155,28 @@ int Translator::LookupDictList(char **wordptr, char *ph_out, unsigned int *flags
|
||||
|
||||
found = LookupDict2(word, word1, ph_out, flags, end_flags, wtab);
|
||||
|
||||
if(flags[0] & FLAG_MAX3)
|
||||
{
|
||||
if(strcmp(ph_out, phonemes_repeat) == 0)
|
||||
{
|
||||
phonemes_repeat_count++;
|
||||
if(phonemes_repeat_count > 3)
|
||||
{
|
||||
ph_out[0] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy0(phonemes_repeat, ph_out, sizeof(phonemes_repeat));
|
||||
phonemes_repeat_count = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
phonemes_repeat_count = 0;
|
||||
}
|
||||
|
||||
|
||||
if((found == 0) && (flags[1] & FLAG_ACCENT))
|
||||
{
|
||||
int letter;
|
||||
|
||||
+10
-4
@@ -324,7 +324,7 @@ int main (int argc, char **argv)
|
||||
|
||||
FILE *f_text=NULL;
|
||||
char *p_text=NULL;
|
||||
FILE *f_phonemes_out = stderr;
|
||||
FILE *f_phonemes_out = stdout;
|
||||
char *data_path = NULL; // use default path for espeak-data
|
||||
|
||||
int option_index = 0;
|
||||
@@ -345,7 +345,8 @@ int main (int argc, char **argv)
|
||||
int option_linelength = 0;
|
||||
int option_waveout = 0;
|
||||
|
||||
char filename[120];
|
||||
espeak_VOICE voice_select;
|
||||
char filename[200];
|
||||
char voicename[40];
|
||||
char voice_mbrola[20];
|
||||
char dictname[40];
|
||||
@@ -529,8 +530,13 @@ int main (int argc, char **argv)
|
||||
|
||||
if(espeak_SetVoiceByName(voicename) != EE_OK)
|
||||
{
|
||||
fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
|
||||
exit(2);
|
||||
memset(&voice_select,0,sizeof(voice_select));
|
||||
voice_select.languages = voicename;
|
||||
if(espeak_SetVoiceByProperties(&voice_select) != EE_OK)
|
||||
{
|
||||
fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if(flag_compile)
|
||||
|
||||
+30
-9
@@ -79,8 +79,6 @@ const unsigned short punct_chars[] = {',','.','?','!',':',';',
|
||||
0x037e, // Greek question mark (looks like semicolon)
|
||||
0x0387, // Greek semicolon, ano teleia
|
||||
0x0964, // Devanagari Danda (fullstop)
|
||||
0x3001, // ideograph comma
|
||||
0x3002, // ideograph period
|
||||
|
||||
0x0589, // Armenian period
|
||||
0x055d, // Armenian comma
|
||||
@@ -88,6 +86,17 @@ const unsigned short punct_chars[] = {',','.','?','!',':',';',
|
||||
0x055e, // Armenian question
|
||||
0x055b, // Armenian emphasis mark
|
||||
|
||||
0x1362, // Ethiopic period
|
||||
0x1363,
|
||||
0x1364,
|
||||
0x1365,
|
||||
0x1366,
|
||||
0x1367,
|
||||
0x1368,
|
||||
|
||||
0x3001, // ideograph comma
|
||||
0x3002, // ideograph period
|
||||
|
||||
0xff01, // fullwidth exclamation
|
||||
0xff0c, // fullwidth comma
|
||||
0xff0e, // fullwidth period
|
||||
@@ -109,8 +118,6 @@ static const unsigned int punct_attributes [] = { 0,
|
||||
CLAUSE_QUESTION, // Greek question mark
|
||||
CLAUSE_SEMICOLON, // Greek semicolon
|
||||
CLAUSE_PERIOD+0x8000, // Devanagari Danda (fullstop)
|
||||
CLAUSE_COMMA+0x8000, // ideograph comma
|
||||
CLAUSE_PERIOD+0x8000, // ideograph period
|
||||
|
||||
CLAUSE_PERIOD+0x8000, // Armenian period
|
||||
CLAUSE_COMMA, // Armenian comma
|
||||
@@ -118,6 +125,17 @@ static const unsigned int punct_attributes [] = { 0,
|
||||
CLAUSE_QUESTION + PUNCT_IN_WORD, // Armenian question
|
||||
CLAUSE_PERIOD + PUNCT_IN_WORD, // Armenian emphasis mark
|
||||
|
||||
CLAUSE_PERIOD, // Ethiopic period
|
||||
CLAUSE_COMMA, // Ethiopic comma
|
||||
CLAUSE_SEMICOLON, // Ethiopic semicolon
|
||||
CLAUSE_COLON, // Ethiopic colon
|
||||
CLAUSE_COLON, // Ethiopic preface colon
|
||||
CLAUSE_QUESTION, // Ethiopic question mark
|
||||
CLAUSE_PERIOD, // Ethiopic paragraph
|
||||
|
||||
CLAUSE_COMMA+0x8000, // ideograph comma
|
||||
CLAUSE_PERIOD+0x8000, // ideograph period
|
||||
|
||||
CLAUSE_EXCLAMATION+0x8000, // fullwidth
|
||||
CLAUSE_COMMA+0x8000,
|
||||
CLAUSE_PERIOD+0x8000,
|
||||
@@ -865,7 +883,7 @@ int Translator::AnnouncePunctuation(int c1, int c2, char *buf, int bufix)
|
||||
#define SSML_AUDIO 11
|
||||
#define SSML_EMPHASIS 12
|
||||
#define SSML_BREAK 13
|
||||
#define SSML_METADATA 14
|
||||
#define SSML_IGNORE_TEXT 14
|
||||
#define HTML_BREAK 15
|
||||
#define SSML_CLOSE 0x10 // for a closing tag, OR this with the tag type
|
||||
|
||||
@@ -887,7 +905,7 @@ MNEM_TAB ssmltags[] = {
|
||||
{"audio", SSML_AUDIO},
|
||||
{"emphasis", SSML_EMPHASIS},
|
||||
{"break", SSML_BREAK},
|
||||
{"metadata", SSML_METADATA},
|
||||
{"metadata", SSML_IGNORE_TEXT},
|
||||
|
||||
{"br", HTML_BREAK},
|
||||
{"li", HTML_BREAK},
|
||||
@@ -898,6 +916,8 @@ MNEM_TAB ssmltags[] = {
|
||||
{"h3", SSML_PARAGRAPH},
|
||||
{"h4", SSML_PARAGRAPH},
|
||||
{"hr", SSML_PARAGRAPH},
|
||||
{"script", SSML_IGNORE_TEXT},
|
||||
{"style", SSML_IGNORE_TEXT},
|
||||
{NULL,0}};
|
||||
|
||||
|
||||
@@ -911,6 +931,7 @@ static const char *VoiceFromStack()
|
||||
SSML_STACK *sp;
|
||||
const char *v_id;
|
||||
int voice_name_specified;
|
||||
int voice_found;
|
||||
espeak_VOICE voice_select;
|
||||
char voice_name[40];
|
||||
char language[40];
|
||||
@@ -952,7 +973,7 @@ static const char *VoiceFromStack()
|
||||
|
||||
voice_select.name = voice_name;
|
||||
voice_select.languages = language;
|
||||
v_id = SelectVoice(&voice_select);
|
||||
v_id = SelectVoice(&voice_select, &voice_found);
|
||||
if(v_id == NULL)
|
||||
return("default");
|
||||
return(v_id);
|
||||
@@ -1625,12 +1646,12 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
}
|
||||
break;
|
||||
|
||||
case SSML_METADATA:
|
||||
case SSML_IGNORE_TEXT:
|
||||
ignore_text = 1;
|
||||
break;
|
||||
|
||||
case SSML_SUB + SSML_CLOSE:
|
||||
case SSML_METADATA + SSML_CLOSE:
|
||||
case SSML_IGNORE_TEXT + SSML_CLOSE:
|
||||
ignore_text = 0;
|
||||
break;
|
||||
|
||||
|
||||
+12
-5
@@ -447,7 +447,7 @@ static void StopSpeak(int unused)
|
||||
static int optional_argument;
|
||||
static const char *arg_opts = "afklpsvw"; // which options have arguments
|
||||
static char *opt_string="";
|
||||
#define no_argument 0
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
@@ -494,7 +494,8 @@ int main (int argc, char **argv)
|
||||
int flag_stdin = 0;
|
||||
int flag_compile = 0;
|
||||
int pitch_adjustment = 50;
|
||||
char filename[120];
|
||||
espeak_VOICE voice_select;
|
||||
char filename[200];
|
||||
char voicename[40];
|
||||
char dictname[40];
|
||||
|
||||
@@ -510,10 +511,11 @@ int main (int argc, char **argv)
|
||||
option_endpause = 1;
|
||||
option_phoneme_input = 1;
|
||||
option_multibyte = espeakCHARS_AUTO; // auto
|
||||
f_trans = stderr;
|
||||
f_trans = stdout;
|
||||
|
||||
#ifdef NEED_GETOPT
|
||||
optind = 1;
|
||||
opt_string = "";
|
||||
while(optind < argc)
|
||||
{
|
||||
int len;
|
||||
@@ -735,8 +737,13 @@ int main (int argc, char **argv)
|
||||
|
||||
if(SetVoiceByName(voicename) != EE_OK)
|
||||
{
|
||||
fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
|
||||
exit(2);
|
||||
memset(&voice_select,0,sizeof(voice_select));
|
||||
voice_select.languages = voicename;
|
||||
if(SetVoiceByProperties(&voice_select) != EE_OK)
|
||||
{
|
||||
fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
SetParameter(espeakRATE,speed,0);
|
||||
|
||||
+7
-4
@@ -911,10 +911,12 @@ ESPEAK_API espeak_ERROR espeak_Char(wchar_t character)
|
||||
|
||||
|
||||
ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name)
|
||||
{//===================================================
|
||||
{//============================================================
|
||||
ENTER("espeak_SetVoiceByName");
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
//#ifdef USE_ASYNC
|
||||
// I don't think there's a need to queue change voice requests
|
||||
#ifdef deleted
|
||||
espeak_ERROR a_error;
|
||||
|
||||
if(synchronous_mode)
|
||||
@@ -937,10 +939,11 @@ ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name)
|
||||
|
||||
|
||||
ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_selector)
|
||||
{//=====================================================================
|
||||
{//==============================================================================
|
||||
ENTER("espeak_SetVoiceByProperties");
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
//#ifdef USE_ASYNC
|
||||
#ifdef deleted
|
||||
espeak_ERROR a_error;
|
||||
|
||||
if(synchronous_mode)
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.39.29 23.Nov.08";
|
||||
const char *version_string = "1.39.36 03.Dec.08";
|
||||
const int version_phdata = 0x013900;
|
||||
|
||||
int option_device_number = -1;
|
||||
|
||||
+31
-21
@@ -123,7 +123,7 @@ Translator *SelectTranslator(const char *name)
|
||||
int name2 = 0;
|
||||
Translator *tr;
|
||||
|
||||
static const unsigned char stress_amps_sk[8] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const unsigned char stress_amps_sk[8] = {17,17, 20,20, 20,24, 24,22 };
|
||||
static const short stress_lengths_sk[8] = {190,190, 210,210, 0,0, 210,210};
|
||||
|
||||
// convert name string into a word of up to 4 characters, for the switch()
|
||||
@@ -198,10 +198,9 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
case L('d','a'): // Danish
|
||||
{
|
||||
static const unsigned char stress_amps_da[] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const short stress_lengths_da[8] = {160,140, 200,200, 0,0, 220,210};
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_da,stress_amps_da);
|
||||
SetupTranslator(tr,stress_lengths_da,NULL);
|
||||
|
||||
tr->langopts.stress_rule = 0;
|
||||
SetLetterVowel(tr,'y');
|
||||
@@ -365,6 +364,16 @@ Translator *SelectTranslator(const char *name)
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef deleted
|
||||
case L('g','a'): // Irish Gaelic
|
||||
{
|
||||
tr = new Translator();
|
||||
|
||||
tr->langopts.stress_rule = 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case L('h','i'): // Hindi
|
||||
case L('n','e'): // Nepali
|
||||
{
|
||||
@@ -390,7 +399,7 @@ Translator *SelectTranslator(const char *name)
|
||||
case L('b','s'): // Bosnian
|
||||
case L('s','r'): // Serbian
|
||||
{
|
||||
static const unsigned char stress_amps_hr[8] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const unsigned char stress_amps_hr[8] = {17,17, 20,20, 20,24, 24,22 };
|
||||
static const short stress_lengths_hr[8] = {180,160, 200,200, 0,0, 220,230};
|
||||
static const short stress_lengths_sr[8] = {160,150, 200,200, 0,0, 250,260};
|
||||
|
||||
@@ -476,12 +485,11 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
case L('i','s'): // Icelandic
|
||||
{
|
||||
static const unsigned char stress_amps_is[] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const short stress_lengths_is[8] = {180,160, 200,200, 0,0, 240,250};
|
||||
static const wchar_t is_lettergroup_B[] = {'c','f','h','k','p','t','x',0xfe,0}; // voiceless conants, including 'þ' ?? 's'
|
||||
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_is,stress_amps_is);
|
||||
SetupTranslator(tr,stress_lengths_is,NULL);
|
||||
tr->langopts.stress_rule = 0;
|
||||
tr->langopts.stress_flags = 0x10;
|
||||
tr->langopts.param[LOPT_IT_LENGTHEN] = 0x11; // remove lengthen indicator from unstressed vowels
|
||||
@@ -499,8 +507,8 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
case L('i','t'): // Italian
|
||||
{
|
||||
static const short stress_lengths_it[8] = {150, 140, 180, 180, 0, 0, 270, 320};
|
||||
static const unsigned char stress_amps_it[8] = {15,14, 19,19, 20,24, 24,22 };
|
||||
static const short stress_lengths_it[8] = {150, 140, 170, 170, 0, 0, 300, 330};
|
||||
static const unsigned char stress_amps_it[8] = {15,14, 19,19, 20,22, 22,20 };
|
||||
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_it,stress_amps_it);
|
||||
@@ -606,7 +614,7 @@ SetLengthMods(tr,3); // all equal
|
||||
{
|
||||
static wchar_t vowels_cyrillic[] = {0x440, // also include 'р' [R]
|
||||
0x430,0x435,0x438,0x439,0x43e,0x443,0x44b,0x44d,0x44e,0x44f,0x450,0x451,0x456,0x457,0x45d,0x45e,0};
|
||||
static const unsigned char stress_amps_mk[8] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const unsigned char stress_amps_mk[8] = {17,17, 20,20, 20,24, 24,22 };
|
||||
static const short stress_lengths_mk[8] = {180,160, 200,200, 0,0, 220,230};
|
||||
|
||||
tr = new Translator();
|
||||
@@ -639,10 +647,9 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
case L('n','o'): // Norwegian
|
||||
{
|
||||
static const unsigned char stress_amps_no[] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const short stress_lengths_no[8] = {160,140, 200,200, 0,0, 220,210};
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_no,stress_amps_no);
|
||||
SetupTranslator(tr,stress_lengths_no,NULL);
|
||||
|
||||
tr->langopts.stress_rule = 0;
|
||||
SetLetterVowel(tr,'y');
|
||||
@@ -652,12 +659,13 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
case L('o','m'):
|
||||
{
|
||||
static const unsigned char stress_amps_om[] = {16,16, 20,20, 20,24, 24,22 };
|
||||
static const unsigned char stress_amps_om[] = {18,15, 20,20, 20,22, 22,22 };
|
||||
static const short stress_lengths_om[8] = {200,200, 200,200, 0,0, 200,200};
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_om,stress_amps_om);
|
||||
|
||||
tr->langopts.stress_rule = 3;
|
||||
tr->langopts.stress_rule = 2;
|
||||
tr->langopts.stress_flags = 0x16 + 0x80000;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -766,11 +774,13 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
case L('s','q'): // Albanian
|
||||
{
|
||||
static const short stress_lengths_sq[8] = {170, 170, 170, 170, 0, 0, 250, 270};
|
||||
static const unsigned char stress_amps_sq[8] = {17,12, 17,17, 20,20, 24,22 };
|
||||
static const short stress_lengths_sq[8] = {150, 150, 180, 180, 0, 0, 300, 300};
|
||||
static const unsigned char stress_amps_sq[8] = {16,12, 16,16, 20,20, 21,19 };
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_sq,stress_amps_sq);
|
||||
tr->langopts.stress_flags = 0x4 + 0x10;
|
||||
|
||||
tr->langopts.stress_rule = 2;
|
||||
tr->langopts.stress_flags = 0x16 + 0x100;
|
||||
SetLetterVowel(tr,'y');
|
||||
tr->langopts.numbers = 0x69 + 0x8000;
|
||||
}
|
||||
@@ -879,8 +889,8 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
case L('v','i'): // Vietnamese
|
||||
{
|
||||
static const short stress_lengths_vi[8] = {150, 150, 180, 180, 210, 220, 220, 280};
|
||||
static const unsigned char stress_amps_vi[] = {16,16, 16,16, 24,24, 24,22 };
|
||||
static const short stress_lengths_vi[8] = {150, 150, 180, 180, 210, 230, 230, 240};
|
||||
static const unsigned char stress_amps_vi[] = {16,16, 16,16, 22,22, 22,22 };
|
||||
static wchar_t vowels_vi[] = {
|
||||
0x61, 0xe0, 0xe1, 0x1ea3, 0xe3, 0x1ea1, // a
|
||||
0x103, 0x1eb1, 0x1eaf, 0x1eb3, 0x1eb5, 0x1eb7, // ă
|
||||
@@ -900,12 +910,12 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
tr->langopts.stress_rule = 0;
|
||||
tr->langopts.word_gap = 0x20; // length of a final vowel is less dependent on the next consonant
|
||||
tr->langopts.vowel_pause = 4;
|
||||
tr->langopts.word_gap = 0x21; // length of a final vowel is less dependent on the next consonant, don't merge consonant with next word
|
||||
// tr->langopts.vowel_pause = 4;
|
||||
tr->letter_groups[0] = vowels_vi;
|
||||
// tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
|
||||
tr->langopts.unstressed_wd1 = 2;
|
||||
tr->langopts.numbers = 0x0049;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
+2
-1
@@ -412,7 +412,7 @@ int IsSpace(unsigned int c)
|
||||
Translator::Translator()
|
||||
{//=====================
|
||||
int ix;
|
||||
static const unsigned char stress_amps2[] = {16,16, 20,20, 20,24, 24,21 };
|
||||
static const unsigned char stress_amps2[] = {17,17, 20,20, 20,24, 24,21 };
|
||||
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
|
||||
@@ -2111,6 +2111,7 @@ void *Translator::TranslateClause(FILE *f_text, const void *vp_input, int *tone_
|
||||
expect_verb_s=0;
|
||||
end_stressed_vowel=0;
|
||||
prev_dict_flags = 0;
|
||||
phonemes_repeat_count = 0;
|
||||
|
||||
sbuf[0] = 0;
|
||||
sbuf[1] = ' ';
|
||||
|
||||
+4
-1
@@ -56,7 +56,7 @@
|
||||
#define FLAG_ALT_TRANS 0x100000 // language specific
|
||||
#define FLAG_ALT2_TRANS 0x200000 // language specific
|
||||
|
||||
|
||||
#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
|
||||
#define BITNUM_FLAG_TEXTMODE 29
|
||||
@@ -314,6 +314,7 @@ typedef struct {
|
||||
// bit16= Don't diminish consecutive syllables within a word.
|
||||
// bit17= "priority" stress reduces other primary stress to "unstressed" not "secondary"
|
||||
// bit18= don't lengthen short vowels more than long vowels at end-of-clause
|
||||
// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
|
||||
|
||||
int stress_flags;
|
||||
int unstressed_wd1; // stress for $u word of 1 syllable
|
||||
@@ -416,6 +417,8 @@ public:
|
||||
|
||||
char phon_out[300];
|
||||
char word_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes
|
||||
char phonemes_repeat[20];
|
||||
int phonemes_repeat_count;
|
||||
|
||||
unsigned char stress_amps[8];
|
||||
unsigned char stress_amps_r[8];
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ extern USHORT voice_pcnt[N_PEAKS+1][3];
|
||||
extern voice_t *voice;
|
||||
extern int tone_points[12];
|
||||
|
||||
const char *SelectVoice(espeak_VOICE *voice_select);
|
||||
const char *SelectVoice(espeak_VOICE *voice_select, int *found);
|
||||
espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name);
|
||||
voice_t *LoadVoice(const char *voice_name, int control);
|
||||
voice_t *LoadVoiceVariant(const char *voice_name, int variant);
|
||||
|
||||
+15
-6
@@ -365,8 +365,11 @@ void VoiceReset(int tone_only)
|
||||
static int breath_widths[N_PEAKS] = {0,200,200,400,400,400,600,600,600};
|
||||
|
||||
// default is: pitch 82,118
|
||||
voice->pitch_base = 0x49000; // default, 73 << 12;
|
||||
voice->pitch_range = 0x0f30; // default = 0x1000
|
||||
// voice->pitch_base = 0x49000; // default, 73 << 12;
|
||||
// voice->pitch_range = 0x0f30; // default = 0x1000
|
||||
voice->pitch_base = 0x47000;
|
||||
voice->pitch_range = 3996;
|
||||
|
||||
voice->formant_factor = 256;
|
||||
|
||||
voice->echo_delay = 0;
|
||||
@@ -1122,7 +1125,7 @@ static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int s
|
||||
matching_parts += matching; // number of parts which match
|
||||
|
||||
if(matching_parts == 0)
|
||||
break; // no matching parts for this language
|
||||
continue; // no matching parts for this language
|
||||
|
||||
x = 5;
|
||||
// reduce the score if not all parts of the required language match
|
||||
@@ -1301,8 +1304,8 @@ espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name)
|
||||
|
||||
|
||||
|
||||
char const *SelectVoice(espeak_VOICE *voice_select)
|
||||
{//================================================
|
||||
char const *SelectVoice(espeak_VOICE *voice_select, int *found)
|
||||
{//============================================================
|
||||
// Returns a path within espeak-voices, with a possible +variant suffix
|
||||
// variant is an output-only parameter
|
||||
int nv; // number of candidates
|
||||
@@ -1323,6 +1326,7 @@ char const *SelectVoice(espeak_VOICE *voice_select)
|
||||
static espeak_VOICE voice_variants[N_VOICE_VARIANTS];
|
||||
static char voice_id[50];
|
||||
|
||||
*found = 1;
|
||||
memcpy(&voice_select2,voice_select,sizeof(voice_select2));
|
||||
|
||||
if(n_voices_list == 0)
|
||||
@@ -1366,6 +1370,7 @@ char const *SelectVoice(espeak_VOICE *voice_select)
|
||||
if(nv == 0)
|
||||
{
|
||||
// no matching voice, choose the default
|
||||
*found = 0;
|
||||
if((voices[0] = SelectVoiceByName(voices_list,"default")) != NULL)
|
||||
nv = 1;
|
||||
}
|
||||
@@ -1639,8 +1644,12 @@ espeak_ERROR SetVoiceByName(const char *name)
|
||||
espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector)
|
||||
{//============================================================
|
||||
const char *voice_id;
|
||||
int voice_found;
|
||||
|
||||
voice_id = SelectVoice(voice_selector);
|
||||
voice_id = SelectVoice(voice_selector, &voice_found);
|
||||
|
||||
if(voice_found == 0)
|
||||
return(EE_NOT_FOUND);
|
||||
|
||||
LoadVoiceVariant(voice_id,0);
|
||||
DoVoiceChange(voice);
|
||||
|
||||
+30
-40
@@ -59,7 +59,7 @@ voice_t *wvoice;
|
||||
|
||||
FILE *f_log = NULL;
|
||||
int option_waveout = 0;
|
||||
int option_harmonic1 = 11; // 10
|
||||
int option_harmonic1 = 10; // 10
|
||||
int option_log_frames = 0;
|
||||
static int flutter_amp = 64;
|
||||
|
||||
@@ -252,7 +252,7 @@ static const unsigned char Flutter_tab[N_FLUTTER] = {
|
||||
};
|
||||
|
||||
// waveform shape table for HF peaks, formants 6,7,8
|
||||
#define N_WAVEMULT 512
|
||||
#define N_WAVEMULT 128
|
||||
static int wavemult_offset=0;
|
||||
static int wavemult_max=0;
|
||||
|
||||
@@ -266,32 +266,8 @@ static unsigned char wavemult[N_WAVEMULT] = {
|
||||
218,213,207,201,194,188,181,174,166,159,152,144,136,128,121,113,
|
||||
105, 98, 90, 83, 76, 69, 62, 55, 49, 43, 37, 32, 27, 22, 18, 14,
|
||||
11, 8, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
|
||||
// set from y = pow(2,x) * 128, x=-1 to 1
|
||||
unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
|
||||
@@ -662,24 +638,31 @@ int WavegenOpenSound()
|
||||
}
|
||||
|
||||
|
||||
|
||||
int WavegenCloseSound()
|
||||
{//====================
|
||||
PaError active;
|
||||
|
||||
// check whether speaking has finished, and close the stream
|
||||
// if(pa_stream != NULL)
|
||||
if((pa_stream != NULL) && (WcmdqUsed() == 0)) // TEST, also check that queue is empty
|
||||
if(pa_stream != NULL)
|
||||
{
|
||||
#if USE_PORTAUDIO == 18
|
||||
active = Pa_StreamActive(pa_stream);
|
||||
#else
|
||||
active = Pa_IsStreamActive(pa_stream);
|
||||
#endif
|
||||
if(active == 0)
|
||||
if(WcmdqUsed() == 0) // also check that the queue is empty
|
||||
{
|
||||
Pa_CloseStream(pa_stream);
|
||||
pa_stream = NULL;
|
||||
return(1);
|
||||
if(active == 0)
|
||||
{
|
||||
Pa_CloseStream(pa_stream);
|
||||
pa_stream = NULL;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WavegenOpenSound(); // still items in the queue, shouldn't be closed
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
@@ -901,13 +884,20 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
}
|
||||
}
|
||||
|
||||
// increase bass, up to the F1 peak
|
||||
h=1;
|
||||
x = peaks[1].height * 24;
|
||||
for(f=pitch; f<peaks[1].freq; f+=pitch)
|
||||
{
|
||||
int y;
|
||||
int h2;
|
||||
// increase bass
|
||||
y = peaks[1].height * 10; // addition as a multiple of 1/256s
|
||||
h2 = (1000<<16)/pitch; // decrease until 1000Hz
|
||||
x = y/h2;
|
||||
h = 1;
|
||||
while(y > 0)
|
||||
{
|
||||
htab[h++] += x;
|
||||
htab[h++] += y;
|
||||
y -= x;
|
||||
}
|
||||
}
|
||||
|
||||
// find the nearest harmonic for HF peaks where we don't use shape
|
||||
for(; pk<N_PEAKS; pk++)
|
||||
@@ -1255,8 +1245,8 @@ int Wavegen()
|
||||
if((ix = amp_ix>>8) > 127) ix = 127;
|
||||
amp = amplitude_env[ix];
|
||||
amplitude2 = (amplitude2 * amp)/255;
|
||||
if(amp < 255)
|
||||
modulation_type = 7;
|
||||
// if(amp < 255)
|
||||
// modulation_type = 7;
|
||||
}
|
||||
|
||||
// introduce roughness into the sound by reducing the amplitude of
|
||||
|
||||
Reference in New Issue
Block a user