This commit is contained in:
Reece H. Dunn
2012-12-10 16:49:26 +00:00
parent 4eff8623d5
commit f9b7bbab1c
120 changed files with 4132 additions and 2583 deletions
+3 -2
View File
@@ -44,6 +44,7 @@
extern void FindPhonemesUsed(void);
extern void DisplayErrorFile(const char *fname);
extern int utf8_out(unsigned int c, char *buf);
extern void DrawEnvelopes();
char path_source[sizeof(path_home)+20];
@@ -3503,9 +3504,9 @@ fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references
CompileReport();
report_dict = CompileAllDictionaries();
#ifdef deleted
//#ifdef deleted
DrawEnvelopes();
#endif
//#endif
if(gui_flag)
{
+35 -1
View File
@@ -879,6 +879,18 @@ static int group3_ix;
int isHexDigit(int c)
{
if((c >= '0') && (c <= '9'))
return(c - '0');
if((c >= 'a') && (c <= 'f'))
return(c - 'a' + 10);
if((c >= 'A') && (c <= 'F'))
return(c - 'A' + 10);
return(-1);
}
static void copy_rule_string(char *string, int &state)
{//===================================================
// state 0: conditional, 1=pre, 2=match, 3=post, 4=phonemes
@@ -889,9 +901,11 @@ static void copy_rule_string(char *string, int &state)
int ix;
int len;
char c;
int c2, c3;
int sxflags;
int value;
int literal;
int hexdigit_input = 0;
MNEM_TAB *mr;
if(string[0] == 0) return;
@@ -911,18 +925,38 @@ static void copy_rule_string(char *string, int &state)
{
literal = 0;
c = *p++;
if((c == '0') && (p[0] == 'x') && (isHexDigit(p[1]) >= 0) && (isHexDigit(p[2]) >= 0))
{
hexdigit_input = 1;
c = p[1];
p+= 2;
}
if(c == '\\')
{
c = *p++; // treat next character literally
//#ifdef deleted
if((c >= '0') && (c <= '3') && (p[0] >= '0') && (p[0] <= '7') && (p[1] >= '0') && (p[1] <= '7'))
{
// character code given by 3 digit octal value;
c = (c-'0')*64 + (p[0]-'0')*8 + (p[1]-'0');
p += 2;
}
//endif
literal = 1;
}
if(hexdigit_input)
{
if(((c2 = isHexDigit(c)) >= 0) && ((c3 = isHexDigit(p[0])) >= 0))
{
c = c2 * 16 + c3;
literal = 1;
p++;
}
else
{
hexdigit_input = 0;
}
}
if((state==1) || (state==3))
{
// replace special characters (note: 'E' is reserved for a replaced silent 'e')
+28 -28
View File
@@ -524,27 +524,33 @@ unsigned short ipa1[96] = {
};
static void WritePhMnemonic(char **buf, PHONEME_TAB *ph, PHONEME_LIST *plist)
{//=======================================================================================
char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa)
{//=====================================================================================
int c;
int mnem;
int len;
int first;
int ix = 0;
char *phon_out;
char *p;
unsigned int ipa_control=0; // first byte of ipa string may control the phoneme name interpretation. 0x20 = ignore this phoneme
PHONEME_DATA phdata;
phon_out = *buf;
if(ph->code == phonEND_WORD)
{
// ignore
phon_out[0] = 0;
return;
return(phon_out);
}
if(option_phonemes == 3)
if(ph->code == phonSWITCH)
{
// the tone_ph field contains a phoneme table number
p = phoneme_tab_list[plist->tone_ph].name;
sprintf(phon_out, "(%s)", p);
return(phon_out + strlen(phon_out));
}
if(use_ipa)
{
// has an ipa name been defined for this phoneme ?
phdata.ipa_string[0] = 0;
@@ -568,8 +574,9 @@ static void WritePhMnemonic(char **buf, PHONEME_TAB *ph, PHONEME_LIST *plist)
}
if(ipa_control >= 0x20)
{
*buf += ix;
return; // 0x20 = ignore phoneme
phon_out = &phon_out[ix];
*phon_out = 0;
return(phon_out); // 0x20 = ignore phoneme
}
}
}
@@ -580,7 +587,7 @@ static void WritePhMnemonic(char **buf, PHONEME_TAB *ph, PHONEME_LIST *plist)
if((c == '/') && (option_phoneme_variants==0))
break; // discard phoneme variant indicator
if(option_phonemes == 3)
if(use_ipa)
{
// convert from ascii to ipa
if(first && (c == '_'))
@@ -605,13 +612,15 @@ static void WritePhMnemonic(char **buf, PHONEME_TAB *ph, PHONEME_LIST *plist)
first = 0;
}
*buf += ix;
phon_out = &phon_out[ix];
*phon_out = 0;
return(phon_out);
} // end of WritePhMnemonic
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
{//============================================================
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa)
{//=========================================================================
/* Can be called after a clause has been translated into phonemes, in order
to display the clause in phoneme mnemonic form.
*/
@@ -622,7 +631,6 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
int phon_out_ix=0;
int stress;
unsigned int c;
char *p;
char *buf;
char phon_buf[30];
PHONEME_LIST *plist;
@@ -646,7 +654,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
c = 0;
if(stress > 5) stress = 5;
if(option_phonemes == 3)
if(use_ipa)
{
c = 0x2cc; // ipa, secondary stress
if(stress > 3)
@@ -664,30 +672,22 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
}
}
if(plist->ph->code == phonSWITCH)
{
// the tone_ph field contains a phoneme table number
p = phoneme_tab_list[plist->tone_ph].name;
buf = WritePhMnemonic(buf, plist->ph, plist, use_ipa);
sprintf(buf, "(%s)", p);
buf += (strlen(p) + 2);
}
else
if(plist->ph->code != phonSWITCH)
{
WritePhMnemonic(&buf, plist->ph, plist);
if(plist->synthflags & SFLAG_LENGTHEN)
{
WritePhMnemonic(&buf, phoneme_tab[phonLENGTHEN], NULL);
buf = WritePhMnemonic(buf, phoneme_tab[phonLENGTHEN], NULL, use_ipa);
}
if((plist->synthflags & SFLAG_SYLLABLE) && (plist->type != phVOWEL))
{
// syllablic consonant
WritePhMnemonic(&buf, phoneme_tab[phonSYLLABIC], NULL);
buf = WritePhMnemonic(buf, phoneme_tab[phonSYLLABIC], NULL, use_ipa);
}
if(plist->tone_ph > 0)
{
WritePhMnemonic(&buf, phoneme_tab[plist->tone_ph], NULL);
buf = WritePhMnemonic(buf, phoneme_tab[plist->tone_ph], NULL, use_ipa);
}
}
+20 -9
View File
@@ -313,6 +313,17 @@ static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
}
static void PrintVersion()
{//=======================
const char *version;
const char *path_data;
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 0, NULL, espeakINITIALIZE_DONT_EXIT);
version = espeak_Info(&path_data);
printf("eSpeak text-to-speech: %s Data at: %s\n", version, path_data);
}
#ifdef NEED_GETOPT
struct option {
char *name;
@@ -352,6 +363,7 @@ int main (int argc, char **argv)
{"phonout", required_argument, 0, 0x108},
{"pho", no_argument, 0, 0x109},
{"ipa", no_argument, 0, 0x10a},
{"version", no_argument, 0, 0x10b},
{0, 0, 0, 0}
};
@@ -473,15 +485,10 @@ int main (int argc, char **argv)
break;
case 'h':
{
const char *version;
const char *path_data;
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 0, data_path, espeakINITIALIZE_DONT_EXIT);
version = espeak_Info(&path_data);
printf("\n");
printf("eSpeak text-to-speech: %s Data at: %s\n%s", version, path_data, help_text);
exit(0);
}
printf("\n");
PrintVersion();
printf("%s", help_text);
exit(0);
break;
case 'k':
@@ -599,6 +606,10 @@ int main (int argc, char **argv)
option_phonemes = 3;
break;
case 0x10b: // -version
PrintVersion();
exit(0);
default:
exit(0);
}
+8 -2
View File
@@ -134,7 +134,13 @@ int TestSynthCallback(short *wav, int numsamples, espeak_EVENT *events)
fprintf(f_events,"'%s'\n",events->id.name);
else
if(type==espeakEVENT_PHONEME)
fprintf(f_events,"[%s]\n",WordToString(events->id.number));
{
char buf[10];
fprintf(f_events,"[%s]\n",WordToString(events->id.number)); //old version, only 4 characters bytes
// memcpy(buf, events->id.string, 8);
// buf[8] = 0;
// fprintf(f_events,"[%s]\n", buf);
}
else
fprintf(f_events,"%d\n",events->id.number);
@@ -2309,7 +2315,7 @@ if(control==2)
fprintf(f_events,"Type Audio Text Length Id\n");
fclose(f_events);
espeak_Initialize(AUDIO_OUTPUT_RETRIEVAL,1000,NULL,1);
espeak_Initialize(AUDIO_OUTPUT_RETRIEVAL, 1000, NULL, espeakINITIALIZE_PHONEME_EVENTS);
espeak_SetSynthCallback(TestSynthCallback);
espeak_SetUriCallback(TestUriCallback);
+19 -9
View File
@@ -60,7 +60,7 @@ static void* say_thread(void*);
static espeak_ERROR push(t_espeak_command* the_command);
static t_espeak_command* pop();
static void init();
static void init(int process_parameters);
static int node_counter=0;
enum {MAX_NODE_COUNTER=400,
INACTIVITY_TIMEOUT=50, // in ms, check that the stream is inactive
@@ -75,7 +75,7 @@ void fifo_init()
// security
pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
init();
init(0);
assert(-1 != sem_init(&my_sem_start_is_required, 0, 0));
assert(-1 != sem_init(&my_sem_stop_is_acknowledged, 0, 0));
@@ -457,7 +457,7 @@ static void* say_thread(void*)
{
// no mutex required since the stop command is synchronous
// and waiting for my_sem_stop_is_acknowledged
init();
init(1);
// purge start semaphore
SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
@@ -569,14 +569,24 @@ static t_espeak_command* pop()
}
static void init()
static void init(int process_parameters)
{
ENTER("fifo > init");
while (delete_espeak_command( pop() ))
{}
node_counter = 0;
// Changed by Tyler Spivey 30.Nov.2011
t_espeak_command *c = NULL;
ENTER("fifo > init");
c = pop();
while (c != NULL) {
if (process_parameters && (c->type == ET_PARAMETER || c->type == ET_VOICE_NAME || c->type == ET_VOICE_SPEC))
{
process_espeak_command(c);
}
delete_espeak_command(c);
c = pop();
}
node_counter = 0;
}
//>
//<fifo_init
void fifo_terminate()
@@ -589,7 +599,7 @@ void fifo_terminate()
sem_destroy(&my_sem_start_is_required);
sem_destroy(&my_sem_stop_is_acknowledged);
init(); // purge fifo
init(0); // purge fifo
}
#endif
+6 -2
View File
@@ -1862,15 +1862,19 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
case NUM_DFRACTION_1: // italian, say "hundredths" if leading zero
case NUM_DFRACTION_5: // hungarian, always say "tenths" etc.
case NUM_DFRACTION_6: // kazakh, always say "tenths" etc, before the decimal fraction
LookupNum3(tr, atoi(&word[n_digits]), ph_buf, 0,0,0);
if((word[n_digits]=='0') || (decimal_mode == NUM_DFRACTION_5))
if((word[n_digits]=='0') || (decimal_mode != NUM_DFRACTION_1))
{
// decimal part has leading zeros, so add a "hundredths" or "thousandths" suffix
sprintf(string,"_0Z%d",decimal_count);
if(Lookup(tr, string, buf1) == 0)
break; // revert to speaking single digits
strcat(ph_buf,buf1);
if(decimal_mode == NUM_DFRACTION_6)
strcat(ph_out, buf1);
else
strcat(ph_buf, buf1);
}
strcat(ph_out,ph_buf);
n_digits += decimal_count;
+1
View File
@@ -191,6 +191,7 @@ static int n_param_stack;
PARAM_STACK param_stack[N_PARAM_STACK];
static int speech_parameters[N_SPEECH_PARAM]; // current values, from param_stack
int saved_parameters[N_SPEECH_PARAM]; //Parameters saved on synthesis start
const int param_defaults[N_SPEECH_PARAM] = {
0, // silence (internal use)
+7 -4
View File
@@ -32,6 +32,7 @@
extern int GetAmplitude(void);
extern void DoSonicSpeed(int value);
extern int saved_parameters[];
// convert from words-per-minute to internal speed factor
@@ -343,6 +344,7 @@ void SetParameter(int parameter, int value, int relative)
}
}
param_stack[0].parameter[parameter] = new_value;
saved_parameters[parameter] = new_value;
switch(parameter)
{
@@ -715,14 +717,14 @@ if(stress <= 1)
if(stress >= 7)
{
// tonic syllable, include a constant component so it doesn't decrease directly with speed
length_mod += 20;
length_mod += tr->langopts.lengthen_tonic;
if(emphasized)
length_mod += 10;
length_mod += (tr->langopts.lengthen_tonic/2);
}
else
if(emphasized)
{
length_mod += 20;
length_mod += tr->langopts.lengthen_tonic;
}
if((len = tr->stress_lengths[stress]) == 0)
@@ -739,7 +741,8 @@ if(stress <= 1)
}
}
if(end_of_clause == 2)
if((end_of_clause == 2) && !(tr->langopts.stress_flags & S_NO_EOC_LENGTHEN))
{
// this is the last syllable in the clause, lengthen it - more for short vowels
len = (p->ph->std_length * 2);
+9 -2
View File
@@ -282,7 +282,7 @@ static void CloseWaveFile()
void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr)
void MarkerEvent(int type, unsigned int char_position, int value, int value2, unsigned char *out_ptr)
{//======================================================================================
// Do nothing in the command-line version.
if(type == 2)
@@ -444,6 +444,8 @@ static void StopSpeak(int unused)
signal(SIGINT,StopSpeak);
} // end of StopSpeak()
#ifdef NEED_GETOPT
struct option {
char *name;
@@ -483,6 +485,7 @@ int main (int argc, char **argv)
{"phonout", required_argument, 0, 0x108},
{"pho", no_argument, 0, 0x109},
{"ipa", no_argument, 0, 0x10a},
{"version", no_argument, 0, 0x10b},
{0, 0, 0, 0}
};
@@ -601,7 +604,6 @@ int main (int argc, char **argv)
init_path(argv[0],data_path);
printf("\nspeak text-to-speech: %s Data at: %s\n%s",version_string,path_home,help_text);
exit(0);
break;
case 'k':
option_capitals = atoi(optarg2);
@@ -722,6 +724,11 @@ int main (int argc, char **argv)
option_phonemes = 3;
break;
case 0x10b: // --version
init_path(argv[0],data_path);
printf("speak text-to-speech: %s Data at: %s\n",version_string,path_home);
exit(0);
default:
exit(0);
}
+26 -5
View File
@@ -66,6 +66,7 @@ int (* uri_callback)(int, const char *, const char *) = NULL;
int (* phoneme_callback)(const char *) = NULL;
char path_home[N_PATH_HOME]; // this is the espeak-data directory
extern int saved_parameters[N_SPEECH_PARAM]; //Parameters saved on synthesis start
void WVoiceChanged(voice_t *wvoice)
@@ -543,9 +544,9 @@ static const char* label[] = {
#endif
void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr)
{//======================================================================================
// type: 1=word, 2=sentence, 3=named mark, 4=play audio, 5=end
void MarkerEvent(int type, unsigned int char_position, int value, int value2, unsigned char *out_ptr)
{//==================================================================================================
// type: 1=word, 2=sentence, 3=named mark, 4=play audio, 5=end, 7=phoneme
ENTER("MarkerEvent");
espeak_EVENT *ep;
double time;
@@ -574,7 +575,20 @@ void MarkerEvent(int type, unsigned int char_position, int value, unsigned char
if((type == espeakEVENT_MARK) || (type == espeakEVENT_PLAY))
ep->id.name = &namedata[value];
else
#ifdef deleted
// temporarily removed, don't introduce until after eSpeak version 1.46.02
if(type == espeakEVENT_PHONEME)
{
int *p;
p = (int *)(ep->id.string);
p[0] = value;
p[1] = value2;
}
else
#endif
{
ep->id.number = value;
}
} // end of MarkerEvent
@@ -596,6 +610,9 @@ espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text,
my_unique_identifier = unique_identifier;
my_user_data = user_data;
for (int i=0; i < N_SPEECH_PARAM; i++)
saved_parameters[i] = param_stack[0].parameter[i];
switch(position_type)
{
case POS_CHARACTER:
@@ -769,13 +786,13 @@ ENTER("espeak_Initialize");
option_phonemes = 0;
option_mbrola_phonemes = 0;
option_phoneme_events = (options & 1);
option_phoneme_events = (options & (espeakINITIALIZE_PHONEME_EVENTS | espeakINITIALIZE_PHONEME_IPA));
VoiceReset(0);
// SetVoiceByName("default");
for(param=0; param<N_SPEECH_PARAM; param++)
param_stack[0].parameter[param] = param_defaults[param];
param_stack[0].parameter[param] = saved_parameters[param] = param_defaults[param];
SetParameter(espeakRATE,175,0);
SetParameter(espeakVOLUME,100,0);
@@ -1157,6 +1174,10 @@ ESPEAK_API espeak_ERROR espeak_Cancel(void)
SHOW_TIME("espeak_Cancel > LEAVE");
#endif
embedded_value[EMBED_T] = 0; // reset echo for pronunciation announcements
for (int i=0; i < N_SPEECH_PARAM; i++)
SetParameter(i, saved_parameters[i], 0);
return EE_OK;
} // end of espeak_Cancel
+5 -1
View File
@@ -488,7 +488,11 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
len = (80 * speed.wav_factor)/256;
if(ph->code != phonEND_WORD)
DoMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, ph->mnemonic);
{
char phoneme_name[16];
WritePhMnemonic(phoneme_name, p->ph, p, option_phoneme_events & espeakINITIALIZE_PHONEME_IPA);
DoPhonemeMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, phoneme_name);
}
ptr += sprintf(ptr,"%s\t",WordToString(name));
+2 -2
View File
@@ -35,7 +35,7 @@
#include "translate.h"
#include "wave.h"
const char *version_string = "1.46.01 22.Nov.11";
const char *version_string = "1.46.02 06.Jan.12";
const int version_phdata = 0x014600;
int option_device_number = -1;
@@ -675,7 +675,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
if(control & 0x100)
{
// change phonemes pass
// "change phonemes" pass
plist->ph = phoneme_tab[plist->phcode];
}
ph = plist->ph;
+35 -7
View File
@@ -1211,10 +1211,27 @@ void DoMarker(int type, int char_posn, int length, int value)
// Type 1=word, 2=sentence, 3=named marker, 4=play audio, 5=end
if(WcmdqFree() > 5)
{
wcmdq[wcmdq_tail][0] = WCMD_MARKER;
wcmdq[wcmdq_tail][1] = type;
wcmdq[wcmdq_tail][2] = (char_posn & 0xffffff) | (length << 24);
wcmdq[wcmdq_tail][3] = value;
wcmdq[wcmdq_tail][0] = WCMD_MARKER + (type << 8);
wcmdq[wcmdq_tail][1] = (char_posn & 0xffffff) | (length << 24);
wcmdq[wcmdq_tail][2] = value;
WcmdqInc();
}
} // end of DoMarker
void DoPhonemeMarker(int type, int char_posn, int length, char *name)
{//==================================================================
// This could be used to return an index to the word currently being spoken
// Type 7=phoneme
int *p;
if(WcmdqFree() > 5)
{
wcmdq[wcmdq_tail][0] = WCMD_MARKER + (type << 8);
wcmdq[wcmdq_tail][1] = (char_posn & 0xffffff) | (length << 24);
p = (int *)name;
wcmdq[wcmdq_tail][2] = p[0]; // up to 8 bytes of UTF8 characters
wcmdq[wcmdq_tail][3] = p[1];
WcmdqInc();
}
} // end of DoMarker
@@ -1319,6 +1336,8 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
unsigned char *pitch_env=NULL;
unsigned char *amp_env;
PHONEME_TAB *ph;
int use_ipa=0;
char phoneme_name[16];
static int sourceix=0;
PHONEME_DATA phdata;
@@ -1330,6 +1349,9 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
if(option_quiet)
return(0);
if(option_phoneme_events & espeakINITIALIZE_PHONEME_IPA)
use_ipa = 1;
if(mbrola_name[0] != 0)
return(MbrolaGenerate(phoneme_list,n_ph,resume));
@@ -1405,7 +1427,8 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
if(option_phoneme_events && (p->type != phVOWEL) && (p->ph->code != phonEND_WORD))
{
// Note, for vowels, do the phoneme event after the vowel-start
DoMarker(espeakEVENT_PHONEME, sourceix, 0, p->ph->mnemonic);
WritePhMnemonic(phoneme_name, p->ph, p, use_ipa);
DoPhonemeMarker(espeakEVENT_PHONEME, sourceix, 0, phoneme_name);
}
switch(p->type)
@@ -1712,7 +1735,8 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
if(option_phoneme_events)
{
DoMarker(espeakEVENT_PHONEME, sourceix, 0, p->ph->mnemonic);
WritePhMnemonic(phoneme_name, p->ph, p, use_ipa);
DoPhonemeMarker(espeakEVENT_PHONEME, sourceix, 0, phoneme_name);
}
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
@@ -1896,7 +1920,11 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control)
if((option_phonemes > 0) || (phoneme_callback != NULL))
{
GetTranslatedPhonemeString(translator->phon_out,sizeof(translator->phon_out));
int use_ipa = 0;
if(option_phonemes == 3)
use_ipa = 1;
GetTranslatedPhonemeString(translator->phon_out, sizeof(translator->phon_out), use_ipa);
if(option_phonemes > 0)
{
fprintf(f_trans,"%s\n",translator->phon_out);
+4 -2
View File
@@ -17,6 +17,8 @@
* <http://www.gnu.org/licenses/>. *
***************************************************************************/
#define espeakINITIALIZE_PHONEME_IPA 0x0002 // move this to speak_lib.h, after eSpeak version 1.46.02
#define N_PHONEME_LIST 1000 // enough for source[N_TR_SOURCE] full of text, else it will truncate
@@ -475,7 +477,7 @@ int WavegenInitSound();
void WavegenInit(int rate, int wavemult_fact);
float polint(float xa[],float ya[],int n,float x);
int WavegenFill(int fill_zeros);
void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr);
void MarkerEvent(int type, unsigned int char_position, int value, int value2, unsigned char *out_ptr);
extern unsigned char *wavefile_data;
@@ -559,7 +561,7 @@ int MbrolaFill(int length, int resume, int amplitude);
void MbrolaReset(void);
void DoEmbedded(int *embix, int sourceix);
void DoMarker(int type, int char_posn, int length, int value);
//int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int amp);
void DoPhonemeMarker(int type, int char_posn, int length, char *name);
int DoSample3(PHONEME_DATA *phdata, int length_mod, int amp);
int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_LIST *plist, int modulation);
int PauseLength(int pause, int control);
+33 -6
View File
@@ -141,7 +141,7 @@ static Translator* NewTranslator(void)
memset(tr->letter_bits,0,sizeof(tr->letter_bits));
memset(tr->letter_groups,0,sizeof(tr->letter_groups));
// 0-5 sets of characters matched by A B C H F G Y in pronunciation rules
// 0-6 sets of characters matched by A B C H F G Y in pronunciation rules
// these may be set differently for different languages
SetLetterBits(tr,0,"aeiou"); // A vowels, except y
SetLetterBits(tr,1,"bcdfgjklmnpqstvxz"); // B hard consonants, excluding h,r,w
@@ -164,6 +164,7 @@ static Translator* NewTranslator(void)
}
memset(&(tr->langopts),0,sizeof(tr->langopts));
tr->langopts.max_lengthmod = 500;
tr->langopts.lengthen_tonic = 20;
tr->langopts.stress_rule = STRESSPOSN_2R;
tr->langopts.unstressed_wd1 = 1;
@@ -274,11 +275,13 @@ static const unsigned int replace_cyrillic_latin[] =
0x45c,0x107,
0}; // ѓ ѕ ќ
static const unsigned char ru_vowels[] = {0x10,0x15,0x31,0x18,0x1e,0x23,0x2b,0x2d,0x2e,0x2f, 0xb9,0xc9,0x91,0x8f,0x36,0}; //also kazakh
static const unsigned char ru_consonants[] = {0x11,0x12,0x13,0x14,0x16,0x17,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2c, 0x73,0x7b,0x83,0x9b,0};
static void SetCyrillicLetters(Translator *tr)
{//===========================================
// character codes offset by 0x420
static const char ru_vowels[] = {0x10,0x15,0x31,0x18,0x1e,0x23,0x2b,0x2d,0x2e,0x2f,0};
static const char ru_consonants[] = {0x11,0x12,0x13,0x14,0x16,0x17,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2c,0};
static const char ru_soft[] = {0x2c,0x19,0x27,0x29,0}; // letter group B [k ts; s;]
static const char ru_hard[] = {0x2a,0x16,0x26,0x28,0}; // letter group H [S Z ts]
static const char ru_nothard[] = {0x11,0x12,0x13,0x14,0x17,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x24,0x25,0x27,0x29,0x2c,0};
@@ -291,14 +294,14 @@ static void SetCyrillicLetters(Translator *tr)
tr->letter_bits_offset = OFFSET_CYRILLIC;
memset(tr->letter_bits,0,sizeof(tr->letter_bits));
SetLetterBits(tr,LETTERGP_A,ru_vowels);
SetLetterBits(tr,LETTERGP_A,(char *)ru_vowels);
SetLetterBits(tr,1,ru_soft);
SetLetterBits(tr,2,ru_consonants);
SetLetterBits(tr,2,(char *)ru_consonants);
SetLetterBits(tr,3,ru_hard);
SetLetterBits(tr,4,ru_nothard);
SetLetterBits(tr,5,ru_voiced);
SetLetterBits(tr,6,ru_ivowels);
SetLetterBits(tr,LETTERGP_VOWEL2,ru_vowels);
SetLetterBits(tr,LETTERGP_VOWEL2,(char *)ru_vowels);
} // end of SetCyrillicLetters
@@ -893,6 +896,30 @@ SetLengthMods(tr,3); // all equal
}
break;
case L('k','k'): // Kazakh
{
static const unsigned char stress_amps_tr[8] = {18,16, 20,21, 20,21, 21,20 };
static const short stress_lengths_tr[8] = {190,180, 230,230, 0,0, 250,250};
tr->letter_bits_offset = OFFSET_CYRILLIC;
memset(tr->letter_bits,0,sizeof(tr->letter_bits));
SetLetterBits(tr,LETTERGP_A,(char *)ru_vowels);
SetLetterBits(tr,LETTERGP_C,(char *)ru_consonants);
SetLetterBits(tr,LETTERGP_VOWEL2,(char *)ru_vowels);
SetupTranslator(tr,stress_lengths_tr,stress_amps_tr);
tr->langopts.stress_rule = 7; // stress on the last syllable, before any explicitly unstressed syllable
tr->langopts.stress_flags = S_NO_AUTO_2 + S_NO_EOC_LENGTHEN; //no automatic secondary stress, don't lengthen at end-of-clause
tr->langopts.lengthen_tonic = 0;
tr->langopts.param[LOPT_SUFFIX] = 1;
tr->langopts.numbers = NUM_OMIT_1_HUNDRED | NUM_DFRACTION_6 ;
tr->langopts.max_initial_consonants = 2;
SetLengthMods(tr,3); // all equal
}
break;
case L('k','o'): // Korean, TEST
{
static const char ko_ivowels[] = {0x63,0x64,0x67,0x68,0x6d,0x72,0x74,0x75,0}; // y and i vowels
+10 -10
View File
@@ -334,16 +334,16 @@ static unsigned char length_mods_en0[100] = {
static unsigned char length_mods_equal[100] = {
/* a , t s n d z r N <- next */
110,110,110,110,110,110,110,110,110, 110, /* a <- next2 */
110,110,110,110,110,110,110,110,110, 110, /* , */
110,110,110,110,110,110,110,110,110, 110, /* t */
110,110,110,110,110,110,110,110,110, 110, /* s */
110,110,110,110,110,110,110,110,110, 110, /* n */
110,110,110,110,110,110,110,110,110, 110, /* d */
110,110,110,110,110,110,110,110,110, 110, /* z */
110,110,110,110,110,110,110,110,110, 110, /* r */
110,110,110,110,110,110,110,110,110, 110, /* N */
110,110,110,110,110,110,110,110,110, 110 }; // SPARE
110,120,100,110,110,110,110,110,110, 110, /* a <- next2 */
110,120,100,110,110,110,110,110,110, 110, /* , */
110,120,100,110,100,110,110,110,100, 110, /* t */
110,120,100,110,110,110,110,110,110, 110, /* s */
110,120,100,110,110,110,110,110,110, 110, /* n */
110,120,100,110,110,110,110,110,110, 110, /* d */
110,120,100,110,110,110,110,110,110, 110, /* z */
110,120,100,110,110,110,110,110,110, 110, /* r */
110,120,100,110,110,110,110,110,110, 110, /* N */
110,120,100,110,110,110,110,110,110, 110 }; // SPARE
static unsigned char *length_mod_tabs[6] = {
+7 -2
View File
@@ -355,6 +355,7 @@ typedef struct {
#define S_INITIAL_2 0x2000
#define S_NO_AUTO_DIM 0x10000
#define S_HYPEN_UNSTRESS 0x100000
#define S_NO_EOC_LENGTHEN 0x200000
// bit0=don't stress monosyllables, except at end of clause
// bit1=don't set diminished stress,
// bit2=mark unstressed final syllables as diminished
@@ -373,6 +374,7 @@ typedef struct {
// bit18= don't lengthen short vowels more than long vowels at end-of-clause
// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
// bit20= hyphenated words, 2nd part is unstressed
// bit21= don't lengthen vowels at end-of-clause
int stress_flags;
int unstressed_wd1; // stress for $u word of 1 syllable
@@ -398,6 +400,7 @@ typedef struct {
#define NUM_DFRACTION_3 0x6000
#define NUM_DFRACTION_4 0x8000
#define NUM_DFRACTION_5 0xa000
#define NUM_DFRACTION_6 0xc000
#define NUM_ORDINAL_DOT 0x10000
#define NUM_NOPAUSE 0x20000
#define NUM_AND_HUNDRED 0x40000
@@ -476,7 +479,8 @@ typedef struct {
const unsigned int *replace_chars; // characters to be substitutes
const char *ascii_language; // switch to this language for Latin characters
int max_lengthmod;
int suffix_add_e; // replace a suffix (which has the SUFX_E flag) with this character
int lengthen_tonic; // lengthen the tonic syllable
int suffix_add_e; // replace a suffix (which has the SUFX_E flag) with this character
} LANGUAGE_OPTIONS;
@@ -635,7 +639,7 @@ int IsDigit(unsigned int c);
int IsAlpha(unsigned int c);
int isspace2(unsigned int c);
int towlower2(unsigned int c);
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out);
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa);
Translator *SelectTranslator(const char *name);
int SetTranslator2(const char *name);
@@ -675,6 +679,7 @@ int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix
void SetVoiceStack(espeak_VOICE *v, const char *variant_name);
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata);
void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata);
char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa);
extern FILE *f_trans; // for logging
extern FILE *f_logespeak;
+4 -2
View File
@@ -408,6 +408,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
char phon_out[N_PH_LIST*2];
int clause_tone;
int clause_count;
int use_ipa = 0;
FILE *f;
int fd_temp;
char fname_temp[100];
@@ -459,6 +460,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
t_phonetic->SetDefaultStyle(style_phonetic_large);
translate_text = 3;
use_ipa = 1;
break;
case T_PROCESS:
@@ -468,7 +470,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
myframe->OnProsody(event);
}
prosodycanvas->LayoutData(ph_list,n_ph_list);
option_phoneme_events = 1;
option_phoneme_events = espeakINITIALIZE_PHONEME_EVENTS;
option_log_frames = 1;
MakeWave2(ph_list,n_ph_list);
option_log_frames = 0;
@@ -495,7 +497,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
CalcPitches(translator,clause_tone);
CalcLengths(translator);
GetTranslatedPhonemeString(translator->phon_out,sizeof(translator->phon_out));
GetTranslatedPhonemeString(translator->phon_out, sizeof(translator->phon_out), use_ipa);
if(clause_count++ > 0)
strcat(phon_out," ||");
strcat(phon_out,translator->phon_out);
+23 -10
View File
@@ -745,19 +745,32 @@ size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSiz
int wave_close(void* theHandler)
{
SHOW_TIME("wave_close > ENTER");
static int aStopStreamCount = 0;
int a_status = pthread_mutex_lock(&pulse_mutex);
if (a_status) {
SHOW("Error: pulse_mutex lock=%d (%s)\n", a_status, __FUNCTION__);
return PULSE_ERROR;
}
drain();
// Avoid race condition by making sure this function only
// gets called once at a time
aStopStreamCount++;
if (aStopStreamCount != 1)
{
SHOW_TIME("wave_close > LEAVE (stopStreamCount)");
return 0;
}
pthread_mutex_unlock(&pulse_mutex);
SHOW_TIME("wave_close (ret)");
int a_status = pthread_mutex_lock(&pulse_mutex);
if (a_status)
{
SHOW("Error: pulse_mutex lock=%d (%s)\n", a_status, __FUNCTION__);
aStopStreamCount = 0; // last action
return PULSE_ERROR;
}
return PULSE_OK;
drain();
pthread_mutex_unlock(&pulse_mutex);
SHOW_TIME("wave_close (ret)");
aStopStreamCount = 0; // last action
return PULSE_OK;
}
//>
+20 -9
View File
@@ -261,8 +261,11 @@ unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
#ifdef LOG_FRAMES
static void LogMarker(int type, int value)
{//=======================================
static void LogMarker(int type, int value, int value2)
{//===================================================
char buf[20];
int *p;
if(option_log_frames == 0)
return;
@@ -272,7 +275,13 @@ static void LogMarker(int type, int value)
if(f_log)
{
if(type == espeakEVENT_PHONEME)
fprintf(f_log,"Phoneme [%s]\n",WordToString(value));
{
p = (int *)buf;
p[0] = value;
p[1] = value2;
buf[8] = 0;
fprintf(f_log,"Phoneme [%s]\n", buf);
}
else
fprintf(f_log,"\n");
fclose(f_log);
@@ -1630,7 +1639,7 @@ void WavegenSetVoice(voice_t *v)
}
WavegenSetEcho();
SetPitchFormants();
MarkerEvent(espeakEVENT_SAMPLERATE,0,wvoice->samplerate,out_ptr);
MarkerEvent(espeakEVENT_SAMPLERATE, 0, wvoice->samplerate, 0, out_ptr);
// WVoiceChanged(wvoice);
}
@@ -1862,6 +1871,7 @@ int WavegenFill2(int fill_zeros)
long *q;
int length;
int result;
int marker_type;
static int resume=0;
static int echo_complete=0;
@@ -1889,7 +1899,7 @@ int WavegenFill2(int fill_zeros)
q = wcmdq[wcmdq_head];
length = q[1];
switch(q[0])
switch(q[0] & 0xff)
{
case WCMD_PITCH:
SetPitch(length,(unsigned char *)q[2],q[3] >> 16,q[3] & 0xffff);
@@ -1946,13 +1956,14 @@ int WavegenFill2(int fill_zeros)
#endif
case WCMD_MARKER:
MarkerEvent(q[1],q[2],q[3],out_ptr);
marker_type = q[0] >> 8;
MarkerEvent(marker_type, q[1],q[2],q[3],out_ptr);
#ifdef LOG_FRAMES
LogMarker(q[1],q[3]);
LogMarker(marker_type, q[2], q[3]);
#endif
if(q[1] == 1)
if(marker_type == 1) // word marker
{
current_source_index = q[2] & 0xffffff;
current_source_index = q[1] & 0xffffff;
}
break;