mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-02 22:07:12 +00:00
Merge branch 'master' into android
Conflicts: README.md
This commit is contained in:
@@ -1639,6 +1639,12 @@ int LoadSpect(const char *path, int control)
|
||||
}
|
||||
spectseq->Load(stream);
|
||||
|
||||
if(spectseq->frames == NULL)
|
||||
{
|
||||
error("Bad vowel file, no frames: '%s'",path);
|
||||
return(0);
|
||||
}
|
||||
|
||||
// do we need additional klatt data ?
|
||||
for(frame=0; frame < spectseq->numframes; frame++)
|
||||
{
|
||||
@@ -3616,6 +3622,11 @@ make_envs();
|
||||
"# ------- ---------\n");
|
||||
|
||||
|
||||
fprintf(f_errors, "Source data path = '%s'\n", path_source);
|
||||
strncpy0(fname,path_phfile.mb_str(wxConvLocal),sizeof(fname));
|
||||
fprintf(f_errors, "Master phonemes file = '%s'\n", fname);
|
||||
fprintf(f_errors, "Output to '%s/'\n\n", path_home);
|
||||
|
||||
sprintf(fname,"%s/%s",path_home,"phondata");
|
||||
f_phdata = fopen_log(f_errors,fname,"wb");
|
||||
|
||||
|
||||
+8
-7
@@ -919,8 +919,8 @@ int isHexDigit(int c)
|
||||
}
|
||||
|
||||
|
||||
static void copy_rule_string(char *string, int &state)
|
||||
{//===================================================
|
||||
static void copy_rule_string(char *string, int *state_out)
|
||||
{//=======================================================
|
||||
// state 0: conditional, 1=pre, 2=match, 3=post, 4=phonemes
|
||||
static char *outbuf[5] = {rule_cond, rule_pre, rule_match, rule_post, rule_phonemes};
|
||||
static int next_state[5] = {2,2,4,4,4};
|
||||
@@ -934,6 +934,7 @@ static void copy_rule_string(char *string, int &state)
|
||||
int value;
|
||||
int literal;
|
||||
int hexdigit_input = 0;
|
||||
int state = *state_out;
|
||||
MNEM_TAB *mr;
|
||||
|
||||
if(string[0] == 0) return;
|
||||
@@ -1174,7 +1175,7 @@ static void copy_rule_string(char *string, int &state)
|
||||
if(c == 0) break;
|
||||
}
|
||||
|
||||
state = next_state[state];
|
||||
*state_out = next_state[state];
|
||||
} // end of copy_rule_string
|
||||
|
||||
|
||||
@@ -1213,14 +1214,14 @@ static char *compile_rule(char *input)
|
||||
case ')': // end of prefix section
|
||||
*p = 0;
|
||||
state = 1;
|
||||
copy_rule_string(buf,state);
|
||||
copy_rule_string(buf,&state);
|
||||
p = buf;
|
||||
break;
|
||||
|
||||
case '(': // start of suffix section
|
||||
*p = 0;
|
||||
state = 2;
|
||||
copy_rule_string(buf,state);
|
||||
copy_rule_string(buf,&state);
|
||||
state = 3;
|
||||
p = buf;
|
||||
if(input[ix+1] == ' ')
|
||||
@@ -1234,14 +1235,14 @@ static char *compile_rule(char *input)
|
||||
case '\r':
|
||||
case 0: // end of line
|
||||
*p = 0;
|
||||
copy_rule_string(buf,state);
|
||||
copy_rule_string(buf,&state);
|
||||
finish=1;
|
||||
break;
|
||||
|
||||
case '\t': // end of section section
|
||||
case ' ':
|
||||
*p = 0;
|
||||
copy_rule_string(buf,state);
|
||||
copy_rule_string(buf,&state);
|
||||
p = buf;
|
||||
break;
|
||||
|
||||
|
||||
+25
-14
@@ -531,7 +531,7 @@ unsigned short ipa1[96] = {
|
||||
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x303,0x7f
|
||||
};
|
||||
|
||||
#define N_PHON_OUT 500
|
||||
#define N_PHON_OUT 500 // realloc increment
|
||||
static char *phon_out_buf = NULL;
|
||||
static int phon_out_size = 0;
|
||||
|
||||
@@ -974,7 +974,7 @@ int Unpronouncable(Translator *tr, char *word, int posn)
|
||||
|
||||
|
||||
|
||||
static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int &vowel_count, int &stressed_syllable, int control)
|
||||
static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int *vowel_count, int *stressed_syllable, int control)
|
||||
{//=================================================================================================================================================
|
||||
// control = 1, set stress to 1 for forced unstressed vowels
|
||||
unsigned char phcode;
|
||||
@@ -1001,7 +1001,7 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
{
|
||||
/* primary stress on preceeding vowel */
|
||||
j = count - 1;
|
||||
while((j > 0) && (stressed_syllable == 0) && (vowel_stress[j] < 4))
|
||||
while((j > 0) && (*stressed_syllable == 0) && (vowel_stress[j] < 4))
|
||||
{
|
||||
if((vowel_stress[j] != 0) && (vowel_stress[j] != 1))
|
||||
{
|
||||
@@ -1027,7 +1027,7 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
}
|
||||
else
|
||||
{
|
||||
if((ph->std_length < 4) || (stressed_syllable == 0))
|
||||
if((ph->std_length < 4) || (*stressed_syllable == 0))
|
||||
{
|
||||
stress = ph->std_length;
|
||||
|
||||
@@ -1067,14 +1067,14 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
*ph_out = 0;
|
||||
|
||||
/* has the position of the primary stress been specified by $1, $2, etc? */
|
||||
if(stressed_syllable > 0)
|
||||
if(*stressed_syllable > 0)
|
||||
{
|
||||
if(stressed_syllable >= count)
|
||||
stressed_syllable = count-1; // the final syllable
|
||||
if(*stressed_syllable >= count)
|
||||
*stressed_syllable = count-1; // the final syllable
|
||||
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
vowel_stress[*stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
primary_posn = stressed_syllable;
|
||||
primary_posn = *stressed_syllable;
|
||||
}
|
||||
|
||||
if(max_stress == 5)
|
||||
@@ -1099,8 +1099,8 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
max_stress = 4;
|
||||
}
|
||||
|
||||
stressed_syllable = primary_posn;
|
||||
vowel_count = count;
|
||||
*stressed_syllable = primary_posn;
|
||||
*vowel_count = count;
|
||||
return(max_stress);
|
||||
} // end of GetVowelStress
|
||||
|
||||
@@ -1122,7 +1122,7 @@ void ChangeWordStress(Translator *tr, char *word, int new_stress)
|
||||
signed char vowel_stress[N_WORD_PHONEMES/2];
|
||||
|
||||
strcpy((char *)phonetic,word);
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, vowel_count, stressed_syllable, 0);
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 0);
|
||||
|
||||
if(new_stress >= 4)
|
||||
{
|
||||
@@ -1249,7 +1249,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
unstressed_word = 1;
|
||||
}
|
||||
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, vowel_count, stressed_syllable, 1);
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 1);
|
||||
if((max_stress < 0) && dictionary_flags)
|
||||
{
|
||||
max_stress = 0;
|
||||
@@ -1551,6 +1551,17 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
break;
|
||||
|
||||
case 13: // LANG=ml, 1st unless 1st vowel is short and 2nd is long
|
||||
if(stressed_syllable == 0)
|
||||
{
|
||||
stressed_syllable = 1;
|
||||
if((vowel_length[1] == 0) && (vowel_count > 2) && (vowel_length[2] > 0))
|
||||
stressed_syllable = 2;
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* now guess the complete stress pattern */
|
||||
@@ -3049,7 +3060,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
|
||||
if(tr->transpose_min > 0)
|
||||
{
|
||||
strncpy0(word_buf,word, N_WORD_BYTES);
|
||||
wlen = TransposeAlphabet(tr, word_buf);
|
||||
wlen = TransposeAlphabet(tr, word_buf); // bit 6 indicates compressed characters
|
||||
word = word_buf;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -80,6 +80,7 @@ static const char *help_text =
|
||||
"--split=\"<minutes>\"\n"
|
||||
"\t Starts a new WAV file every <minutes>. Used with -w\n"
|
||||
"--stdout Write speech output to stdout\n"
|
||||
"--version Shows version number and date, and location of espeak-data\n"
|
||||
"--voices=<language>\n"
|
||||
"\t List the available voices for the specified language.\n"
|
||||
"\t If <language> is omitted, then list all voices.\n";
|
||||
|
||||
+58
-58
@@ -40,7 +40,7 @@
|
||||
//<decls and function prototypes
|
||||
|
||||
|
||||
// my_mutex: protects my_thread_is_talking,
|
||||
// my_mutex: protects my_thread_is_talking,
|
||||
static pthread_mutex_t my_mutex;
|
||||
static sem_t my_sem_start_is_required;
|
||||
static sem_t my_sem_stop_is_required;
|
||||
@@ -53,7 +53,7 @@ static int my_event_is_running=0;
|
||||
|
||||
enum {MIN_TIMEOUT_IN_MS=10,
|
||||
ACTIVITY_TIMEOUT=50, // in ms, check that the stream is active
|
||||
MAX_ACTIVITY_CHECK=6
|
||||
MAX_ACTIVITY_CHECK=6
|
||||
};
|
||||
|
||||
|
||||
@@ -93,12 +93,12 @@ void event_init(void)
|
||||
assert(-1 != sem_init(&my_sem_stop_is_required, 0, 0));
|
||||
assert(-1 != sem_init(&my_sem_stop_is_acknowledged, 0, 0));
|
||||
|
||||
pthread_attr_t a_attrib;
|
||||
pthread_attr_t a_attrib;
|
||||
if (pthread_attr_init (& a_attrib)
|
||||
|| pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE)
|
||||
|| pthread_create( &my_thread,
|
||||
& a_attrib,
|
||||
polling_thread,
|
||||
|| pthread_create( &my_thread,
|
||||
& a_attrib,
|
||||
polling_thread,
|
||||
(void*)NULL))
|
||||
{
|
||||
assert(0);
|
||||
@@ -126,7 +126,7 @@ ENTER("event_display");
|
||||
"MARK",
|
||||
"PLAY",
|
||||
"END",
|
||||
"MSG_TERMINATED"
|
||||
"MSG_TERMINATED"
|
||||
};
|
||||
|
||||
SHOW("event_display > event=0x%x\n",event);
|
||||
@@ -146,17 +146,17 @@ ENTER("event_display");
|
||||
static espeak_EVENT* event_copy (espeak_EVENT* event)
|
||||
{
|
||||
ENTER("event_copy");
|
||||
|
||||
|
||||
if (event==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
espeak_EVENT* a_event=(espeak_EVENT*)malloc(sizeof(espeak_EVENT));
|
||||
if (a_event)
|
||||
{
|
||||
memcpy(a_event, event, sizeof(espeak_EVENT));
|
||||
|
||||
|
||||
switch(event->type)
|
||||
{
|
||||
case espeakEVENT_MARK:
|
||||
@@ -166,14 +166,14 @@ static espeak_EVENT* event_copy (espeak_EVENT* event)
|
||||
a_event->id.name = strdup(event->id.name);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
event_display(a_event);
|
||||
|
||||
|
||||
return a_event;
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ ENTER("event_declare");
|
||||
return EE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
espeak_ERROR a_error = EE_OK;
|
||||
|
||||
if (!a_status)
|
||||
@@ -309,7 +309,7 @@ ENTER("event_declare");
|
||||
//
|
||||
// if (!a_status && !my_event_is_running && (a_error == EE_OK))
|
||||
// {
|
||||
// // quit when command is actually started
|
||||
// // quit when command is actually started
|
||||
// // (for possible forthcoming 'end of command' checks)
|
||||
SHOW_TIME("event_declare > post my_sem_start_is_required\n");
|
||||
sem_post(&my_sem_start_is_required);
|
||||
@@ -399,18 +399,18 @@ ENTER("sleep_until_timeout_or_stop_request");
|
||||
|
||||
add_time_in_ms( &ts, time_in_ms);
|
||||
|
||||
SHOW("polling_thread > sleep_until_timeout_or_stop_request > start sem_timedwait from %d.%09lu to %d.%09lu \n",
|
||||
SHOW("polling_thread > sleep_until_timeout_or_stop_request > start sem_timedwait from %d.%09lu to %d.%09lu \n",
|
||||
to.tv_sec, to.tv_nsec,
|
||||
ts.tv_sec, ts.tv_nsec);
|
||||
|
||||
while ((err = sem_timedwait(&my_sem_stop_is_required, &ts)) == -1
|
||||
while ((err = sem_timedwait(&my_sem_stop_is_required, &ts)) == -1
|
||||
&& errno == EINTR)
|
||||
{
|
||||
continue; // Restart when interrupted by handler
|
||||
}
|
||||
|
||||
assert (gettimeofday(&tv, NULL) != -1);
|
||||
SHOW("polling_thread > sleep_until_timeout_or_stop_request > stop sem_timedwait %d.%09lu \n",
|
||||
SHOW("polling_thread > sleep_until_timeout_or_stop_request > stop sem_timedwait %d.%09lu \n",
|
||||
tv.tv_sec, tv.tv_usec*1000);
|
||||
|
||||
if (err == 0)
|
||||
@@ -424,7 +424,7 @@ ENTER("sleep_until_timeout_or_stop_request");
|
||||
//>
|
||||
//<get_remaining_time
|
||||
// Asked for the time interval required for reaching the sample.
|
||||
// If the stream is opened but the audio samples are not played,
|
||||
// If the stream is opened but the audio samples are not played,
|
||||
// a timeout is started.
|
||||
|
||||
static int get_remaining_time(uint32_t sample, uint32_t* time_in_ms, int* stop_is_required)
|
||||
@@ -448,18 +448,18 @@ ENTER("get_remaining_time");
|
||||
|
||||
// stream opened but not active
|
||||
//
|
||||
// Several possible states:
|
||||
// * the stream is opened but not yet started:
|
||||
// Several possible states:
|
||||
// * the stream is opened but not yet started:
|
||||
//
|
||||
// wait for the start of stream
|
||||
//
|
||||
// * some samples have already been played,
|
||||
// * some samples have already been played,
|
||||
// ** the end of stream is reached
|
||||
// ** or there is an underrun
|
||||
//
|
||||
//
|
||||
// wait for the close of stream
|
||||
|
||||
*stop_is_required = sleep_until_timeout_or_stop_request( ACTIVITY_TIMEOUT);
|
||||
*stop_is_required = sleep_until_timeout_or_stop_request( ACTIVITY_TIMEOUT);
|
||||
}
|
||||
|
||||
return err;
|
||||
@@ -499,8 +499,8 @@ ENTER("polling_thread");
|
||||
SHOW_TIME("polling_thread > unlocked\n");
|
||||
|
||||
a_stop_is_required=0;
|
||||
a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required);
|
||||
if ((a_status==0) && a_stop_is_required)
|
||||
a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required); // NOTE: may set a_stop_is_required to -1
|
||||
if ((a_status==0) && (a_stop_is_required > 0))
|
||||
{
|
||||
SHOW("polling_thread > stop required (%d)\n", __LINE__);
|
||||
while(0 == sem_trywait(&my_sem_stop_is_required))
|
||||
@@ -513,27 +513,27 @@ ENTER("polling_thread");
|
||||
}
|
||||
|
||||
// In this loop, my_event_is_running = 1
|
||||
while (head && !a_stop_is_required)
|
||||
while (head && (a_stop_is_required <= 0))
|
||||
{
|
||||
SHOW_TIME("polling_thread > check head\n");
|
||||
while(0 == sem_trywait(&my_sem_start_is_required))
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
espeak_EVENT* event = (espeak_EVENT*)(head->data);
|
||||
assert(event);
|
||||
|
||||
|
||||
uint32_t time_in_ms = 0;
|
||||
|
||||
int err = get_remaining_time((uint32_t)event->sample,
|
||||
&time_in_ms,
|
||||
|
||||
int err = get_remaining_time((uint32_t)event->sample,
|
||||
&time_in_ms,
|
||||
&a_stop_is_required);
|
||||
if (a_stop_is_required)
|
||||
if (a_stop_is_required > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (err != 0)
|
||||
{
|
||||
{
|
||||
// No available time: the event is deleted.
|
||||
SHOW("polling_thread > %s\n","audio device down");
|
||||
a_status = pthread_mutex_lock(&my_mutex);
|
||||
@@ -547,22 +547,22 @@ ENTER("polling_thread");
|
||||
if (my_callback)
|
||||
{
|
||||
event_notify(event);
|
||||
// the user_data (and the type) are cleaned to be sure
|
||||
// the user_data (and the type) are cleaned to be sure
|
||||
// that MSG_TERMINATED is called twice (at delete time too).
|
||||
event->type=espeakEVENT_LIST_TERMINATED;
|
||||
event->user_data=NULL;
|
||||
}
|
||||
|
||||
|
||||
a_status = pthread_mutex_lock(&my_mutex);
|
||||
SHOW_TIME("polling_thread > locked\n");
|
||||
event_delete( (espeak_EVENT*)pop());
|
||||
a_status = pthread_mutex_unlock(&my_mutex);
|
||||
SHOW_TIME("polling_thread > unlocked\n");
|
||||
|
||||
|
||||
a_stop_is_required=0;
|
||||
a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required);
|
||||
|
||||
if ((a_status==0) && a_stop_is_required)
|
||||
|
||||
if ((a_status==0) && (a_stop_is_required > 0))
|
||||
{
|
||||
SHOW("polling_thread > stop required (%d)\n", __LINE__);
|
||||
while(0 == sem_trywait(&my_sem_stop_is_required))
|
||||
@@ -579,17 +579,17 @@ ENTER("polling_thread");
|
||||
a_stop_is_required = sleep_until_timeout_or_stop_request(time_in_ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
a_status = pthread_mutex_lock(&my_mutex);
|
||||
SHOW_TIME("polling_thread > locked\n");
|
||||
|
||||
|
||||
SHOW_TIME("polling_thread > my_event_is_running = 0\n");
|
||||
my_event_is_running = 0;
|
||||
|
||||
if(!a_stop_is_required)
|
||||
|
||||
if(a_stop_is_required <= 0)
|
||||
{
|
||||
a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required);
|
||||
if ((a_status==0) && a_stop_is_required)
|
||||
if ((a_status==0) && (a_stop_is_required > 0))
|
||||
{
|
||||
SHOW("polling_thread > stop required (%d)\n", __LINE__);
|
||||
while(0 == sem_trywait(&my_sem_stop_is_required))
|
||||
@@ -605,8 +605,8 @@ ENTER("polling_thread");
|
||||
a_status = pthread_mutex_unlock(&my_mutex);
|
||||
SHOW_TIME("polling_thread > unlocked\n");
|
||||
|
||||
if (a_stop_is_required)
|
||||
{
|
||||
if (a_stop_is_required > 0)
|
||||
{
|
||||
SHOW("polling_thread > %s\n","stop required!");
|
||||
// no mutex required since the stop command is synchronous
|
||||
// and waiting for my_sem_stop_is_acknowledged
|
||||
@@ -642,13 +642,13 @@ static espeak_ERROR push(void* the_data)
|
||||
SHOW("event > push > %s\n", "EE_BUFFER_FULL");
|
||||
return EE_BUFFER_FULL;
|
||||
}
|
||||
|
||||
|
||||
node *n = (node *)malloc(sizeof(node));
|
||||
if (n == NULL)
|
||||
{
|
||||
return EE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (head == NULL)
|
||||
{
|
||||
head = n;
|
||||
@@ -659,13 +659,13 @@ static espeak_ERROR push(void* the_data)
|
||||
tail->next = n;
|
||||
tail = n;
|
||||
}
|
||||
|
||||
|
||||
tail->next = NULL;
|
||||
tail->data = the_data;
|
||||
|
||||
|
||||
node_counter++;
|
||||
SHOW("event > push > counter=%d (uid=%d)\n",node_counter,((espeak_EVENT*)the_data)->unique_identifier);
|
||||
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
@@ -673,9 +673,9 @@ static void* pop()
|
||||
{
|
||||
ENTER("event > pop");
|
||||
void* the_data = NULL;
|
||||
|
||||
|
||||
assert((!head && !tail) || (head && tail));
|
||||
|
||||
|
||||
if (head != NULL)
|
||||
{
|
||||
node* n = head;
|
||||
@@ -685,12 +685,12 @@ static void* pop()
|
||||
node_counter--;
|
||||
SHOW("event > pop > event=0x%x (counter=%d, uid=%d)\n",the_data, node_counter,((espeak_EVENT*)the_data)->unique_identifier);
|
||||
}
|
||||
|
||||
|
||||
if(head == NULL)
|
||||
{
|
||||
tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
return the_data;
|
||||
}
|
||||
|
||||
@@ -698,10 +698,10 @@ static void* pop()
|
||||
static void init()
|
||||
{
|
||||
ENTER("event > init");
|
||||
|
||||
|
||||
while (event_delete( (espeak_EVENT*)pop() ))
|
||||
{}
|
||||
|
||||
|
||||
node_counter = 0;
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ static void init()
|
||||
void event_terminate()
|
||||
{
|
||||
ENTER("event_terminate");
|
||||
|
||||
|
||||
if (my_thread)
|
||||
{
|
||||
pthread_cancel(my_thread);
|
||||
|
||||
+31
-31
@@ -42,7 +42,7 @@
|
||||
//>
|
||||
//<decls and function prototypes
|
||||
|
||||
// my_mutex: protects my_thread_is_talking,
|
||||
// my_mutex: protects my_thread_is_talking,
|
||||
// my_stop_is_required, and the command fifo
|
||||
static pthread_mutex_t my_mutex;
|
||||
static int my_command_is_running = 0;
|
||||
@@ -50,7 +50,7 @@ static int my_stop_is_required = 0;
|
||||
// + fifo
|
||||
//
|
||||
|
||||
// my_thread: reads commands from the fifo, and runs them.
|
||||
// my_thread: reads commands from the fifo, and runs them.
|
||||
static pthread_t my_thread;
|
||||
static sem_t my_sem_start_is_required;
|
||||
static sem_t my_sem_stop_is_acknowledged;
|
||||
@@ -79,12 +79,12 @@ void fifo_init()
|
||||
assert(-1 != sem_init(&my_sem_start_is_required, 0, 0));
|
||||
assert(-1 != sem_init(&my_sem_stop_is_acknowledged, 0, 0));
|
||||
|
||||
pthread_attr_t a_attrib;
|
||||
pthread_attr_t a_attrib;
|
||||
if (pthread_attr_init (& a_attrib)
|
||||
|| pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE)
|
||||
|| pthread_create( &my_thread,
|
||||
& a_attrib,
|
||||
say_thread,
|
||||
|| pthread_create( &my_thread,
|
||||
& a_attrib,
|
||||
say_thread,
|
||||
(void*)NULL))
|
||||
{
|
||||
assert(0);
|
||||
@@ -106,8 +106,8 @@ void fifo_init()
|
||||
espeak_ERROR fifo_add_command (t_espeak_command* the_command)
|
||||
{
|
||||
ENTER("fifo_add_command");
|
||||
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
espeak_ERROR a_error = EE_OK;
|
||||
|
||||
if (!a_status)
|
||||
@@ -120,12 +120,12 @@ espeak_ERROR fifo_add_command (t_espeak_command* the_command)
|
||||
|
||||
if (!a_status && !my_command_is_running && (a_error == EE_OK))
|
||||
{
|
||||
// quit when command is actually started
|
||||
// quit when command is actually started
|
||||
// (for possible forthcoming 'end of command' checks)
|
||||
SHOW_TIME("fifo_add_command > post my_sem_start_is_required\n");
|
||||
sem_post(&my_sem_start_is_required);
|
||||
int val=1;
|
||||
while (val)
|
||||
while (val > 0)
|
||||
{
|
||||
usleep(50000); // TBD: event?
|
||||
sem_getvalue(&my_sem_start_is_required, &val);
|
||||
@@ -147,8 +147,8 @@ espeak_ERROR fifo_add_command (t_espeak_command* the_command)
|
||||
espeak_ERROR fifo_add_commands (t_espeak_command* command1, t_espeak_command* command2)
|
||||
{
|
||||
ENTER("fifo_add_command");
|
||||
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
espeak_ERROR a_error = EE_OK;
|
||||
|
||||
if (!a_status)
|
||||
@@ -171,12 +171,12 @@ espeak_ERROR fifo_add_commands (t_espeak_command* command1, t_espeak_command* co
|
||||
|
||||
if (!a_status && !my_command_is_running && (a_error == EE_OK))
|
||||
{
|
||||
// quit when one command is actually started
|
||||
// quit when one command is actually started
|
||||
// (for possible forthcoming 'end of command' checks)
|
||||
SHOW_TIME("fifo_add_command > post my_sem_start_is_required\n");
|
||||
sem_post(&my_sem_start_is_required);
|
||||
int val=1;
|
||||
while (val)
|
||||
while (val > 0)
|
||||
{
|
||||
usleep(50000); // TBD: event?
|
||||
sem_getvalue(&my_sem_start_is_required, &val);
|
||||
@@ -274,9 +274,9 @@ static int sleep_until_start_request_or_inactivity()
|
||||
int a_start_is_required=0;
|
||||
|
||||
// Wait for the start request (my_sem_start_is_required).
|
||||
// Besides this, if the audio stream is still busy,
|
||||
// check from time to time its end.
|
||||
// The end of the stream is confirmed by several checks
|
||||
// Besides this, if the audio stream is still busy,
|
||||
// check from time to time its end.
|
||||
// The end of the stream is confirmed by several checks
|
||||
// for filtering underflow.
|
||||
//
|
||||
int i=0;
|
||||
@@ -305,18 +305,18 @@ static int sleep_until_start_request_or_inactivity()
|
||||
|
||||
add_time_in_ms( &ts, INACTIVITY_TIMEOUT);
|
||||
|
||||
SHOW("fifo > sleep_until_start_request_or_inactivity > start sem_timedwait (start_is_required) from %d.%09lu to %d.%09lu \n",
|
||||
SHOW("fifo > sleep_until_start_request_or_inactivity > start sem_timedwait (start_is_required) from %d.%09lu to %d.%09lu \n",
|
||||
to.tv_sec, to.tv_nsec,
|
||||
ts.tv_sec, ts.tv_nsec);
|
||||
|
||||
while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1
|
||||
while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1
|
||||
&& errno == EINTR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
assert (gettimeofday(&tv, NULL) != -1);
|
||||
SHOW("fifo > sleep_until_start_request_or_inactivity > stop sem_timedwait (start_is_required, err=%d) %d.%09lu \n", err,
|
||||
SHOW("fifo > sleep_until_start_request_or_inactivity > stop sem_timedwait (start_is_required, err=%d) %d.%09lu \n", err,
|
||||
tv.tv_sec, tv.tv_usec*1000);
|
||||
|
||||
if (err==0)
|
||||
@@ -335,8 +335,8 @@ static void close_stream()
|
||||
{
|
||||
SHOW_TIME("fifo > close_stream > ENTER\n");
|
||||
|
||||
// Warning: a wave_close can be already required by
|
||||
// an external command (espeak_Cancel + fifo_stop), if so:
|
||||
// Warning: a wave_close can be already required by
|
||||
// an external command (espeak_Cancel + fifo_stop), if so:
|
||||
// my_stop_is_required = 1;
|
||||
|
||||
int a_status = pthread_mutex_lock(&my_mutex);
|
||||
@@ -358,7 +358,7 @@ static void close_stream()
|
||||
|
||||
a_stop_is_required = my_stop_is_required;
|
||||
a_status = pthread_mutex_unlock(&my_mutex);
|
||||
|
||||
|
||||
if (a_stop_is_required)
|
||||
{
|
||||
// acknowledge the stop request
|
||||
@@ -437,7 +437,7 @@ static void* say_thread(void*)
|
||||
};
|
||||
|
||||
if (my_stop_is_required)
|
||||
{
|
||||
{
|
||||
SHOW_TIME("say_thread > my_command_is_running = 0\n");
|
||||
my_command_is_running = 0;
|
||||
}
|
||||
@@ -453,7 +453,7 @@ static void* say_thread(void*)
|
||||
}
|
||||
|
||||
if (my_stop_is_required)
|
||||
{
|
||||
{
|
||||
// no mutex required since the stop command is synchronous
|
||||
// and waiting for my_sem_stop_is_acknowledged
|
||||
init(1);
|
||||
@@ -463,16 +463,16 @@ static void* say_thread(void*)
|
||||
while(0==sem_trywait(&my_sem_start_is_required))
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// acknowledge the stop request
|
||||
SHOW_TIME("say_thread > post my_sem_stop_is_acknowledged\n");
|
||||
int a_status = sem_post(&my_sem_stop_is_acknowledged);
|
||||
assert( a_status != -1);
|
||||
}
|
||||
// and wait for the next start
|
||||
SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");
|
||||
SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ static espeak_ERROR push(t_espeak_command* the_command)
|
||||
{
|
||||
return EE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (head == NULL)
|
||||
{
|
||||
head = n;
|
||||
@@ -527,7 +527,7 @@ static espeak_ERROR push(t_espeak_command* the_command)
|
||||
tail->next = n;
|
||||
tail = n;
|
||||
}
|
||||
|
||||
|
||||
tail->next = NULL;
|
||||
tail->data = the_command;
|
||||
|
||||
@@ -563,7 +563,7 @@ static t_espeak_command* pop()
|
||||
}
|
||||
|
||||
display_espeak_command(the_command);
|
||||
|
||||
|
||||
return the_command;
|
||||
}
|
||||
|
||||
|
||||
+16
-16
@@ -338,7 +338,7 @@ static void count_pitch_vowels(int start, int end, int clause_end)
|
||||
number_body = 0;
|
||||
number_tail = 0; /* number between tonic syllable and next primary */
|
||||
last_primary = -1;
|
||||
|
||||
|
||||
for(ix=start; ix<end; ix++)
|
||||
{
|
||||
stress = syllable_tab[ix].stress; /* marked stress level */
|
||||
@@ -527,7 +527,7 @@ int secondary=2; // 2
|
||||
n_steps = count_increments(syl_ix+1, head_final, 4);
|
||||
pitch = tune->onset << 8;
|
||||
used_onset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(n_steps > tune->head_max_steps)
|
||||
n_steps = tune->head_max_steps;
|
||||
@@ -697,7 +697,7 @@ static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *t
|
||||
n_primary--;
|
||||
if((tn->backwards) && (n_primary < 2))
|
||||
{
|
||||
pitch = tn->backwards[n_primary] << 8;
|
||||
pitch = tn->backwards[n_primary] << 8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ static void SetPitchGradient(int start_ix, int end_ix, int start_pitch, int end_
|
||||
|
||||
if(n_increments <= 0)
|
||||
return;
|
||||
|
||||
|
||||
if(n_increments > 1)
|
||||
{
|
||||
increment = increment / n_increments;
|
||||
@@ -802,7 +802,7 @@ static int calc_pitches2(int start, int end, int tune_number)
|
||||
|
||||
if(option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE)
|
||||
{
|
||||
tone_posn = tone_posn2; // put tone on the penultimate stressed word
|
||||
tone_posn = tone_posn2; // put tone on the penultimate stressed word
|
||||
}
|
||||
ix = SetHeadIntonation(tune, ix, tone_posn, 0);
|
||||
|
||||
@@ -811,7 +811,7 @@ static int calc_pitches2(int start, int end, int tune_number)
|
||||
|
||||
/* tonic syllable */
|
||||
/******************/
|
||||
|
||||
|
||||
// if(tn->flags & T_EMPH)
|
||||
// {
|
||||
// syllable_tab[ix].flags |= SYL_EMPHASIS;
|
||||
@@ -836,7 +836,7 @@ static int calc_pitches2(int start, int end, int tune_number)
|
||||
|
||||
/* tail, after the tonic syllable */
|
||||
/**********************************/
|
||||
|
||||
|
||||
SetPitchGradient(ix, end, tune->tail_start, tune->tail_end);
|
||||
|
||||
return(tone_pitch_env);
|
||||
@@ -877,7 +877,7 @@ static int calc_pitches(int control, int start, int end, int tune_number)
|
||||
|
||||
if(option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE)
|
||||
{
|
||||
tone_posn = tone_posn2; // put tone on the penultimate stressed word
|
||||
tone_posn = tone_posn2; // put tone on the penultimate stressed word
|
||||
}
|
||||
ix = calc_pitch_segment(ix,tone_posn, th, tn, PRIMARY, continuing);
|
||||
// ix = SetBodyIntonation(&tunes[0], ix, tone_posn, 0);
|
||||
@@ -887,7 +887,7 @@ static int calc_pitches(int control, int start, int end, int tune_number)
|
||||
|
||||
/* tonic syllable */
|
||||
/******************/
|
||||
|
||||
|
||||
if(tn->flags & T_EMPH)
|
||||
{
|
||||
syllable_tab[ix].flags |= SYL_EMPHASIS;
|
||||
@@ -912,7 +912,7 @@ static int calc_pitches(int control, int start, int end, int tune_number)
|
||||
|
||||
/* tail, after the tonic syllable */
|
||||
/**********************************/
|
||||
|
||||
|
||||
SetPitchGradient(ix, end, tn->tail_start, tn->tail_end);
|
||||
|
||||
return(tone_pitch_env);
|
||||
@@ -1037,7 +1037,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
if(tph->mnemonic == 0x343132) // [214]
|
||||
prev_p->tone_ph = PhonemeCode2('3','5');
|
||||
else
|
||||
prev_p->tone_ph = PhonemeCode2('2','1');
|
||||
prev_p->tone_ph = PhonemeCode2('2','1');
|
||||
}
|
||||
if((prev_tph->mnemonic == 0x3135) && (tph->mnemonic == 0x3135)) // [51] + [51]
|
||||
{
|
||||
@@ -1176,7 +1176,7 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
}
|
||||
else
|
||||
{
|
||||
group_tone = tr->punct_to_tone[option][clause_type];
|
||||
group_tone = tr->punct_to_tone[option][clause_type];
|
||||
group_tone_emph = tr->punct_to_tone[option][5]; // emphatic form of statement
|
||||
group_tone_comma = tr->punct_to_tone[option][1]; // emphatic form of statement
|
||||
}
|
||||
@@ -1283,14 +1283,14 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
calc_pitches(option, st_start, st_ix, group_tone);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// unpack pitch data
|
||||
st_ix=0;
|
||||
for(ix=ph_start; ix < ph_end; ix++)
|
||||
{
|
||||
p = &phoneme_list[ix];
|
||||
p->stresslevel = syllable_tab[st_ix].stress;
|
||||
|
||||
|
||||
if(p->synthflags & SFLAG_SYLLABLE)
|
||||
{
|
||||
syl = &syllable_tab[st_ix];
|
||||
@@ -1327,11 +1327,11 @@ if(p->tone_ph)
|
||||
{
|
||||
p->stresslevel |= 8; // emphasized
|
||||
}
|
||||
|
||||
|
||||
st_ix++;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of CalcPitches
|
||||
|
||||
|
||||
|
||||
|
||||
+38
-35
@@ -851,47 +851,50 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
// speak in the language for this alphabet (or English)
|
||||
ph_buf[2] = SetTranslator2(WordToString2(language));
|
||||
|
||||
if(((code = letter - 0xac00) >= 0) && (letter <= 0xd7af))
|
||||
if(translator2 != NULL)
|
||||
{
|
||||
// Special case for Korean letters.
|
||||
// break a syllable hangul into 2 or 3 individual jamo
|
||||
|
||||
hangul_buf[0] = ' ';
|
||||
p3 = &hangul_buf[1];
|
||||
if((initial = (code/28)/21) != 11)
|
||||
if(((code = letter - 0xac00) >= 0) && (letter <= 0xd7af))
|
||||
{
|
||||
p3 += utf8_out(initial + 0x1100, p3);
|
||||
// Special case for Korean letters.
|
||||
// break a syllable hangul into 2 or 3 individual jamo
|
||||
|
||||
hangul_buf[0] = ' ';
|
||||
p3 = &hangul_buf[1];
|
||||
if((initial = (code/28)/21) != 11)
|
||||
{
|
||||
p3 += utf8_out(initial + 0x1100, p3);
|
||||
}
|
||||
utf8_out(((code/28) % 21) + 0x1161, p3); // medial
|
||||
utf8_out((code % 28) + 0x11a7, &p3[3]); // final
|
||||
p3[6] = ' ';
|
||||
p3[7] = 0;
|
||||
ph_buf[3] = 0;
|
||||
TranslateRules(translator2, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL);
|
||||
SetWordStress(translator2, &ph_buf[3], NULL, -1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1);
|
||||
}
|
||||
utf8_out(((code/28) % 21) + 0x1161, p3); // medial
|
||||
utf8_out((code % 28) + 0x11a7, &p3[3]); // final
|
||||
p3[6] = ' ';
|
||||
p3[7] = 0;
|
||||
ph_buf[3] = 0;
|
||||
TranslateRules(translator2, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL);
|
||||
SetWordStress(translator2, &ph_buf[3], NULL, -1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1);
|
||||
}
|
||||
|
||||
if(ph_buf[3] == phonSWITCH)
|
||||
{
|
||||
// another level of language change
|
||||
ph_buf[2] = SetTranslator2(&ph_buf[4]);
|
||||
LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1);
|
||||
}
|
||||
if(ph_buf[3] == phonSWITCH)
|
||||
{
|
||||
// another level of language change
|
||||
ph_buf[2] = SetTranslator2(&ph_buf[4]);
|
||||
LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1);
|
||||
}
|
||||
|
||||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
|
||||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
|
||||
|
||||
if(ph_buf[3] != 0)
|
||||
{
|
||||
ph_buf[0] = phonPAUSE;
|
||||
ph_buf[1] = phonSWITCH;
|
||||
len = strlen(&ph_buf[3]) + 3;
|
||||
ph_buf[len] = phonSWITCH; // switch back
|
||||
ph_buf[len+1] = tr->phoneme_tab_ix;
|
||||
ph_buf[len+2] = 0;
|
||||
if(ph_buf[3] != 0)
|
||||
{
|
||||
ph_buf[0] = phonPAUSE;
|
||||
ph_buf[1] = phonSWITCH;
|
||||
len = strlen(&ph_buf[3]) + 3;
|
||||
ph_buf[len] = phonSWITCH; // switch back
|
||||
ph_buf[len+1] = tr->phoneme_tab_ix;
|
||||
ph_buf[len+2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-26
@@ -1264,7 +1264,7 @@ static const char *VoiceFromStack()
|
||||
|
||||
|
||||
|
||||
static void ProcessParamStack(char *outbuf, int &outix)
|
||||
static void ProcessParamStack(char *outbuf, int *outix)
|
||||
{//====================================================
|
||||
// Set the speech parameters from the parameter stack
|
||||
int param;
|
||||
@@ -1313,8 +1313,8 @@ static void ProcessParamStack(char *outbuf, int &outix)
|
||||
}
|
||||
|
||||
speech_parameters[param] = new_parameters[param];
|
||||
strcpy(&outbuf[outix],buf);
|
||||
outix += strlen(buf);
|
||||
strcpy(&outbuf[*outix],buf);
|
||||
*outix += strlen(buf);
|
||||
}
|
||||
}
|
||||
} // end of ProcessParamStack
|
||||
@@ -1338,7 +1338,7 @@ static PARAM_STACK *PushParamStack(int tag_type)
|
||||
} // end of PushParamStack
|
||||
|
||||
|
||||
static void PopParamStack(int tag_type, char *outbuf, int &outix)
|
||||
static void PopParamStack(int tag_type, char *outbuf, int *outix)
|
||||
{//==============================================================
|
||||
// unwind the stack up to and including the previous tag of this type
|
||||
int ix;
|
||||
@@ -1508,10 +1508,14 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
|
||||
if((tail[0]=='s') && (tail[1]=='t'))
|
||||
{
|
||||
#ifdef PLATFORM_RISCOS
|
||||
*value_out = 100;
|
||||
#else
|
||||
double x;
|
||||
// convert from semitones to a frequency percentage
|
||||
x = pow(double(2.0),double((value*sign)/12)) * 100;
|
||||
x = pow((double)2.0,(double)((value*sign)/12)) * 100;
|
||||
*value_out = (int)x;
|
||||
#endif
|
||||
return(2); // percentage
|
||||
}
|
||||
|
||||
@@ -1739,7 +1743,7 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
|
||||
} // end of SetProsodyParemeter
|
||||
|
||||
|
||||
static int ReplaceKeyName(char *outbuf, int index, int &outix)
|
||||
static int ReplaceKeyName(char *outbuf, int index, int *outix)
|
||||
{//===========================================================
|
||||
// Replace some key-names by single characters, so they can be pronounced in different languages
|
||||
static MNEM_TAB keynames[] = {
|
||||
@@ -1758,14 +1762,14 @@ static int ReplaceKeyName(char *outbuf, int index, int &outix)
|
||||
if((letter = LookupMnem(keynames, p)) != 0)
|
||||
{
|
||||
ix = utf8_out(letter, p);
|
||||
outix = index + ix;
|
||||
*outix = index + ix;
|
||||
return(letter);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outbuf, int self_closing)
|
||||
static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, int self_closing)
|
||||
{//==================================================================================================
|
||||
// xml_buf is the tag and attributes with a zero terminator in place of the original '>'
|
||||
// returns a clause terminator value.
|
||||
@@ -1850,7 +1854,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
// closing tag
|
||||
if((tag_type = LookupMnem(ssmltags,&tag_name[1])) != HTML_NOSPACE)
|
||||
{
|
||||
outbuf[outix++] = ' ';
|
||||
outbuf[(*outix)++] = ' ';
|
||||
}
|
||||
tag_type += SSML_CLOSE;
|
||||
}
|
||||
@@ -1859,7 +1863,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
if((tag_type = LookupMnem(ssmltags,tag_name)) != HTML_NOSPACE)
|
||||
{
|
||||
// separate SSML tags from the previous word (but not HMTL tags such as <b> <font> which can occur inside a word)
|
||||
outbuf[outix++] = ' ';
|
||||
outbuf[(*outix)++] = ' ';
|
||||
}
|
||||
|
||||
if(self_closing && ignore_if_self_closing[tag_type])
|
||||
@@ -1959,22 +1963,22 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
}
|
||||
|
||||
sprintf(buf,"%c%dY",CTRL_EMBEDDED,value);
|
||||
strcpy(&outbuf[outix],buf);
|
||||
outix += strlen(buf);
|
||||
strcpy(&outbuf[*outix],buf);
|
||||
*outix += strlen(buf);
|
||||
|
||||
sayas_start = outix;
|
||||
sayas_start = *outix;
|
||||
sayas_mode = value; // punctuation doesn't end clause during SAY-AS
|
||||
break;
|
||||
|
||||
case SSML_SAYAS + SSML_CLOSE:
|
||||
if(sayas_mode == SAYAS_KEY)
|
||||
{
|
||||
outbuf[outix] = 0;
|
||||
outbuf[*outix] = 0;
|
||||
ReplaceKeyName(outbuf, sayas_start, outix);
|
||||
}
|
||||
|
||||
outbuf[outix++] = CTRL_EMBEDDED;
|
||||
outbuf[outix++] = 'Y';
|
||||
outbuf[(*outix)++] = CTRL_EMBEDDED;
|
||||
outbuf[(*outix)++] = 'Y';
|
||||
sayas_mode = 0;
|
||||
break;
|
||||
|
||||
@@ -1983,7 +1987,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
{
|
||||
// use the alias rather than the text
|
||||
ignore_text = 1;
|
||||
outix += attrcopy_utf8(&outbuf[outix],attr1,n_outbuf-outix);
|
||||
*outix += attrcopy_utf8(&outbuf[*outix],attr1,n_outbuf-*outix);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2013,8 +2017,8 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
if((index = AddNameData(buf,0)) >= 0)
|
||||
{
|
||||
sprintf(buf,"%c%dM",CTRL_EMBEDDED,index);
|
||||
strcpy(&outbuf[outix],buf);
|
||||
outix += strlen(buf);
|
||||
strcpy(&outbuf[*outix],buf);
|
||||
*outix += strlen(buf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2041,8 +2045,8 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
if(index >= 0)
|
||||
{
|
||||
sprintf(buf,"%c%dI",CTRL_EMBEDDED,index);
|
||||
strcpy(&outbuf[outix],buf);
|
||||
outix += strlen(buf);
|
||||
strcpy(&outbuf[*outix],buf);
|
||||
*outix += strlen(buf);
|
||||
sp->parameter[espeakSILENCE] = 1;
|
||||
}
|
||||
}
|
||||
@@ -2054,8 +2058,8 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
if(uri_callback(1,uri,xmlbase) == 0)
|
||||
{
|
||||
sprintf(buf,"%c%dU",CTRL_EMBEDDED,index);
|
||||
strcpy(&outbuf[outix],buf);
|
||||
outix += strlen(buf);
|
||||
strcpy(&outbuf[*outix],buf);
|
||||
*outix += strlen(buf);
|
||||
sp->parameter[espeakSILENCE] = 1;
|
||||
}
|
||||
}
|
||||
@@ -2085,8 +2089,8 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb
|
||||
if(value < 3)
|
||||
{
|
||||
// adjust prepause on the following word
|
||||
sprintf(&outbuf[outix],"%c%dB",CTRL_EMBEDDED,value);
|
||||
outix += 3;
|
||||
sprintf(&outbuf[*outix],"%c%dB",CTRL_EMBEDDED,value);
|
||||
*outix += 3;
|
||||
terminator = 0;
|
||||
}
|
||||
value = break_value[value];
|
||||
@@ -2433,7 +2437,7 @@ f_input = f_in; // for GetC etc
|
||||
self_closing = 1;
|
||||
}
|
||||
|
||||
terminator = ProcessSsmlTag(xml_buf,buf,ix,n_buf,self_closing);
|
||||
terminator = ProcessSsmlTag(xml_buf,buf,&ix,n_buf,self_closing);
|
||||
|
||||
if(terminator != 0)
|
||||
{
|
||||
|
||||
@@ -114,6 +114,7 @@ static const char *help_text =
|
||||
"--split=\"<minutes>\"\n"
|
||||
"\t Starts a new WAV file every <minutes>. Used with -w\n"
|
||||
"--stdout Write speech output to stdout\n"
|
||||
"--version Shows version number and date, and location of espeak-data\n"
|
||||
"--voices=<language>\n"
|
||||
"\t List the available voices for the specified language.\n"
|
||||
"\t If <language> is omitted, then list all voices.\n";
|
||||
|
||||
+3
-2
@@ -766,10 +766,11 @@ ENTER("espeak_Initialize");
|
||||
#ifdef PLATFORM_RISCOS
|
||||
setlocale(LC_CTYPE,"ISO8859-1");
|
||||
#else
|
||||
if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
|
||||
if(setlocale(LC_CTYPE,"C.UTF-8") == NULL)
|
||||
{
|
||||
if(setlocale(LC_CTYPE,"UTF-8") == NULL)
|
||||
setlocale(LC_CTYPE,"");
|
||||
if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
|
||||
setlocale(LC_CTYPE,"");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+6
-3
@@ -314,10 +314,13 @@ ESPEAK_API espeak_ERROR espeak_Synth(const void *text,
|
||||
espeakENDPAUSE If set then a sentence pause is added at the end of the text. If not set then
|
||||
this pause is suppressed.
|
||||
|
||||
unique_identifier: message identifier; helpful for identifying later
|
||||
data supplied to the callback.
|
||||
unique_identifier: This must be either NULL, or point to an integer variable to
|
||||
which eSpeak writes a message identifier number.
|
||||
eSpeak includes this number in espeak_EVENT messages which are the result of
|
||||
this call of espeak_Synth().
|
||||
|
||||
user_data: pointer which will be passed to the callback function.
|
||||
user_data: a pointer (or NULL) which will be passed to the callback function in
|
||||
espeak_EVENT messages.
|
||||
|
||||
Return: EE_OK: operation achieved
|
||||
EE_BUFFER_FULL: the command can not be buffered;
|
||||
|
||||
+16
-2
@@ -675,7 +675,7 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
break;
|
||||
|
||||
case '[': // width--
|
||||
pk->pkright -= 1;
|
||||
pk->pkright -= 10;
|
||||
if(pk->pkright < 0)
|
||||
pk->pkright = 0;
|
||||
display = 1;
|
||||
@@ -683,7 +683,21 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
break;
|
||||
|
||||
case ']': // width++
|
||||
pk->pkright += 1;
|
||||
pk->pkright += 10;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
case '{': // width--
|
||||
pk->pkright -= 2;
|
||||
if(pk->pkright < 0)
|
||||
pk->pkright = 0;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
case '}': // width++
|
||||
pk->pkright += 2;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
//#define USE_PORTAUDIO
|
||||
//#define USE_PULSEAUDIO
|
||||
#define USE_NANOSLEEP
|
||||
#define __cdecl
|
||||
#define __cdecl
|
||||
//#define ESPEAK_API extern "C"
|
||||
|
||||
#ifdef _ESPEAKEDIT
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.47.11d 11.Jun.13";
|
||||
const char *version_string = "1.47.12 23.Sep.13";
|
||||
const int version_phdata = 0x014709;
|
||||
|
||||
int option_device_number = -1;
|
||||
@@ -67,7 +67,7 @@ int vowel_transition[4];
|
||||
int vowel_transition0;
|
||||
int vowel_transition1;
|
||||
|
||||
int FormantTransition2(frameref_t *seq, int &n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which);
|
||||
int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which);
|
||||
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
// do we need to modify a frame for blending with a consonant?
|
||||
if((this_ph->type == phVOWEL) && (fmt_params->fmt2_addr == 0) && (fmt_params->use_vowelin))
|
||||
{
|
||||
seq_len_adjust += FormantTransition2(frames,nf,fmt_params->transition0,fmt_params->transition1,NULL,which);
|
||||
seq_len_adjust += FormantTransition2(frames,&nf,fmt_params->transition0,fmt_params->transition1,NULL,which);
|
||||
}
|
||||
|
||||
length1 = 0;
|
||||
|
||||
+10
-10
@@ -336,7 +336,7 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
|
||||
q = wcmdq[wcmdq_tail];
|
||||
q[0] = WCMD_WAVE2;
|
||||
q[1] = length | (wav_length << 16); // length in samples
|
||||
q[2] = long64(&wavefile_data[index]);
|
||||
q[2] = (long64)(&wavefile_data[index]);
|
||||
q[3] = wav_scale + (amp << 8);
|
||||
WcmdqInc();
|
||||
return(length);
|
||||
@@ -357,7 +357,7 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
|
||||
q = wcmdq[wcmdq_tail];
|
||||
q[0] = WCMD_WAVE;
|
||||
q[1] = x; // length in samples
|
||||
q[2] = long64(&wavefile_data[index]);
|
||||
q[2] = (long64)(&wavefile_data[index]);
|
||||
q[3] = wav_scale + (amp << 8);
|
||||
WcmdqInc();
|
||||
|
||||
@@ -372,7 +372,7 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
|
||||
q = wcmdq[wcmdq_tail];
|
||||
q[0] = WCMD_WAVE;
|
||||
q[1] = len4*2; // length in samples
|
||||
q[2] = long64(&wavefile_data[index+x]);
|
||||
q[2] = (long64)(&wavefile_data[index+x]);
|
||||
q[3] = wav_scale + (amp << 8);
|
||||
WcmdqInc();
|
||||
|
||||
@@ -388,7 +388,7 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
|
||||
q = wcmdq[wcmdq_tail];
|
||||
q[0] = WCMD_WAVE;
|
||||
q[1] = length; // length in samples
|
||||
q[2] = long64(&wavefile_data[index+x]);
|
||||
q[2] = (long64)(&wavefile_data[index+x]);
|
||||
q[3] = wav_scale + (amp << 8);
|
||||
WcmdqInc();
|
||||
}
|
||||
@@ -613,7 +613,7 @@ static int VowelCloseness(frame_t *fr)
|
||||
}
|
||||
|
||||
|
||||
int FormantTransition2(frameref_t *seq, int &n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which)
|
||||
int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which)
|
||||
{//==============================================================================================================================
|
||||
int ix;
|
||||
int formant;
|
||||
@@ -639,7 +639,7 @@ static short vcolouring[N_VCOLOUR][5] = {
|
||||
|
||||
frame_t *fr = NULL;
|
||||
|
||||
if(n_frames < 2)
|
||||
if(*n_frames < 2)
|
||||
return(0);
|
||||
|
||||
len = (data1 & 0x3f) * 2;
|
||||
@@ -714,8 +714,8 @@ if(voice->klattv[0])
|
||||
|
||||
if(flags & 8)
|
||||
{
|
||||
fr = CopyFrame(seq[n_frames-1].frame,0);
|
||||
seq[n_frames-1].frame = fr;
|
||||
fr = CopyFrame(seq[*n_frames-1].frame,0);
|
||||
seq[*n_frames-1].frame = fr;
|
||||
rms = RMS_GLOTTAL1;
|
||||
|
||||
// degree of glottal-stop effect depends on closeness of vowel (indicated by f1 freq)
|
||||
@@ -723,7 +723,7 @@ if(voice->klattv[0])
|
||||
}
|
||||
else
|
||||
{
|
||||
fr = DuplicateLastFrame(seq,n_frames++,len);
|
||||
fr = DuplicateLastFrame(seq,(*n_frames)++,len);
|
||||
if(len > 36)
|
||||
seq_len_adjust += (len - 36);
|
||||
|
||||
@@ -737,7 +737,7 @@ if(voice->klattv[0])
|
||||
|
||||
if((vcolour > 0) && (vcolour <= N_VCOLOUR))
|
||||
{
|
||||
for(ix=0; ix<n_frames; ix++)
|
||||
for(ix=0; ix < *n_frames; ix++)
|
||||
{
|
||||
fr = CopyFrame(seq[ix].frame,0);
|
||||
seq[ix].frame = fr;
|
||||
|
||||
+16
-4
@@ -39,6 +39,7 @@
|
||||
#define L_qa 0x716100
|
||||
#define L_grc 0x677263 // grc Ancient Greek
|
||||
#define L_jbo 0x6a626f // jbo Lojban
|
||||
#define L_mni 0x6d6e69 // mni Manipuri
|
||||
#define L_pap 0x706170 // pap Papiamento]
|
||||
#define L_qvi 0x717669 // qvi Kichwa
|
||||
#define L_shs 0x736873 // shs Shuswap / Secwepemctsin
|
||||
@@ -81,7 +82,7 @@ ALPHABET alphabets [] = {
|
||||
{"_hi", OFFSET_DEVANAGARI, 0x900, 0x97f,L('h','i'), AL_WORDS},
|
||||
{"_bn", OFFSET_BENGALI, 0x0980, 0x9ff, L('b','n'), AL_WORDS},
|
||||
{"_gur", OFFSET_GURMUKHI, 0xa00, 0xa7f, L('p','a'), AL_WORDS},
|
||||
{"_gu", OFFSET_GUJARATI, 0xa80, 0xaff, 0, 0},
|
||||
{"_gu", OFFSET_GUJARATI, 0xa80, 0xaff, L('g','u'), AL_WORDS},
|
||||
{"_or", OFFSET_ORIYA, 0xb00, 0xb7f, 0, 0},
|
||||
{"_ta", OFFSET_TAMIL, 0xb80, 0xbff, L('t','a'), AL_WORDS},
|
||||
{"_te", OFFSET_TELUGU, 0xc00, 0xc7f, L('t','e'), 0},
|
||||
@@ -460,7 +461,7 @@ Translator *SelectTranslator(const char *name)
|
||||
Translator *tr;
|
||||
|
||||
static const short stress_lengths_equal[8] = {230, 230, 230, 230, 0, 0, 230, 230};
|
||||
static const unsigned char stress_amps_equal[8] = {18,18, 18,18, 18,18, 18,18 };
|
||||
static const unsigned char stress_amps_equal[8] = {19,19, 19,19, 19,19, 19,19 };
|
||||
|
||||
static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 190, 240};
|
||||
static const unsigned char stress_amps_fr[8] = {18,16, 18,18, 18,18, 18,18 };
|
||||
@@ -531,6 +532,8 @@ Translator *SelectTranslator(const char *name)
|
||||
break;
|
||||
|
||||
case L('b','n'): // Bengali
|
||||
case L('a','s'): // Assamese
|
||||
case L_mni: // Manipuri (temporary placement - it's not indo-european)
|
||||
{
|
||||
static const short stress_lengths_bn[8] = {180, 180, 210, 210, 0, 0, 230, 240};
|
||||
static const unsigned char stress_amps_bn[8] = {18,18, 18,18, 20,20, 22,22 };
|
||||
@@ -852,6 +855,7 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
case L('h','i'): // Hindi
|
||||
case L('n','e'): // Nepali
|
||||
case L('o','r'): // Oriya
|
||||
case L('p','a'): // Punjabi
|
||||
case L('g','u'): // Gujarati
|
||||
{
|
||||
@@ -887,6 +891,11 @@ SetupTranslator(tr,stress_lengths_equal,stress_amps_equal);
|
||||
tr->langopts.max_digits = 22;
|
||||
tr->langopts.numbers2 |= NUM2_ENGLISH_NUMERALS;
|
||||
}
|
||||
else
|
||||
if(name2 == L('o','r'))
|
||||
{
|
||||
tr->letter_bits_offset = OFFSET_ORIYA;
|
||||
}
|
||||
SetIndicLetters(tr);
|
||||
}
|
||||
break;
|
||||
@@ -1455,8 +1464,8 @@ SetLengthMods(tr,3); // all equal
|
||||
break;
|
||||
|
||||
case L('t','a'): // Tamil
|
||||
case L('m','l'): // Malayalam
|
||||
case L('k','n'): // Kannada
|
||||
case L('m','l'): // Malayalam
|
||||
case L('m','r'): // Marathi
|
||||
case L('t','e'): // Telugu
|
||||
{
|
||||
@@ -1464,7 +1473,7 @@ 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 = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY; // use 'diminished' for unstressed final syllable
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2; // use 'diminished' for unstressed final syllable
|
||||
tr->langopts.spelling_stress = 1;
|
||||
tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000
|
||||
|
||||
@@ -1483,9 +1492,12 @@ SetLengthMods(tr,3); // all equal
|
||||
else
|
||||
if(name2 == L('m','l'))
|
||||
{
|
||||
static const short stress_lengths_ml[8] = {180, 160, 240, 240, 0, 0, 260, 260};
|
||||
SetupTranslator(tr,stress_lengths_ml, stress_amps_equal);
|
||||
tr->letter_bits_offset = OFFSET_MALAYALAM;
|
||||
tr->langopts.numbers = NUM_OMIT_1_THOUSAND | NUM_OMIT_1_HUNDRED;
|
||||
tr->langopts.numbers2 = NUM2_OMIT_1_HUNDRED_ONLY;
|
||||
tr->langopts.stress_rule = 13; // 1st syllable, unless 1st vowel is short and 2nd is long
|
||||
}
|
||||
else
|
||||
if(name2 == L('k','n'))
|
||||
|
||||
+34
-17
@@ -461,6 +461,8 @@ int IsSpace(unsigned int c)
|
||||
return(0);
|
||||
if((c >= 0x2500) && (c < 0x25a0))
|
||||
return(1); // box drawing characters
|
||||
if((c >= 0xfff9) && (c <= 0xffff))
|
||||
return(1); // unicode specials
|
||||
// if(wcschr(chars_space,c))
|
||||
// return(1);
|
||||
return(iswspace(c));
|
||||
@@ -863,6 +865,7 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
int wflags;
|
||||
int wmark;
|
||||
int was_unpronouncable = 0;
|
||||
int loopcount;
|
||||
WORD_TAB wtab_null[8];
|
||||
|
||||
// translate these to get pronunciations of plural 's' suffix (different forms depending on
|
||||
@@ -1198,7 +1201,7 @@ if(end_type & SUFX_UNPRON)
|
||||
|
||||
found = 0;
|
||||
confirm_prefix = 1;
|
||||
for (int loopcount = 0; (loopcount < 50) && (end_type & SUFX_P); loopcount++)
|
||||
for (loopcount = 0; (loopcount < 50) && (end_type & SUFX_P); loopcount++)
|
||||
{
|
||||
// Found a standard prefix, remove it and retranslate
|
||||
// loopcount guards against an endless loop
|
||||
@@ -1730,7 +1733,7 @@ int SetTranslator2(const char *new_language)
|
||||
translator2 = SelectTranslator(new_language);
|
||||
strcpy(translator2_language,new_language);
|
||||
|
||||
if(LoadDictionary(translator2, new_language, 0) != 0)
|
||||
if(LoadDictionary(translator2, translator2->dictionary_name, 0) != 0)
|
||||
{
|
||||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
|
||||
new_phoneme_tab = -1;
|
||||
@@ -2052,7 +2055,6 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
pre_pause = 1;
|
||||
}
|
||||
|
||||
plist2 = &ph_list2[n_ph_list2];
|
||||
stress = 0;
|
||||
next_stress = 1;
|
||||
srcix = 0;
|
||||
@@ -2080,6 +2082,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
tr->prev_dict_flags[0] = 0;
|
||||
tr->prev_dict_flags[1] = 0;
|
||||
}
|
||||
plist2 = &ph_list2[n_ph_list2];
|
||||
|
||||
if((option_capitals==1) && (word_flags & FLAG_FIRST_UPPER))
|
||||
{
|
||||
@@ -2296,8 +2299,8 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
|
||||
|
||||
|
||||
static int EmbeddedCommand(unsigned int &source_index)
|
||||
{//===================================================
|
||||
static int EmbeddedCommand(unsigned int *source_index_out)
|
||||
{//=======================================================
|
||||
// An embedded command to change the pitch, volume, etc.
|
||||
// returns number of commands added to embedded_list
|
||||
|
||||
@@ -2308,6 +2311,7 @@ static int EmbeddedCommand(unsigned int &source_index)
|
||||
unsigned char c;
|
||||
char *p;
|
||||
int cmd;
|
||||
int source_index = *source_index_out;
|
||||
|
||||
c = source[source_index];
|
||||
if(c == '+')
|
||||
@@ -2355,6 +2359,7 @@ static int EmbeddedCommand(unsigned int &source_index)
|
||||
}
|
||||
|
||||
embedded_list[embedded_ix++] = cmd + sign + (value << 8);
|
||||
*source_index_out = source_index;
|
||||
return(1);
|
||||
} // end of EmbeddedCommand
|
||||
|
||||
@@ -2762,7 +2767,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
}
|
||||
else
|
||||
{
|
||||
embedded_count += EmbeddedCommand(source_index);
|
||||
embedded_count += EmbeddedCommand(&source_index);
|
||||
prev_in_save = prev_in;
|
||||
// replace the embedded command by spaces
|
||||
memset(&source[srcix],' ',source_index-srcix);
|
||||
@@ -2932,19 +2937,25 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
}
|
||||
|
||||
letter_count++;
|
||||
|
||||
if(tr->letter_bits_offset > 0)
|
||||
if(c != ' ')
|
||||
{
|
||||
if(((c < 0x250) && (prev_out >= tr->letter_bits_offset)) ||
|
||||
((c >= tr->letter_bits_offset) && (letter_count > 1) && (prev_out < 0x250)))
|
||||
letter_count++;
|
||||
|
||||
if(tr->letter_bits_offset > 0)
|
||||
{
|
||||
// Don't mix native and Latin characters in the same word
|
||||
// Break into separate words
|
||||
c = ' ';
|
||||
space_inserted = 1;
|
||||
word_flags |= FLAG_HYPHEN_AFTER;
|
||||
next_word_flags |= FLAG_HYPHEN;
|
||||
if(((c < 0x250) && (prev_out >= tr->letter_bits_offset)) ||
|
||||
((c >= tr->letter_bits_offset) && (letter_count > 1) && (prev_out < 0x250)))
|
||||
{
|
||||
// Don't mix native and Latin characters in the same word
|
||||
// Break into separate words
|
||||
if(IsAlpha(prev_out))
|
||||
{
|
||||
c = ' ';
|
||||
space_inserted = 1;
|
||||
word_flags |= FLAG_HYPHEN_AFTER;
|
||||
next_word_flags |= FLAG_HYPHEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2983,6 +2994,12 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
{
|
||||
int next2_in;
|
||||
utf8_in(&next2_in,&source[source_index + next_in_nbytes]);
|
||||
|
||||
if((tr->translator_name == L('n','l')) && (letter_count==2) && (c == 'j') && (prev_in == 'I'))
|
||||
{
|
||||
// Dutch words may capitalise initial IJ, don't split
|
||||
}
|
||||
else
|
||||
if(IsAlpha(next2_in))
|
||||
{
|
||||
// changing from upper to lower case, start new word at the last uppercase, if 3 or more letters
|
||||
|
||||
+11
-9
@@ -178,7 +178,7 @@ static MNEM_TAB keyword_tab[] = {
|
||||
|
||||
#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,7,0};
|
||||
const char variants_male[N_VOICE_VARIANTS] = {1,2,3,4,5,6,0};
|
||||
const char variants_female[N_VOICE_VARIANTS] = {11,12,13,14,0};
|
||||
const char *variant_lists[3] = {variants_either, variants_male, variants_female};
|
||||
|
||||
@@ -249,11 +249,11 @@ static void SetToneAdjust(voice_t *voice, int *tone_pts)
|
||||
height2 = tone_pts[pt+1];
|
||||
if((freq2 - freq1) > 0)
|
||||
{
|
||||
rate = double(height2-height1)/(freq2-freq1);
|
||||
rate = (double)(height2-height1)/(freq2-freq1);
|
||||
|
||||
for(ix=freq1; ix<freq2; ix++)
|
||||
{
|
||||
y = height1 + int(rate * (ix-freq1));
|
||||
y = height1 + (int)(rate * (ix-freq1));
|
||||
if(y > 255)
|
||||
y = 255;
|
||||
voice->tone_adjust[ix] = y;
|
||||
@@ -489,11 +489,11 @@ static void VoiceFormant(char *p)
|
||||
return;
|
||||
|
||||
if(freq >= 0)
|
||||
voice->freq[formant] = int(freq * 2.56001);
|
||||
voice->freq[formant] = (int)(freq * 2.56001);
|
||||
if(height >= 0)
|
||||
voice->height[formant] = int(height * 2.56001);
|
||||
voice->height[formant] = (int)(height * 2.56001);
|
||||
if(width >= 0)
|
||||
voice->width[formant] = int(width * 2.56001);
|
||||
voice->width[formant] = (int)(width * 2.56001);
|
||||
voice->freqadd[formant] = freqadd;
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
n = sscanf(p,"%d %d",&pitch1,&pitch2);
|
||||
voice->pitch_base = (pitch1 - 9) << 12;
|
||||
voice->pitch_range = (pitch2 - pitch1) * 108;
|
||||
factor = double(pitch1 - 82)/82;
|
||||
factor = (double)(pitch1 - 82)/82;
|
||||
voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch
|
||||
}
|
||||
break;
|
||||
@@ -1068,7 +1068,6 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
if((ix = SelectPhonemeTableName(phonemes_name)) < 0)
|
||||
{
|
||||
fprintf(stderr,"Unknown phoneme table: '%s'\n",phonemes_name);
|
||||
ix = 0;
|
||||
}
|
||||
voice->phoneme_tab_ix = ix;
|
||||
new_translator->phoneme_tab_ix = ix;
|
||||
@@ -1587,6 +1586,7 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found)
|
||||
vp = voices[ix];
|
||||
// is the main voice the required gender?
|
||||
skip=0;
|
||||
|
||||
if((gender != 0) && (vp->gender != gender))
|
||||
{
|
||||
skip=1;
|
||||
@@ -1595,6 +1595,7 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found)
|
||||
{
|
||||
skip=1;
|
||||
}
|
||||
|
||||
if(skip==0)
|
||||
{
|
||||
voices2[ix2++] = vp;
|
||||
@@ -1879,7 +1880,8 @@ espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector)
|
||||
|
||||
void FreeVoiceList()
|
||||
{//=================
|
||||
for(int ix=0; ix<n_voices_list; ix++)
|
||||
int ix;
|
||||
for(ix=0; ix<n_voices_list; ix++)
|
||||
{
|
||||
if(voices_list[ix] != NULL)
|
||||
{
|
||||
|
||||
+14
-14
@@ -1016,16 +1016,16 @@ static void AdvanceParameters()
|
||||
for(ix=0; ix <= wvoice->n_harmonic_peaks; ix++)
|
||||
{
|
||||
peaks[ix].freq1 += peaks[ix].freq_inc;
|
||||
peaks[ix].freq = int(peaks[ix].freq1);
|
||||
peaks[ix].freq = (int)peaks[ix].freq1;
|
||||
peaks[ix].height1 += peaks[ix].height_inc;
|
||||
if((peaks[ix].height = int(peaks[ix].height1)) < 0)
|
||||
if((peaks[ix].height = (int)peaks[ix].height1) < 0)
|
||||
peaks[ix].height = 0;
|
||||
peaks[ix].left1 += peaks[ix].left_inc;
|
||||
peaks[ix].left = int(peaks[ix].left1);
|
||||
peaks[ix].left = (int)peaks[ix].left1;
|
||||
if(ix < 3)
|
||||
{
|
||||
peaks[ix].right1 += peaks[ix].right_inc;
|
||||
peaks[ix].right = int(peaks[ix].right1);
|
||||
peaks[ix].right = (int)peaks[ix].right1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1038,10 +1038,10 @@ static void AdvanceParameters()
|
||||
if(ix < 7)
|
||||
{
|
||||
peaks[ix].freq1 += peaks[ix].freq_inc;
|
||||
peaks[ix].freq = int(peaks[ix].freq1);
|
||||
peaks[ix].freq = (int)peaks[ix].freq1;
|
||||
}
|
||||
peaks[ix].height1 += peaks[ix].height_inc;
|
||||
if((peaks[ix].height = int(peaks[ix].height1)) < 0)
|
||||
if((peaks[ix].height = (int)peaks[ix].height1) < 0)
|
||||
peaks[ix].height = 0;
|
||||
}
|
||||
|
||||
@@ -1157,7 +1157,7 @@ static int ApplyBreath(void)
|
||||
if((amp = wvoice->breath[ix]) != 0)
|
||||
{
|
||||
amp *= (peaks[ix].height >> 14);
|
||||
value += int(resonator(&rbreath[ix],noise) * amp);
|
||||
value += (int)resonator(&rbreath[ix],noise) * amp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1255,7 +1255,7 @@ int Wavegen()
|
||||
for(pk=wvoice->n_harmonic_peaks+1; pk<N_PEAKS; pk++)
|
||||
{
|
||||
// find the nearest harmonic for HF peaks where we don't use shape
|
||||
peak_harmonic[pk] = peaks[pk].freq / (wdata.pitch*16);
|
||||
peak_harmonic[pk] = ((peaks[pk].freq / (wdata.pitch*8)) + 1) / 2;
|
||||
}
|
||||
|
||||
// adjust amplitude to compensate for fewer harmonics at higher pitch
|
||||
@@ -1357,12 +1357,12 @@ int Wavegen()
|
||||
|
||||
for(h=1; h<=h_switch_sign; h++)
|
||||
{
|
||||
total += (int(sin_tab[theta >> 5]) * harmspect[h]);
|
||||
total += ((int)sin_tab[theta >> 5] * harmspect[h]);
|
||||
theta += waveph;
|
||||
}
|
||||
while(h<=maxh)
|
||||
{
|
||||
total -= (int(sin_tab[theta >> 5]) * harmspect[h]);
|
||||
total -= ((int)sin_tab[theta >> 5] * harmspect[h]);
|
||||
theta += waveph;
|
||||
h++;
|
||||
}
|
||||
@@ -1807,27 +1807,27 @@ if(option_log_frames)
|
||||
if(ix < 7)
|
||||
{
|
||||
peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
|
||||
peaks[ix].freq = int(peaks[ix].freq1);
|
||||
peaks[ix].freq = (int)peaks[ix].freq1;
|
||||
next = (fr2->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
|
||||
peaks[ix].freq_inc = ((next - peaks[ix].freq1) * (STEPSIZE/4)) / length4; // lower headroom for fixed point math
|
||||
}
|
||||
|
||||
peaks[ix].height1 = (fr1->fheight[ix] * v->height[ix]) << 6;
|
||||
peaks[ix].height = int(peaks[ix].height1);
|
||||
peaks[ix].height = (int)peaks[ix].height1;
|
||||
next = (fr2->fheight[ix] * v->height[ix]) << 6;
|
||||
peaks[ix].height_inc = ((next - peaks[ix].height1) * STEPSIZE) / length2;
|
||||
|
||||
if((ix <= 5) && (ix <= wvoice->n_harmonic_peaks))
|
||||
{
|
||||
peaks[ix].left1 = (fr1->fwidth[ix] * v->width[ix]) << 10;
|
||||
peaks[ix].left = int(peaks[ix].left1);
|
||||
peaks[ix].left = (int)peaks[ix].left1;
|
||||
next = (fr2->fwidth[ix] * v->width[ix]) << 10;
|
||||
peaks[ix].left_inc = ((next - peaks[ix].left1) * STEPSIZE) / length2;
|
||||
|
||||
if(ix < 3)
|
||||
{
|
||||
peaks[ix].right1 = (fr1->fright[ix] * v->width[ix]) << 10;
|
||||
peaks[ix].right = int(peaks[ix].right1);
|
||||
peaks[ix].right = (int)peaks[ix].right1;
|
||||
next = (fr2->fright[ix] * v->width[ix]) << 10;
|
||||
peaks[ix].right_inc = ((next - peaks[ix].right1) * STEPSIZE) / length2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user