Merge branch 'master' into android

Conflicts:
	README.md
This commit is contained in:
Reece H. Dunn
2013-09-25 08:57:56 +01:00
55 changed files with 3266 additions and 564 deletions
+11
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}