Browse Source

Use the default uncrustify config (with indentation changes) to reformat the code.

master
Reece H. Dunn 9 years ago
parent
commit
36be9ac13f
40 changed files with 5696 additions and 5583 deletions
  1. 101
    100
      src/espeak-ng.c
  2. 243
    236
      src/libespeak-ng/compiledata.c
  3. 38
    39
      src/libespeak-ng/compiledict.c
  4. 1
    1
      src/libespeak-ng/compilembrola.c
  5. 31
    31
      src/libespeak-ng/debug.c
  6. 150
    151
      src/libespeak-ng/dictionary.c
  7. 524
    524
      src/libespeak-ng/espeak_command.c
  8. 65
    65
      src/libespeak-ng/espeak_command.h
  9. 73
    74
      src/libespeak-ng/event.c
  10. 14
    14
      src/libespeak-ng/event.h
  11. 329
    330
      src/libespeak-ng/fifo.c
  12. 10
    10
      src/libespeak-ng/fifo.h
  13. 214
    202
      src/libespeak-ng/intonation.c
  14. 174
    173
      src/libespeak-ng/klatt.c
  15. 34
    34
      src/libespeak-ng/klatt.h
  16. 13
    13
      src/libespeak-ng/mbrowrap.c
  17. 2
    1
      src/libespeak-ng/mbrowrap.h
  18. 80
    78
      src/libespeak-ng/numbers.c
  19. 8
    8
      src/libespeak-ng/phoneme.h
  20. 10
    10
      src/libespeak-ng/phonemelist.c
  21. 213
    193
      src/libespeak-ng/readclause.c
  22. 108
    106
      src/libespeak-ng/setlengths.c
  23. 257
    257
      src/libespeak-ng/sintab.h
  24. 65
    64
      src/libespeak-ng/speak_lib.c
  25. 25
    25
      src/libespeak-ng/spect.c
  26. 20
    20
      src/libespeak-ng/spect.h
  27. 3
    3
      src/libespeak-ng/speech.h
  28. 26
    26
      src/libespeak-ng/synth_mbrola.c
  29. 75
    75
      src/libespeak-ng/synthdata.c
  30. 67
    66
      src/libespeak-ng/synthesize.c
  31. 40
    40
      src/libespeak-ng/synthesize.h
  32. 1072
    1066
      src/libespeak-ng/tr_languages.c
  33. 39
    39
      src/libespeak-ng/translate.c
  34. 76
    76
      src/libespeak-ng/translate.h
  35. 50
    50
      src/libespeak-ng/voices.c
  36. 439
    420
      src/libespeak-ng/wave.c
  37. 528
    510
      src/libespeak-ng/wave_pulse.c
  38. 205
    186
      src/libespeak-ng/wave_sada.c
  39. 171
    165
      src/libespeak-ng/wavegen.c
  40. 103
    102
      src/speak-ng.c

+ 101
- 100
src/espeak-ng.c View File

@@ -42,66 +42,66 @@


static const char *help_text =
"\nespeak-ng [options] [\"<words>\"]\n\n"
"-f <text file> Text file to speak\n"
"--stdin Read text input from stdin instead of a file\n\n"
"If neither -f nor --stdin, then <words> are spoken, or if none then text\n"
"is spoken from stdin, each line separately.\n\n"
"-a <integer>\n"
"\t Amplitude, 0 to 200, default is 100\n"
"-g <integer>\n"
"\t Word gap. Pause between words, units of 10mS at the default speed\n"
"-k <integer>\n"
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
"\t higher values indicate a pitch increase (try -k20).\n"
"-l <integer>\n"
"\t Line length. If not zero (which is the default), consider\n"
"\t lines less than this length as end-of-clause\n"
"-p <integer>\n"
"\t Pitch adjustment, 0 to 99, default is 50\n"
"-s <integer>\n"
"\t Speed in approximate words per minute. The default is 175\n"
"-v <voice name>\n"
"\t Use voice file of this name from espeak-data/voices\n"
"-w <wave file name>\n"
"\t Write speech to this WAV file, rather than speaking it directly\n"
"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
"-m\t Interpret SSML markup, and ignore other < > tags\n"
"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
"-x\t Write phoneme mnemonics to stdout\n"
"-X\t Write phonemes mnemonics and translation trace to stdout\n"
"-z\t No final sentence pause at the end of the text\n"
"--compile=<voice name>\n"
"\t Compile pronunciation rules and dictionary from the current\n"
"\t directory. <voice name> specifies the language\n"
"--compile-mbrola=<voice name>\n"
"\t Compile an MBROLA voice\n"
"--compile-intonations\n"
"\t Compile the intonation data\n"
"--compile-phonemes\n"
"\t Compile the phoneme data\n"
"--ipa Write phonemes to stdout using International Phonetic Alphabet\n"
"--path=\"<path>\"\n"
"\t Specifies the directory containing the espeak-data directory\n"
"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n"
"--phonout=\"<filename>\"\n"
"\t Write phoneme output from -x -X --ipa and --pho to this file\n"
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
"--sep=<character>\n"
"\t Separate phonemes (from -x --ipa) with <character>.\n"
"\t Default is space, z means ZWJN character.\n"
"--split=<minutes>\n"
"\t Starts a new WAV file every <minutes>. Used with -w\n"
"--stdout Write speech output to stdout\n"
"--tie=<character>\n"
"\t Use a tie character within multi-letter phoneme names.\n"
"\t Default is U+361, z means ZWJ character.\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";
"\nespeak-ng [options] [\"<words>\"]\n\n"
"-f <text file> Text file to speak\n"
"--stdin Read text input from stdin instead of a file\n\n"
"If neither -f nor --stdin, then <words> are spoken, or if none then text\n"
"is spoken from stdin, each line separately.\n\n"
"-a <integer>\n"
"\t Amplitude, 0 to 200, default is 100\n"
"-g <integer>\n"
"\t Word gap. Pause between words, units of 10mS at the default speed\n"
"-k <integer>\n"
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
"\t higher values indicate a pitch increase (try -k20).\n"
"-l <integer>\n"
"\t Line length. If not zero (which is the default), consider\n"
"\t lines less than this length as end-of-clause\n"
"-p <integer>\n"
"\t Pitch adjustment, 0 to 99, default is 50\n"
"-s <integer>\n"
"\t Speed in approximate words per minute. The default is 175\n"
"-v <voice name>\n"
"\t Use voice file of this name from espeak-data/voices\n"
"-w <wave file name>\n"
"\t Write speech to this WAV file, rather than speaking it directly\n"
"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
"-m\t Interpret SSML markup, and ignore other < > tags\n"
"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
"-x\t Write phoneme mnemonics to stdout\n"
"-X\t Write phonemes mnemonics and translation trace to stdout\n"
"-z\t No final sentence pause at the end of the text\n"
"--compile=<voice name>\n"
"\t Compile pronunciation rules and dictionary from the current\n"
"\t directory. <voice name> specifies the language\n"
"--compile-mbrola=<voice name>\n"
"\t Compile an MBROLA voice\n"
"--compile-intonations\n"
"\t Compile the intonation data\n"
"--compile-phonemes\n"
"\t Compile the phoneme data\n"
"--ipa Write phonemes to stdout using International Phonetic Alphabet\n"
"--path=\"<path>\"\n"
"\t Specifies the directory containing the espeak-data directory\n"
"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n"
"--phonout=\"<filename>\"\n"
"\t Write phoneme output from -x -X --ipa and --pho to this file\n"
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
"--sep=<character>\n"
"\t Separate phonemes (from -x --ipa) with <character>.\n"
"\t Default is space, z means ZWJN character.\n"
"--split=<minutes>\n"
"\t Starts a new WAV file every <minutes>. Used with -w\n"
"--stdout Write speech output to stdout\n"
"--tie=<character>\n"
"\t Use a tie character within multi-letter phoneme names.\n"
"\t Default is U+361, z means ZWJ character.\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";



@@ -231,7 +231,7 @@ void DisplayVoices(FILE *f_out, char *language)
break;
}
fprintf(f_out,"%2d %-12s%s%c %-20s %-13s ",
p[0],lang_name,age_buf,genders[v->gender],buf,v->identifier);
p[0],lang_name,age_buf,genders[v->gender],buf,v->identifier);
}
else
{
@@ -266,7 +266,8 @@ int OpenWavFile(char *path, int rate)
static unsigned char wave_hdr[44] = {
'R','I','F','F',0x24,0xf0,0xff,0x7f,'W','A','V','E','f','m','t',' ',
0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0,
2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f};
2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f
};

if(path == NULL)
return(2);
@@ -281,7 +282,7 @@ int OpenWavFile(char *path, int rate)
else
f_wavfile = fopen(path,"wb");
}
if(f_wavfile == NULL)
{
fprintf(stderr,"Can't write to: '%s'\n",path);
@@ -389,16 +390,16 @@ static void PrintVersion()


#ifdef NEED_GETOPT
struct option {
char *name;
int has_arg;
int *flag;
int val;
};
int optind;
static int optional_argument;
static const char *arg_opts = "abfgklpsvw"; // which options have arguments
static char *opt_string="";
struct option {
char *name;
int has_arg;
int *flag;
int val;
};
int optind;
static int optional_argument;
static const char *arg_opts = "abfgklpsvw"; // which options have arguments
static char *opt_string="";
#define no_argument 0
#define required_argument 1
#define optional_argument 2
@@ -407,7 +408,7 @@ static void PrintVersion()
int main (int argc, char **argv)
{
static struct option long_options[] =
{
{
{"help", no_argument, 0, 'h'},
{"stdin", no_argument, 0, 0x100},
{"compile-debug", optional_argument, 0, 0x101},
@@ -427,7 +428,7 @@ int main (int argc, char **argv)
{"compile-intonations", no_argument, 0, 0x10f},
{"compile-phonemes", no_argument, 0, 0x110},
{0, 0, 0, 0}
};
};

static const char* err_load = "Failed to read ";

@@ -496,7 +497,7 @@ int main (int argc, char **argv)
break; // -- means don't interpret further - as commands

opt_string="";
for(ix=0; ;ix++)
for(ix=0;; ix++)
{
if(long_options[ix].name == 0)
break;
@@ -528,7 +529,7 @@ int main (int argc, char **argv)
while(true)
{
c = getopt_long (argc, argv, "a:b:f:g:hk:l:mp:qs:v:w:xXz",
long_options, &option_index);
long_options, &option_index);

/* Detect the end of the options. */
if (c == -1)
@@ -610,23 +611,23 @@ int main (int argc, char **argv)
synth_flags &= ~espeakENDPAUSE;
break;

case 0x100: // --stdin
case 0x100: // --stdin
flag_stdin = 1;
break;

case 0x105: // --stdout
case 0x105: // --stdout
option_waveout = 1;
strcpy(wavefile,"stdout");
break;

case 0x101: // --compile-debug
case 0x102: // --compile
case 0x102: // --compile
strncpy0(voicename,optarg2,sizeof(voicename));
flag_compile = c;
quiet = 1;
break;

case 0x103: // --punct
case 0x103: // --punct
option_punctuation = 1;
if(optarg2 != NULL)
{
@@ -671,34 +672,34 @@ int main (int argc, char **argv)
// deprecated and obsolete
switch(atoi(optarg2))
{
case 1:
phonemes_separator = '_';
break;
case 2:
phonemes_separator = 0x0361;
phoneme_options |= espeakPHONEMES_TIE;
break;
case 3:
phonemes_separator = 0x200d; // ZWJ
phoneme_options |= espeakPHONEMES_TIE;
break;
case 1:
phonemes_separator = '_';
break;
case 2:
phonemes_separator = 0x0361;
phoneme_options |= espeakPHONEMES_TIE;
break;
case 3:
phonemes_separator = 0x200d; // ZWJ
phoneme_options |= espeakPHONEMES_TIE;
break;
}
}
break;

case 0x10b: // --version
PrintVersion();
exit(0);
case 0x10c: // --sep
phoneme_options |= espeakPHONEMES_SHOW;
if(optarg2 == 0)
phonemes_separator = ' ';
else
utf8_in(&phonemes_separator, optarg2);
if(phonemes_separator == 'z')
phonemes_separator = 0x200c; // ZWNJ
if(phonemes_separator == 'z')
phonemes_separator = 0x200c; // ZWNJ
break;

case 0x10d: // --tie
@@ -707,8 +708,8 @@ int main (int argc, char **argv)
phonemes_separator = 0x0361; // default: combining-double-inverted-breve
else
utf8_in(&phonemes_separator, optarg2);
if(phonemes_separator == 'z')
phonemes_separator = 0x200d; // ZWJ
if(phonemes_separator == 'z')
phonemes_separator = 0x200d; // ZWJ
break;

case 0x10e: // --compile-mbrola
@@ -755,7 +756,7 @@ int main (int argc, char **argv)
// play the sound output
samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,data_path,0);
}

if(voicename[0] == 0)
strcpy(voicename,"default");
@@ -795,7 +796,7 @@ int main (int argc, char **argv)
espeak_SetParameter(espeakLINELENGTH,option_linelength,0);
if(option_punctuation == 2)
espeak_SetPunctuationList(option_punctlist);

espeak_SetPhonemeTrace(phoneme_options | (phonemes_separator << 8), f_phonemes_out);


+ 243
- 236
src/libespeak-ng/compiledata.c View File

@@ -40,8 +40,8 @@
#endif

typedef struct {
unsigned int value;
char *name;
unsigned int value;
char *name;
} NAMETAB;

NAMETAB *manifest = NULL;
@@ -322,29 +322,29 @@ static keywtab_t keywords[] = {
{"flag3", tPHONEME_FLAG, phFLAG3},

// voiced / unvoiced
{"vcd", tPHONEME_FLAG, phVOICED},
{"vls", tPHONEME_FLAG, phFORTIS},
{"vcd", tPHONEME_FLAG, phVOICED},
{"vls", tPHONEME_FLAG, phFORTIS},

// place of articulation, set bits 16-19 of phflags
{"blb", tPLACE, 1},
{"lbd", tPLACE, 2},
{"dnt", tPLACE, 3},
{"alv", tPLACE, 4},
{"rfx", tPLACE, 5},
{"pla", tPLACE, 6},
{"pal", tPLACE, 7},
{"vel", tPLACE, 8},
{"lbv", tPLACE, 9},
{"uvl", tPLACE, 10},
{"phr", tPLACE, 11},
{"glt", tPLACE, 12},
{"blb", tPLACE, 1},
{"lbd", tPLACE, 2},
{"dnt", tPLACE, 3},
{"alv", tPLACE, 4},
{"rfx", tPLACE, 5},
{"pla", tPLACE, 6},
{"pal", tPLACE, 7},
{"vel", tPLACE, 8},
{"lbv", tPLACE, 9},
{"uvl", tPLACE, 10},
{"phr", tPLACE, 11},
{"glt", tPLACE, 12},

// vowel transition attributes
{"len=", tTRANSITION, 1},
{"rms=", tTRANSITION, 2},
{"f1=", tTRANSITION, 3},
{"len=", tTRANSITION, 1},
{"rms=", tTRANSITION, 2},
{"f1=", tTRANSITION, 3},
{"f2=", tTRANSITION, 4},
{"f3=", tTRANSITION, 5},
{"f3=", tTRANSITION, 5},
{"brk", tTRANSITION, 6},
{"rate", tTRANSITION, 7},
{"glstop", tTRANSITION, 8},
@@ -359,7 +359,8 @@ static keywtab_t keywords[] = {


static keywtab_t *keyword_tabs[] = {
keywords, k_conditions, k_properties, k_intonation };
keywords, k_conditions, k_properties, k_intonation
};


static PHONEME_TAB *phoneme_out;
@@ -376,7 +377,7 @@ static char equivalence_buf[20000];

#define N_PROCS 50
int n_procs;
int proc_addr[N_PROCS];
int proc_addr[N_PROCS];
char proc_names[40][N_PROCS];

#define MAX_PROG_BUF 2000
@@ -386,54 +387,54 @@ USHORT prog_buf[MAX_PROG_BUF+20];

static void ReadPhondataManifest()
{
// Read the phondata-manifest file
FILE *f;
int n_lines=0;
int ix;
char *p;
unsigned int value;
char buf[sizeof(path_home)+40];
char name[120];
// Read the phondata-manifest file
FILE *f;
int n_lines=0;
int ix;
char *p;
unsigned int value;
char buf[sizeof(path_home)+40];
char name[120];

sprintf(buf,"%s%c%s",path_home,PATHSEP,"phondata-manifest");
if((f = fopen(buf, "r")) == NULL)
return;
while(fgets(buf, sizeof(buf), f) != NULL)
n_lines++;
rewind(f);
if(manifest != NULL)
{
for(ix=0; ix < n_manifest; ix++)
free(manifest[ix].name);
}
if((manifest = (NAMETAB *)realloc(manifest, n_lines * sizeof(NAMETAB))) == NULL)
{
fclose(f);
return;
}
n_manifest = 0;
while(fgets(buf, sizeof(buf), f) != NULL)
{
if(!isalpha(buf[0]))
continue;
if(sscanf(&buf[2], "%x %s", &value, name) == 2)
{
if((p = (char *)malloc(strlen(name)+1)) != NULL)
{
strcpy(p, name);
manifest[n_manifest].value = value;
manifest[n_manifest].name = p;
n_manifest++;
}
}
}
fclose(f);
if((f = fopen(buf, "r")) == NULL)
return;
while(fgets(buf, sizeof(buf), f) != NULL)
n_lines++;
rewind(f);
if(manifest != NULL)
{
for(ix=0; ix < n_manifest; ix++)
free(manifest[ix].name);
}
if((manifest = (NAMETAB *)realloc(manifest, n_lines * sizeof(NAMETAB))) == NULL)
{
fclose(f);
return;
}
n_manifest = 0;
while(fgets(buf, sizeof(buf), f) != NULL)
{
if(!isalpha(buf[0]))
continue;
if(sscanf(&buf[2], "%x %s", &value, name) == 2)
{
if((p = (char *)malloc(strlen(name)+1)) != NULL)
{
strcpy(p, name);
manifest[n_manifest].value = value;
manifest[n_manifest].name = p;
n_manifest++;
}
}
}
fclose(f);
}

static const char *KeyToMnem(keywtab_t *ktab, int type, int value)
@@ -467,7 +468,8 @@ static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)
"", "", "IF", "IF OR",
"", "", "", "",
"", "", "", "FMT",
"WAV", "NextVowelStart", "PrevVowelEnd", "+wav" };
"WAV", "NextVowelStart", "PrevVowelEnd", "+wav"
};

static const char *nextPh_string[6] = {
"prevPh", "thisPh", "nextPh", "next2Ph", "nextPhW", "**",
@@ -483,15 +485,17 @@ static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)

static const char *instn_jumps[] = {
"JMP", "Invalid", "Invalid", "Invalid",
"JMP false", "SwitchNextVowelType", "SwitchPrevVowelType", "Invalid"};
"JMP false", "SwitchNextVowelType", "SwitchPrevVowelType", "Invalid"
};

static char instn1_paramtype[] = {
0, 3, 3, 3, 3, 3, 3, 1,
1, 1, 1, 1, 1, 0, 0, 0,
3, 3, 3, 3, 3, 3, 3, 3,
0, 0, 0, 0, 0, 0, 0, 0};
0, 0, 0, 0, 0, 0, 0, 0
};

return;
return;

if(compile_phoneme)
{
@@ -715,7 +719,7 @@ unsigned char envelope_dat[N_ENVELOPES][ENV_LEN];

typedef struct {
FILE *file;
int linenum;
int linenum;
char fname[80];
} STACK;

@@ -728,7 +732,7 @@ int if_level;
typedef struct {
USHORT *p_then;
USHORT *p_else;
int returned;
int returned;
} IF_STACK;
IF_STACK if_stack[N_IF_STACK];

@@ -785,8 +789,8 @@ static void CompileReport(void)
int procedure_num;
int prev_mnemonic;

if(f_report == NULL)
return;
if(f_report == NULL)
return;

// make a list of all the references and sort it
list = (REF_HASH_TAB **)malloc((count_references)* sizeof(REF_HASH_TAB *));
@@ -794,7 +798,7 @@ static void CompileReport(void)
return;

fprintf(f_report,"\n%d phoneme tables\n",n_phoneme_tabs);
fprintf(f_report," new total\n");
fprintf(f_report," new total\n");
for(ix=0; ix<n_phoneme_tabs; ix++)
{
fprintf(f_report,"%8s %3d %4d\n",phoneme_tab_list2[ix].name, phoneme_tab_list2[ix].n_phonemes, n_phcodes_list[ix]+1);
@@ -872,7 +876,7 @@ int strcasecmp(const char *s1, const char *s2)
int ix=0;
int diff;

for(;;)
for(;; )
{
if((diff = (tolower(s1[ix]) - tolower(s2[ix]))) != 0)
return(diff);
@@ -905,7 +909,7 @@ static int ph_sorter(char **a, char **b)
return(ix);

strcpy(mnem1,WordToString(p1->mnemonic));
return(strcasecmp(mnem1,WordToString(p2->mnemonic)));
return(strcasecmp(mnem1,WordToString(p2->mnemonic)));
}


@@ -1015,7 +1019,7 @@ static FILE *fopen_log(FILE *f_log, const char *fname,const char *access)
static unsigned int StringToWord(const char *string)
{
// Pack 4 characters into a word
int ix;
int ix;
unsigned char c;
unsigned int word;

@@ -1067,7 +1071,8 @@ static MNEM_TAB reserved_phonemes[] = {
{"#i", phonVOWELTYPES+3},
{"#o", phonVOWELTYPES+4},
{"#u", phonVOWELTYPES+5},
{NULL, 0} };
{NULL, 0}
};


static void ReservePhCodes()
@@ -1096,9 +1101,9 @@ static int LookupPhoneme(const char *string, int control)
// control = 1 declare phoneme if not found
// control = 2 start looking after control & stress phonemes

int ix;
int start;
int use;
int ix;
int start;
int use;
unsigned int word;

if(strcmp(string,"NULL")==0)
@@ -1116,7 +1121,7 @@ static int LookupPhoneme(const char *string, int control)

if(control==2)
start = 8; // don't look for control and stress phonemes (allows these characters to be
// used for other purposes)
// used for other purposes)

use = 0;
for(ix=start; ix<n_phcodes; ix++)
@@ -1176,11 +1181,11 @@ int CheckNextChar()

static int NextItem(int type)
{
int acc;
unsigned char c=0;
int acc;
unsigned char c=0;
unsigned char c2;
int ix;
int sign;
int ix;
int sign;
char *p;
keywtab_t *pk;

@@ -1308,17 +1313,17 @@ static int NextItem(int type)
static int NextItemMax(int max)
{
// Get a number, but restrict value to max
int value;
char msg[80];
value = NextItem(tNUMBER);
if(value > max)
{
sprintf(msg, "Value %d is greater than maximum %d", value, max);
error(msg, NULL);
value = max;
}
return(value);
int value;
char msg[80];
value = NextItem(tNUMBER);
if(value > max)
{
sprintf(msg, "Value %d is greater than maximum %d", value, max);
error(msg, NULL);
value = max;
}
return(value);
}


@@ -1415,7 +1420,7 @@ int CompileVowelTransition(int which)
rms = 16 / 2;
}

for(;;)
for(;; )
{
key = NextItem(tKEYWORD);
if(item_type != tTRANSITION)
@@ -1724,10 +1729,10 @@ static int LoadWavefile(FILE *f, const char *fname)

if((sr1 != samplerate_native) || (sr2 != sr1*2))
{
int fd_temp;
char command[sizeof(path_home)+250];
int fd_temp;
char command[sizeof(path_home)+250];

failed = 0;
failed = 0;

#ifdef PLATFORM_POSIX
strcpy(fname_temp,"/tmp/espeakXXXXXX");
@@ -1739,52 +1744,52 @@ static int LoadWavefile(FILE *f, const char *fname)
strcpy(fname_temp,tmpnam(NULL));
#endif

fname2 = fname;
len = strlen(fname);
if(strcmp(&fname[len-4], ".wav") == 0)
{
strcpy(msg, fname);
msg[len-4] = 0;
fname2 = msg;
}
sprintf(command,"sox \"%s/../phsource/%s.wav\" -r %d -c1 -t wav %s\n",path_home,fname2,samplerate_native, fname_temp);
if(system(command) != 0)
{
failed = 1;
}
if(failed || (GetFileLength(fname_temp) <= 0))
{
if(resample_fails < 2)
error("Resample command failed: %s", command);
resample_fails++;
if(sr1 != samplerate_native)
{
sprintf(msg, "Can't resample (%d to %d): %s", sr1, samplerate_native, fname);
error("%s", msg);
}
else
{
error("WAV file is not mono: %s", fname);
}
remove(fname_temp);
return(0);
}
f = fopen(fname_temp,"rb");
if(f == NULL)
{
error("Can't read temp file: %s",fname_temp);
return(0);
}
if(f_report != NULL)
fprintf(f_report, "resampled %s\n", fname);
resample_count++;
resample_wav = 1;
fseek(f,40,SEEK_SET); // skip past the WAV header, up to before "data length"
fname2 = fname;
len = strlen(fname);
if(strcmp(&fname[len-4], ".wav") == 0)
{
strcpy(msg, fname);
msg[len-4] = 0;
fname2 = msg;
}
sprintf(command,"sox \"%s/../phsource/%s.wav\" -r %d -c1 -t wav %s\n",path_home,fname2,samplerate_native, fname_temp);
if(system(command) != 0)
{
failed = 1;
}
if(failed || (GetFileLength(fname_temp) <= 0))
{
if(resample_fails < 2)
error("Resample command failed: %s", command);
resample_fails++;
if(sr1 != samplerate_native)
{
sprintf(msg, "Can't resample (%d to %d): %s", sr1, samplerate_native, fname);
error("%s", msg);
}
else
{
error("WAV file is not mono: %s", fname);
}
remove(fname_temp);
return(0);
}
f = fopen(fname_temp,"rb");
if(f == NULL)
{
error("Can't read temp file: %s",fname_temp);
return(0);
}
if(f_report != NULL)
fprintf(f_report, "resampled %s\n", fname);
resample_count++;
resample_wav = 1;
fseek(f,40,SEEK_SET); // skip past the WAV header, up to before "data length"
}

displ = ftell(f_phdata);
@@ -1833,7 +1838,7 @@ static int LoadWavefile(FILE *f, const char *fname)

if(feof(f)) break;

if(scale_factor <= MIN_FACTOR)
if(scale_factor <= MIN_FACTOR)
{
fputc(sample & 0xff,f_phdata);
fputc(sample >> 8,f_phdata);
@@ -1897,19 +1902,19 @@ static int LoadEnvelope(FILE *f, const char *fname)
/* Generate a hash code from the specified string */
static int Hash8(const char *string)
{
int c;
int chars=0;
int hash=0;
while((c = *string++) != 0)
{
c = tolower(c) - 'a';
hash = hash * 8 + c;
hash = (hash & 0x1ff) ^ (hash >> 8); /* exclusive or */
int c;
int chars=0;
int hash=0;
while((c = *string++) != 0)
{
c = tolower(c) - 'a';
hash = hash * 8 + c;
hash = (hash & 0x1ff) ^ (hash >> 8); /* exclusive or */
chars++;
}
}

return((hash+chars) & 0xff);
return((hash+chars) & 0xff);
}


@@ -2182,16 +2187,16 @@ int CompileSound(int keyword, int isvowel)


/*
Condition
bits 14,15 1
bit 13 1 = AND, 0 = OR
bit 12 spare
bit 8-11
=0-3 p,t,n,n2 data=phoneme code
=4-7 p,t,n,n2 data=(bits5-7: phtype, place, property, special) (bits0-4: data)
=8 data = stress bitmap
=9 special tests
*/
Condition
bits 14,15 1
bit 13 1 = AND, 0 = OR
bit 12 spare
bit 8-11
=0-3 p,t,n,n2 data=phoneme code
=4-7 p,t,n,n2 data=(bits5-7: phtype, place, property, special) (bits0-4: data)
=8 data = stress bitmap
=9 special tests
*/

int CompileIf(int elif)
{
@@ -2233,9 +2238,9 @@ int CompileIf(int elif)
// prevPh(), thisPh(), nextPh(), next2Ph() etc
if(key >= 6)
{
// put the 'which' code in the next instruction
word2 = key;
key = 6;
// put the 'which' code in the next instruction
word2 = key;
key = 6;
}
key = key << 8;

@@ -2763,19 +2768,19 @@ int CompilePhoneme(int compile_phoneme)
count = 0;
ix = 1;

for(p=item_string; *p != 0;)
for(p=item_string; *p != 0; )
{
p += utf8_in(&c, p);
if((c == '|') && (count > 0))
{
// '|' means don't allow a tie or joiner before this letter
flags |= (1 << (count -1));
}
else
p += utf8_in(&c, p);
if((c == '|') && (count > 0))
{
// '|' means don't allow a tie or joiner before this letter
flags |= (1 << (count -1));
}
else
if((c=='U') && (p[0]=='+'))
{
int j;
int j;
// U+9999
p++;
memcpy(number_buf,p,4); // U+ should be followed by 4 hex digits
@@ -2786,25 +2791,25 @@ int CompilePhoneme(int compile_phoneme)
// move past the 4 hexdecimal digits
for(j=0; j<4; j++)
{
if(!isalnum(*p))
break;
p++;
if(!isalnum(*p))
break;
p++;
}
ix += utf8_out(c, &ipa_buf[ix]);
count++;
}
else
{
ix += utf8_out(c, &ipa_buf[ix]);
ix += utf8_out(c, &ipa_buf[ix]);
count++;
}
}
ipa_buf[0] = flags;
ipa_buf[ix] = 0;

start = 1;
if(flags != 0)
start = 0; // only include the flags byte if bits are set
start = 1;
if(flags != 0)
start = 0; // only include the flags byte if bits are set
value = strlen(&ipa_buf[start]); // number of UTF-8 bytes

*prog_out++ = (i_IPA_NAME << 8) + value;
@@ -3089,7 +3094,7 @@ static void WritePhonemeTables()

static void EndPhonemeTable()
{
int ix;
int ix;
int *pw;
int length;

@@ -3104,7 +3109,7 @@ static void EndPhonemeTable()
if(phoneme_tab2[ix].type == phINVALID)
{
fprintf(f_errors,"%3d: Phoneme [%s] not declared, referenced at line %d\n",linenum,
WordToString(phoneme_tab2[ix].mnemonic),(int)(phoneme_tab2[ix].program));
WordToString(phoneme_tab2[ix].mnemonic),(int)(phoneme_tab2[ix].program));
error_count++;
phoneme_tab2[ix].type = 0; // prevent the error message repeating
}
@@ -3157,7 +3162,7 @@ static void StartPhonemeTable(const char *name)

if(n_phoneme_tabs > 0)
{
NextItem(tSTRING); // name of base phoneme table
NextItem(tSTRING); // name of base phoneme table
for(ix=0; ix<n_phoneme_tabs; ix++)
{
if(strcmp(item_string,phoneme_tab_list2[ix].name)==0)
@@ -3307,7 +3312,7 @@ static void CompilePhonemeFiles()
count_frames = 0;
n_procs = 0;

for(;;)
for(;; )
{
if(feof(f_in))
{
@@ -3326,8 +3331,8 @@ static void CompilePhonemeFiles()

switch(item)
{
case kUTF8_BOM:
break; // ignore bytes 0xef 0xbb 0xbf
case kUTF8_BOM:
break; // ignore bytes 0xef 0xbb 0xbf

case kINCLUDE:
NextItem(tSTRING);
@@ -3353,7 +3358,7 @@ static void CompilePhonemeFiles()

case kPHONEMETABLE:
EndPhonemeTable();
NextItem(tSTRING); // name of the new phoneme table
NextItem(tSTRING); // name of the new phoneme table
StartPhonemeTable(item_string);
break;

@@ -3391,7 +3396,7 @@ static espeak_ng_STATUS CompilePhonemeData2(const char *source, FILE *log)
sprintf(fname,"%s/../phsource",path_home);

#ifdef MAKE_ENVELOPES
make_envs();
make_envs();
#endif

fprintf(log,"Compiling phoneme data: %s\n",fname);
@@ -3431,19 +3436,19 @@ make_envs();
f_phcontents = stderr;

fprintf (f_phcontents,
"# This file lists the type of data that has been compiled into the\n"
"# phondata file\n"
"#\n"
"# The first character of a line indicates the type of data:\n"
"# S - A SPECT_SEQ structure\n"
"# W - A wavefile segment\n"
"# E - An envelope\n"
"# Q - Phoneme equivalence tables\n"
"#\n"
"# Address is the displacement within phondata of this item\n"
"#\n"
"# Address Data file\n"
"# ------- ---------\n");
"# This file lists the type of data that has been compiled into the\n"
"# phondata file\n"
"#\n"
"# The first character of a line indicates the type of data:\n"
"# S - A SPECT_SEQ structure\n"
"# W - A wavefile segment\n"
"# E - An envelope\n"
"# Q - Phoneme equivalence tables\n"
"#\n"
"# Address is the displacement within phondata of this item\n"
"#\n"
"# Address Data file\n"
"# ------- ---------\n");


fprintf(f_errors, "Source data path = '%s/../phsource'\n", path_home);
@@ -3484,11 +3489,11 @@ make_envs();
EndPhonemeTable();
WritePhonemeTables();

fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references);
fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references);
fclose(f_in);
fclose(f_phdata);
if(f_prog_log != NULL)
fclose(f_prog_log);
if(f_prog_log != NULL)
fclose(f_prog_log);
fclose(f_phindex);
fclose(f_phtab);
fclose(f_phcontents);
@@ -3502,37 +3507,38 @@ fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references

if(resample_count > 0)
{
fprintf(f_errors, "\n%d WAV files resampled to %d Hz\n", resample_count, samplerate_native);
fprintf(log,"Compiled phonemes: %d errors, %d files resampled to %d Hz.\n",error_count, resample_count, samplerate_native);
fprintf(f_errors, "\n%d WAV files resampled to %d Hz\n", resample_count, samplerate_native);
fprintf(log,"Compiled phonemes: %d errors, %d files resampled to %d Hz.\n",error_count, resample_count, samplerate_native);
}
else
{
fprintf(log,"Compiled phonemes: %d errors.\n",error_count);
fprintf(log,"Compiled phonemes: %d errors.\n",error_count);
}

if(f_errors != stderr)
fclose(f_errors);
fclose(f_errors);

ReadPhondataManifest();
return ENS_OK;
ReadPhondataManifest();
return ENS_OK;
}


static const char *preset_tune_names[] = {
"s1", "c1", "q1", "e1", NULL};
"s1", "c1", "q1", "e1", NULL
};

static const TUNE default_tune = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0},
{0, 40, 24, 8, 0, 0, 0, 0},
46, 57, PITCHfall, 16, 0, 0,
255, 78, 50, 255,
3, 5,
{-7,-7,-7}, {-7,-7,-7},
PITCHfall, 64, 8,
PITCHfall, 70, 18, 24, 12,
PITCHfall, 70, 18, 24, 12, 0,
{0,0,0,0,0,0,0,0}, 0
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0},
{0, 40, 24, 8, 0, 0, 0, 0},
46, 57, PITCHfall, 16, 0, 0,
255, 78, 50, 255,
3, 5,
{-7,-7,-7}, {-7,-7,-7},
PITCHfall, 64, 8,
PITCHfall, 70, 18, 24, 12,
PITCHfall, 70, 18, 24, 12, 0,
{0,0,0,0,0,0,0,0}, 0
};

#define N_TUNE_NAMES 100
@@ -3548,7 +3554,8 @@ MNEM_TAB envelope_names[] = {
{"fall2", 14},
{"rise2", 16},
{"rise-fall-rise", 18},
{NULL, -1} };
{NULL, -1}
};

int LookupEnvelopeName(const char *name)
{
@@ -3860,7 +3867,7 @@ espeak_ng_STATUS espeak_ng_CompileIntonation(FILE *log)

espeak_ng_STATUS espeak_ng_CompilePhonemeData(long rate, FILE *log)
{
WavegenInit(rate, 0);
WavegenInit(rate, 0);
WavegenSetVoice(voice);
return CompilePhonemeData2("phonemes", log);
}

+ 38
- 39
src/libespeak-ng/compiledict.c View File

@@ -238,15 +238,15 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
unsigned char c;
char *p;
char *p_end;
int ix;
int match_type;
int finished=0;
int value;
int linenum=0;
int flags;
int suffix_char;
int condition_num=0;
int at_start = 0;
int ix;
int match_type;
int finished=0;
int value;
int linenum=0;
int flags;
int suffix_char;
int condition_num=0;
int at_start = 0;
const char *name;
char buf[200];
char buf_pre[200];
@@ -254,9 +254,8 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
static char output[80];

static char symbols[] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
'&','%','+','#','S','D','Z','A','L','!',' ','@','?','J','N','K','V','?','T','X','?','W'
};
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
'&','%','+','#','S','D','Z','A','L','!',' ','@','?','J','N','K','V','?','T','X','?','W'};

static char symbols_lg[] = {'A','B','C','H','F','G','Y'};

@@ -409,25 +408,25 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
static int compile_line(char *linebuf, char *dict_line, int *hash)
{
// Compile a line in the language_list file
unsigned char c;
unsigned char c;
char *p;
char *word;
char *phonetic;
unsigned int ix;
int step;
unsigned int n_flag_codes = 0;
unsigned int ix;
int step;
unsigned int n_flag_codes = 0;
int flagnum;
int flag_offset;
int length;
int multiple_words = 0;
int multiple_numeric_hyphen = 0;
int flag_offset;
int length;
int multiple_words = 0;
int multiple_numeric_hyphen = 0;
char *multiple_string = NULL;
char *multiple_string_end = NULL;

int len_word;
int len_phonetic;
int text_not_phonemes; // this word specifies replacement text, not phonemes
unsigned int wc;
unsigned int wc;
int all_upper_case;

char *mnemptr;
@@ -679,7 +678,7 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)

all_upper_case = 1;
p = word;
for(p=word;;)
for(p=word;; )
{
// this assumes that the lower case char is the same length as the upper case char
// OK, except for Turkish "I", but use towlower() rather than towlower2()
@@ -823,10 +822,10 @@ static void compile_dictlist_end(FILE *f_out)

static int compile_dictlist_file(const char *path, const char* filename)
{
int length;
int hash;
int length;
int hash;
char *p;
int count=0;
int count=0;
FILE *f_in;
char buf[200];
char fname[sizeof(path_home)+45];
@@ -890,7 +889,7 @@ static char rule_phonemes[80];
static char group_name[LEN_GROUP_NAME+1];
static int group3_ix;

#define N_RULES 3000 // max rules for each group
#define N_RULES 3000 // max rules for each group



@@ -917,10 +916,10 @@ static void copy_rule_string(char *string, int *state_out)
int len;
char c;
int c2, c3;
int sxflags;
int value;
int literal;
int hexdigit_input = 0;
int sxflags;
int value;
int literal;
int hexdigit_input = 0;
int state = *state_out;
MNEM_TAB *mr;

@@ -937,7 +936,7 @@ static void copy_rule_string(char *string, int *state_out)
}
sxflags = 0x808000; // to ensure non-zero bytes

for(p=string,ix=0;;)
for(p=string,ix=0;; )
{
literal = 0;
c = *p++;
@@ -1127,7 +1126,7 @@ static void copy_rule_string(char *string, int *state_out)
case 'i':
sxflags |= SUFX_I;
break;
case 'p': // obsolete, replaced by 'P' above
case 'p': // obsolete, replaced by 'P' above
sxflags |= SUFX_P;
break;
case 'v':
@@ -1209,14 +1208,14 @@ static char *compile_rule(char *input)

switch(c = input[ix])
{
case ')': // end of prefix section
case ')': // end of prefix section
*p = 0;
state = 1;
copy_rule_string(buf,&state);
p = buf;
break;

case '(': // start of suffix section
case '(': // start of suffix section
*p = 0;
state = 2;
copy_rule_string(buf,&state);
@@ -1229,15 +1228,15 @@ static char *compile_rule(char *input)
}
break;

case '\n': // end of line
case '\n': // end of line
case '\r':
case 0: // end of line
case 0: // end of line
*p = 0;
copy_rule_string(buf,&state);
finish=1;
break;

case '\t': // end of section section
case '\t': // end of section section
case ' ':
*p = 0;
copy_rule_string(buf,&state);
@@ -1533,7 +1532,7 @@ static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name
if((common[0] != 0) && (strcmp(p,common)==0))
{
fwrite(p2,len2,1,f_out);
fputc(0,f_out); // no phoneme string, it's the same as previous rule
fputc(0,f_out); // no phoneme string, it's the same as previous rule
}
else
{
@@ -1671,7 +1670,7 @@ static int compile_dictrules(FILE *f_in, FILE *f_out, char *fname_temp)
if((f_temp = fopen_log(fname_temp,"wb")) == NULL)
return(1);

for(;;)
for(;; )
{
linenum++;
buf = fgets(buf1,sizeof(buf1),f_in);

+ 1
- 1
src/libespeak-ng/compilembrola.c View File

@@ -40,7 +40,7 @@ static const char *basename(const char *filename)
static unsigned int StringToWord(const char *string)
{
// Pack 4 characters into a word
int ix;
int ix;
unsigned char c;
unsigned int word;


+ 31
- 31
src/libespeak-ng/debug.c View File

@@ -18,51 +18,51 @@ void debug_init()

void debug_enter(const char* text)
{
struct timeval tv;
struct timeval tv;

gettimeofday(&tv, NULL);
gettimeofday(&tv, NULL);

if (!fd_log)
{
debug_init();
}
if (!fd_log)
{
debug_init();
}

if (fd_log)
{
fprintf(fd_log, "%03d.%03dms > ENTER %s\n",(int)(tv.tv_sec%1000), (int)(tv.tv_usec/1000), text);
}
if (fd_log)
{
fprintf(fd_log, "%03d.%03dms > ENTER %s\n",(int)(tv.tv_sec%1000), (int)(tv.tv_usec/1000), text);
}
}


void debug_show(const char *format, ...)
{
va_list args;
va_start(args, format);
if (!fd_log)
{
debug_init();
}
if (fd_log)
{
vfprintf(fd_log, format, args);
}
va_end(args);
va_list args;
va_start(args, format);
if (!fd_log)
{
debug_init();
}
if (fd_log)
{
vfprintf(fd_log, format, args);
}
va_end(args);
}

void debug_time(const char* text)
{
struct timeval tv;
struct timeval tv;

gettimeofday(&tv, NULL);
gettimeofday(&tv, NULL);

if (!fd_log)
{
debug_init();
}
if (fd_log)
{
fprintf(fd_log, "%03d.%03dms > %s\n",(int)(tv.tv_sec%1000), (int)(tv.tv_usec/1000), text);
}
if (!fd_log)
{
debug_init();
}
if (fd_log)
{
fprintf(fd_log, "%03d.%03dms > %s\n",(int)(tv.tv_sec%1000), (int)(tv.tv_usec/1000), text);
}
}

#endif

+ 150
- 151
src/libespeak-ng/dictionary.c View File

@@ -49,7 +49,7 @@ static unsigned char remove_accent[N_REMOVE_ACCENT] = {
'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0c0
'd','n','o','o','o','o','o', 0, 'o','u','u','u','u','y','t','s', // 0d0
'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0e0
'd','n','o','o','o','o','o', 0 ,'o','u','u','u','u','y','t','y', // 0f0
'd','n','o','o','o','o','o', 0,'o','u','u','u','u','y','t','y', // 0f0

'a','a','a','a','a','a','c','c','c','c','c','c','c','c','d','d', // 100
'd','d','e','e','e','e','e','e','e','e','e','e','g','g','g','g', // 110
@@ -125,7 +125,7 @@ static void InitGroups(Translator *tr)
// for single-letters and two-letter combinations


int ix;
int ix;
char *p;
char *p_name;
unsigned int *pw;
@@ -280,7 +280,7 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
}

if((Reverse4Bytes(pw[0]) != N_HASH_DICT) ||
(length <= 0) || (length > 0x8000000))
(length <= 0) || (length > 0x8000000))
{
fprintf(stderr,"Bad data: '%s' (%x length=%x)\n",fname,Reverse4Bytes(pw[0]),length);
return(2);
@@ -313,13 +313,13 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)


/* Generate a hash code from the specified string
This is used to access the dictionary_2 word-lookup dictionary
*/
This is used to access the dictionary_2 word-lookup dictionary
*/
int HashDictionary(const char *string)
{
int c;
int chars=0;
int hash=0;
int c;
int chars=0;
int hash=0;

while((c = (*string++ & 0xff)) != 0)
{
@@ -338,16 +338,16 @@ int HashDictionary(const char *string)
Returns advanced 'p'
outptr contains encoded phonemes, unrecognized phoneme stops the encoding
bad_phoneme must point to char array of length 2 of more
*/
*/
const char *EncodePhonemes(const char *p, char *outptr, int *bad_phoneme)
{
int ix;
unsigned char c;
int count; /* num. of matching characters */
int max; /* highest num. of matching found so far */
int max_ph; /* corresponding phoneme with highest matching */
int consumed;
unsigned int mnemonic_word;
unsigned char c;
int count; /* num. of matching characters */
int max; /* highest num. of matching found so far */
int max_ph; /* corresponding phoneme with highest matching */
int consumed;
unsigned int mnemonic_word;

if(bad_phoneme != NULL)
*bad_phoneme = 0;
@@ -396,11 +396,11 @@ const char *EncodePhonemes(const char *p, char *outptr, int *bad_phoneme)
mnemonic_word = phoneme_tab[ix]->mnemonic;

while(((c = p[count]) > ' ') && (count < 4) &&
(c == ((mnemonic_word >> (count*8)) & 0xff)))
(c == ((mnemonic_word >> (count*8)) & 0xff)))
count++;

if((count > max) &&
((count == 4) || (((mnemonic_word >> (count*8)) & 0xff)==0)))
((count == 4) || (((mnemonic_word >> (count*8)) & 0xff)==0)))
{
max = count;
max_ph = phoneme_tab[ix]->code;
@@ -461,7 +461,7 @@ void DecodePhonemes(const char *inptr, char *outptr)
// Translate from internal phoneme codes into phoneme mnemonics
unsigned char phcode;
unsigned char c;
unsigned int mnem;
unsigned int mnem;
PHONEME_TAB *ph;
static const char *stress_chars = "==,,'* ";

@@ -627,12 +627,12 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)
bit 7: use tie between letters in multi-character phoneme names
bits 8-23 tie or separator character

*/
*/

int ix;
unsigned int len;
int phon_out_ix=0;
int stress;
int ix;
unsigned int len;
int phon_out_ix=0;
int stress;
int c;
char *p;
char *buf;
@@ -719,7 +719,7 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)

flags = 0;
count = 0;
for(p=phon_buf2; *p != 0;)
for(p=phon_buf2; *p != 0; )
{
p += utf8_in(&c, p);
if(use_tie != 0)
@@ -783,7 +783,7 @@ static int IsLetterGroup(Translator *tr, char *word, int group, int pre)
// match the word against a list of utf-8 strings
char *p;
char *w;
int len=0;
int len=0;

p = tr->letterGroups[group];
if(p == NULL)
@@ -862,7 +862,7 @@ int IsVowel(Translator *tr, int letter)

static int Unpronouncable2(Translator *tr, char *word)
{
int c;
int c;
int end_flags;
char ph_buf[N_WORD_PHONEMES];

@@ -880,16 +880,16 @@ static int Unpronouncable2(Translator *tr, char *word)
int Unpronouncable(Translator *tr, char *word, int posn)
{
/* Determines whether a word in 'unpronouncable', i.e. whether it should
be spoken as individual letters.
be spoken as individual letters.

This function may be language specific. This is a generic version.
*/
This function may be language specific. This is a generic version.
*/

int c;
int c1=0;
int vowel_posn=9;
int index;
int count;
int c;
int c1=0;
int vowel_posn=9;
int index;
int count;
ALPHABET *alphabet;

utf8_in(&c,word);
@@ -913,7 +913,7 @@ int Unpronouncable(Translator *tr, char *word, int posn)

index = 0;
count = 0;
for(;;)
for(;; )
{
index += utf8_in(&c,&word[index]);
if((c==0) || (c==' '))
@@ -1093,17 +1093,16 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *


static char stress_phonemes[] = {phonSTRESS_D, phonSTRESS_U, phonSTRESS_2, phonSTRESS_3,
phonSTRESS_P, phonSTRESS_P2, phonSTRESS_TONIC
};
phonSTRESS_P, phonSTRESS_P2, phonSTRESS_TONIC};


void ChangeWordStress(Translator *tr, char *word, int new_stress)
{
int ix;
unsigned char *p;
int max_stress;
int vowel_count; // num of vowels + 1
int stressed_syllable=0; // position of stressed syllable
int max_stress;
int vowel_count; // num of vowels + 1
int stressed_syllable=0; // position of stressed syllable
unsigned char phonetic[N_WORD_PHONEMES];
signed char vowel_stress[N_WORD_PHONEMES/2];

@@ -1158,28 +1157,28 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
'output' is used for input and output

'dictionary_flags' has bits 0-3 position of stressed vowel (if > 0)
or unstressed (if == 7) or syllables 1 and 2 (if == 6)
bits 8... dictionary flags
or unstressed (if == 7) or syllables 1 and 2 (if == 6)
bits 8... dictionary flags

If 'tonic' is set (>= 0), replace highest stress by this value.

control: bit 0 This is an individual symbol, not a word
control: bit 0 This is an individual symbol, not a word
bit 1 Suffix phonemes are still to be added
*/
*/

unsigned char phcode;
unsigned char *p;
PHONEME_TAB *ph;
int stress;
int max_stress;
int max_stress_input; // any stress specified in the input?
int vowel_count; // num of vowels + 1
int ix;
int v;
int v_stress;
int stressed_syllable; // position of stressed syllable
int max_stress_posn;
int unstressed_word = 0;
int stress;
int max_stress;
int max_stress_input; // any stress specified in the input?
int vowel_count; // num of vowels + 1
int ix;
int v;
int v_stress;
int stressed_syllable; // position of stressed syllable
int max_stress_posn;
int unstressed_word = 0;
char *max_output;
int final_ph;
int final_ph2;
@@ -1201,11 +1200,11 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,


/* stress numbers STRESS_BASE +
0 diminished, unstressed within a word
1 unstressed, weak
2
3 secondary stress
4 main stress */
0 diminished, unstressed within a word
1 unstressed, weak
2
3 secondary stress
4 main stress */

stressflags = tr->langopts.stress_flags;

@@ -1281,7 +1280,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
// stress on first syllable, unless it is a light syllable followed by a heavy syllable
if((syllable_weight[1] > 0) || (syllable_weight[2] == 0))
break;
// else drop through to case 1
// else drop through to case 1
case 1:
// stress on second syllable
if((stressed_syllable == 0) && (vowel_count > 2))
@@ -1305,7 +1304,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
break;
}
}
// drop through to next case
// drop through to next case
case 2:
// a language with stress on penultimate vowel

@@ -1549,8 +1548,8 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
break;
}

if((stressflags & S_FINAL_VOWEL_UNSTRESSED) && ((control & 2) == 0) && (vowel_count > 2) && (max_stress_input < 3) && (vowel_stress[vowel_count - 1] == 4))
{
if((stressflags & S_FINAL_VOWEL_UNSTRESSED) && ((control & 2) == 0) && (vowel_count > 2) && (max_stress_input < 3) && (vowel_stress[vowel_count - 1] == 4))
{
// Don't allow stress on a word-final vowel
// Only do this if there is no suffix phonemes to be added, and if a stress position was not given explicitly
if(phoneme_tab[final_ph]->type == phVOWEL)
@@ -1558,7 +1557,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
vowel_stress[vowel_count - 1] = 1;
vowel_stress[vowel_count - 2] = 4;
}
}
}

/* now guess the complete stress pattern */
if(max_stress < 4)
@@ -1680,19 +1679,19 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
ph = phoneme_tab[p[0]];
}

if((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL))
{
// word starts with a vowel
if((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL))
{
// word starts with a vowel

if((tr->langopts.vowel_pause & 0x20) && (vowel_stress[1] >= 4))
{
*output++ = phonPAUSE_NOLINK; // not to be replaced by link
}
else
{
*output++ = phonPAUSE_VSHORT; // break, but no pause
}
if((tr->langopts.vowel_pause & 0x20) && (vowel_stress[1] >= 4))
{
*output++ = phonPAUSE_NOLINK; // not to be replaced by link
}
else
{
*output++ = phonPAUSE_VSHORT; // break, but no pause
}
}
}

p = phonetic;
@@ -1800,12 +1799,12 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
void AppendPhonemes(Translator *tr, char *string, int size, const char *ph)
{
/* Add new phoneme string "ph" to "string"
Keeps count of the number of vowel phonemes in the word, and whether these
Keeps count of the number of vowel phonemes in the word, and whether these
can be stressed syllables. These values can be used in translation rules
*/
*/
const char *p;
unsigned char c;
int unstress_mark;
unsigned char c;
int unstress_mark;
int length;

length = strlen(ph) + strlen(string);
@@ -1831,7 +1830,7 @@ void AppendPhonemes(Translator *tr, char *string, int size, const char *ph)
if(phoneme_tab[c]->type == phVOWEL)
{
if(((phoneme_tab[c]->phflags & phUNSTRESSED) == 0) &&
(unstress_mark == 0))
(unstress_mark == 0))
{
tr->word_stressed_count++;
}
@@ -1850,19 +1849,19 @@ void AppendPhonemes(Translator *tr, char *string, int size, const char *ph)
static void MatchRule(Translator *tr, char *word[], char *word_start, int group_length, char *rule, MatchRecord *match_out, int word_flags, int dict_flags)
{
/* Checks a specified word against dictionary rules.
Returns with phoneme code string, or NULL if no match found.
Returns with phoneme code string, or NULL if no match found.

word (indirect) points to current character group within the input word
This is advanced by this procedure as characters are consumed
word (indirect) points to current character group within the input word
This is advanced by this procedure as characters are consumed

group: the initial characters used to choose the rules group
group: the initial characters used to choose the rules group

rule: address of dictionary rule data for this character group
rule: address of dictionary rule data for this character group

match_out: returns best points score
match_out: returns best points score

word_flags: indicates whether this is a retranslation after a suffix has been removed
*/
word_flags: indicates whether this is a retranslation after a suffix has been removed
*/

unsigned char rb; // current instuction from rule
unsigned char letter; // current letter from input word, single byte
@@ -1875,19 +1874,19 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_

char *rule_start; /* start of current match template */
char *p;
int ix;
int match_type; /* left, right, or consume */
int failed;
int unpron_ignore;
int consumed; /* number of letters consumed from input */
int syllable_count;
int vowel;
int letter_group;
int distance_right;
int distance_left;
int lg_pts;
int n_bytes;
int ix;
int match_type; /* left, right, or consume */
int failed;
int unpron_ignore;
int consumed; /* number of letters consumed from input */
int syllable_count;
int vowel;
int letter_group;
int distance_right;
int distance_left;
int lg_pts;
int n_bytes;
int add_points;
int command;
int check_atstart;
@@ -1896,7 +1895,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
MatchRecord match;
static MatchRecord best;

int total_consumed; /* letters consumed for best match */
int total_consumed; /* letters consumed for best match */

unsigned char condition_num;
char *common_phonemes; /* common to a group of entries */
@@ -2268,7 +2267,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
end_type = (rule[0] << 16) + ((rule[1] & 0x7f) << 8) + (rule[2] & 0x7f);

if((tr->word_vowel_count == 0) && !(end_type & SUFX_P) && (tr->langopts.param[LOPT_SUFFIX] & 1))
failed = 1; // don't match a suffix rule if there are no previous syllables (needed for lang=tr).
failed = 1; // don't match a suffix rule if there are no previous syllables (needed for lang=tr).
else
{
match.end_type = end_type;
@@ -2551,22 +2550,22 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
/* Translate a word bounded by space characters
Append the result to 'phonemes' and any standard prefix/suffix in 'end_phonemes' */

unsigned char c, c2;
unsigned int c12;
unsigned char c, c2;
unsigned int c12;
int wc=0;
int wc_bytes;
char *p2; /* copy of p for use in double letter chain match */
int found;
int g; /* group chain number */
int g1; /* first group for this letter */
int n;
int letter;
int any_alpha=0;
int ix;
unsigned int digit_count=0;
int found;
int g; /* group chain number */
int g1; /* first group for this letter */
int n;
int letter;
int any_alpha=0;
int ix;
unsigned int digit_count=0;
char *p;
ALPHABET *alphabet;
int dict_flags0=0;
int dict_flags0=0;
MatchRecord match1;
MatchRecord match2;
char ph_buf[40];
@@ -2579,7 +2578,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
if(dict_flags != NULL)
dict_flags0 = dict_flags[0];

for(ix=0; ix<(N_WORD_BYTES-1);)
for(ix=0; ix<(N_WORD_BYTES-1); )
{
c = p_start[ix];
word_copy[ix++] = c;
@@ -2592,7 +2591,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
if((option_phonemes & espeakPHONEMES_TRACE) && ((word_flags & FLAG_NO_TRACE)==0))
{
char wordbuf[120];
unsigned int ix;
unsigned int ix;

for(ix=0; ((c = p_start[ix]) != ' ') && (c != 0) && (ix < (sizeof(wordbuf)-1)); ix++)
{
@@ -2814,7 +2813,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c

if((option_phonemes & espeakPHONEMES_TRACE) && ((word_flags & FLAG_NO_TRACE)==0))
{
fprintf(f_trans,"\n");
fprintf(f_trans,"\n");
}

match1.end_type &= ~SUFX_UNPRON;
@@ -3005,30 +3004,30 @@ int TransposeAlphabet(Translator *tr, char *text)
/* Find an entry in the word_dict file for a specified word.
Returns NULL if no match, else returns 'word_end'

word zero terminated word to match
word2 pointer to next word(s) in the input text (terminated by space)
word zero terminated word to match
word2 pointer to next word(s) in the input text (terminated by space)

flags: returns dictionary flags which are associated with a matched word
flags: returns dictionary flags which are associated with a matched word

end_flags: indicates whether this is a retranslation after removing a suffix
*/
end_flags: indicates whether this is a retranslation after removing a suffix
*/
static const char *LookupDict2(Translator *tr, const char *word, const char *word2,
char *phonetic, unsigned int *flags, int end_flags, WORD_TAB *wtab)
char *phonetic, unsigned int *flags, int end_flags, WORD_TAB *wtab)
{
char *p;
char *next;
int hash;
int phoneme_len;
int wlen;
int hash;
int phoneme_len;
int wlen;
unsigned char flag;
unsigned int dictionary_flags;
unsigned int dictionary_flags2;
int condition_failed=0;
int n_chars;
int no_phonemes;
int skipwords;
int ix;
int c;
unsigned int dictionary_flags;
unsigned int dictionary_flags2;
int condition_failed=0;
int n_chars;
int no_phonemes;
int skipwords;
int ix;
int c;
const char *word_end;
const char *word1;
int wflags = 0;
@@ -3261,7 +3260,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
else
{
/* don't use the 'verb' pronunciation unless we are
expecting a verb */
expecting a verb */
continue;
}
}
@@ -3270,7 +3269,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
if(!tr->expect_past)
{
/* don't use the 'past' pronunciation unless we are
expecting past tense */
expecting past tense */
continue;
}
}
@@ -3279,7 +3278,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
if((!tr->expect_noun) || (end_flags & SUFX_V))
{
/* don't use the 'noun' pronunciation unless we are
expecting a noun */
expecting a noun */
continue;
}
}
@@ -3363,16 +3362,16 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
Returns phonetic data in 'phonetic' and bits in 'flags'

end_flags: indicates if a suffix has been removed
*/
*/
int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *flags, int end_flags, WORD_TAB *wtab)
{
int length;
int length;
const char *found;
const char *word1;
const char *word2;
unsigned char c;
int nbytes;
int len;
int nbytes;
int len;
char word[N_WORD_BYTES];
static char word_replacement[N_WORD_BYTES];

@@ -3567,19 +3566,19 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
{
/* Removes a standard suffix from a word, once it has been indicated by the dictionary rules.
end_type: bits 0-6 number of letters
bits 8-14 suffix flags
bits 8-14 suffix flags

word_copy: make a copy of the original word
This routine is language specific. In English it deals with reversing y->i and e-dropping
that were done when the suffix was added to the original word.
*/
word_copy: make a copy of the original word
This routine is language specific. In English it deals with reversing y->i and e-dropping
that were done when the suffix was added to the original word.
*/

int i;
int i;
char *word_end;
int len_ending;
int end_flags;
const char *p;
int len;
int len;
char ending[50];

// these lists are language specific, but are only relevent if the 'e' suffix flag is used
@@ -3606,7 +3605,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
}

// look for multibyte characters to increase the number of bytes to remove
for(len_ending = i = (end_type & 0x3f); i>0 ; i--) // num.of characters of the suffix
for(len_ending = i = (end_type & 0x3f); i>0; i--) // num.of characters of the suffix
{
word_end--;
while((*word_end & 0xc0) == 0x80)
@@ -3628,8 +3627,8 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
end_flags = (end_type & 0xfff0) | FLAG_SUFX;

/* add an 'e' to the stem if appropriate,
if stem ends in vowel+consonant
or stem ends in 'c' (add 'e' to soften it) */
if stem ends in vowel+consonant
or stem ends in 'c' (add 'e' to soften it) */

if(end_type & SUFX_I)
{

+ 524
- 524
src/libespeak-ng/espeak_command.c
File diff suppressed because it is too large
View File


+ 65
- 65
src/libespeak-ng/espeak_command.h View File

@@ -12,94 +12,94 @@ extern "C"
#endif

typedef enum
{
ET_TEXT,
ET_MARK,
ET_KEY,
ET_CHAR,
ET_PARAMETER,
ET_PUNCTUATION_LIST,
ET_VOICE_NAME,
ET_VOICE_SPEC,
ET_TERMINATED_MSG
} t_espeak_type;

typedef struct
{
unsigned int unique_identifier;
void* text;
size_t size;
unsigned int position;
espeak_POSITION_TYPE position_type;
unsigned int end_position;
unsigned int flags;
void* user_data;
ET_TEXT,
ET_MARK,
ET_KEY,
ET_CHAR,
ET_PARAMETER,
ET_PUNCTUATION_LIST,
ET_VOICE_NAME,
ET_VOICE_SPEC,
ET_TERMINATED_MSG
} t_espeak_type;

typedef struct
{
unsigned int unique_identifier;
void* text;
size_t size;
unsigned int position;
espeak_POSITION_TYPE position_type;
unsigned int end_position;
unsigned int flags;
void* user_data;
} t_espeak_text;

typedef struct
typedef struct
{
unsigned int unique_identifier;
void* text;
size_t size;
const char* index_mark;
unsigned int end_position;
unsigned int flags;
void* user_data;
unsigned int unique_identifier;
void* text;
size_t size;
const char* index_mark;
unsigned int end_position;
unsigned int flags;
void* user_data;
} t_espeak_mark;

typedef struct
typedef struct
{
unsigned int unique_identifier;
void* user_data;
wchar_t character;
wchar_t character;
} t_espeak_character;

typedef struct
typedef struct
{
unsigned int unique_identifier;
void* user_data;
const char* key_name;
const char* key_name;
} t_espeak_key;


typedef struct
typedef struct
{
unsigned int unique_identifier;
void* user_data;
unsigned int unique_identifier;
void* user_data;
} t_espeak_terminated_msg;


typedef struct
typedef struct
{
espeak_PARAMETER parameter;
int value;
int relative;
espeak_PARAMETER parameter;
int value;
int relative;
} t_espeak_parameter;

typedef enum
{
CS_UNDEFINED, // The command has just been created
CS_PENDING, // stored in the fifo
CS_PROCESSED // processed
CS_UNDEFINED, // The command has just been created
CS_PENDING, // stored in the fifo
CS_PROCESSED // processed
} t_command_state;

typedef struct
typedef struct
{
t_espeak_type type;
t_command_state state;
union command
{
t_espeak_text my_text;
t_espeak_mark my_mark;
t_espeak_key my_key;
t_espeak_character my_char;
t_espeak_parameter my_param;
const wchar_t* my_punctuation_list;
const char *my_voice_name;
espeak_VOICE my_voice_spec;
t_espeak_terminated_msg my_terminated_msg;
} u;
t_espeak_type type;
t_command_state state;
union command
{
t_espeak_text my_text;
t_espeak_mark my_mark;
t_espeak_key my_key;
t_espeak_character my_char;
t_espeak_parameter my_param;
const wchar_t* my_punctuation_list;
const char *my_voice_name;
espeak_VOICE my_voice_spec;
t_espeak_terminated_msg my_terminated_msg;
} u;
} t_espeak_command;


@@ -128,12 +128,12 @@ int delete_espeak_command( t_espeak_command* the_command);
void display_espeak_command(t_espeak_command* the_command);


espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size,
unsigned int position, espeak_POSITION_TYPE position_type,
unsigned int end_position, unsigned int flags, void* user_data);
espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size,
const char *index_mark, unsigned int end_position,
unsigned int flags, void* user_data);
espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size,
unsigned int position, espeak_POSITION_TYPE position_type,
unsigned int end_position, unsigned int flags, void* user_data);
espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size,
const char *index_mark, unsigned int end_position,
unsigned int flags, void* user_data);
void sync_espeak_Key(const char *key);
void sync_espeak_Char(wchar_t character);
void sync_espeak_SetPunctuationList(const wchar_t *punctlist);

+ 73
- 74
src/libespeak-ng/event.c View File

@@ -51,15 +51,14 @@ static t_espeak_callback* my_callback = NULL;
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
};
ACTIVITY_TIMEOUT=50, // in ms, check that the stream is active
MAX_ACTIVITY_CHECK=6};


typedef struct t_node
{
void* data;
struct t_node *next;
void* data;
struct t_node *next;
} node;

static node* head=NULL;
@@ -72,40 +71,40 @@ static void* polling_thread(void*);

void event_set_callback(t_espeak_callback* SynthCallback)
{
my_callback = SynthCallback;
my_callback = SynthCallback;
}

void event_init(void)
{
ENTER("event_init");
my_event_is_running=0;
// security
pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
init();
assert(-1 != sem_init(&my_sem_start_is_required, 0, 0));
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;
if (pthread_attr_init (&a_attrib) == 0
&& pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE) == 0)
{
thread_inited = (0 == pthread_create(&my_thread,
&a_attrib,
polling_thread,
(void*)NULL));
}
assert(thread_inited);
pthread_attr_destroy(&a_attrib);
ENTER("event_init");
my_event_is_running=0;
// security
pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
init();
assert(-1 != sem_init(&my_sem_start_is_required, 0, 0));
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;
if (pthread_attr_init (&a_attrib) == 0
&& pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE) == 0)
{
thread_inited = (0 == pthread_create(&my_thread,
&a_attrib,
polling_thread,
(void*)NULL));
}
assert(thread_inited);
pthread_attr_destroy(&a_attrib);
}

static void event_display(espeak_EVENT* event)
{
ENTER("event_display");
ENTER("event_display");

#ifdef DEBUG_ENABLED
if (event==NULL)
@@ -115,16 +114,16 @@ ENTER("event_display");
else
{
static const char* label[] = {
"LIST_TERMINATED",
"WORD",
"SENTENCE",
"MARK",
"PLAY",
"END",
"MSG_TERMINATED",
"PHONEME",
"SAMPLERATE",
"??"
"LIST_TERMINATED",
"WORD",
"SENTENCE",
"MARK",
"PLAY",
"END",
"MSG_TERMINATED",
"PHONEME",
"SAMPLERATE",
"??"
};

SHOW("event_display > event=0x%x\n",event);
@@ -161,7 +160,7 @@ static espeak_EVENT* event_copy (espeak_EVENT* event)
{
a_event->id.name = strdup(event->id.name);
}
break;
break;

default:
break;
@@ -184,7 +183,7 @@ static espeak_EVENT* event_copy (espeak_EVENT* event)

static void event_notify(espeak_EVENT* event)
{
ENTER("event_notify");
ENTER("event_notify");
static unsigned int a_old_uid = 0;

espeak_EVENT events[2];
@@ -223,16 +222,16 @@ ENTER("event_notify");
break;

default:
case espeakEVENT_LIST_TERMINATED:
case espeakEVENT_PLAY:
break;
case espeakEVENT_LIST_TERMINATED:
case espeakEVENT_PLAY:
break;
}
}
}

static int event_delete(espeak_EVENT* event)
{
ENTER("event_delete");
ENTER("event_delete");

event_display(event);

@@ -265,7 +264,7 @@ ENTER("event_delete");

espeak_ERROR event_declare (espeak_EVENT* event)
{
ENTER("event_declare");
ENTER("event_declare");

event_display(event);

@@ -348,7 +347,7 @@ espeak_ERROR event_clear_all ()

static int sleep_until_timeout_or_stop_request(uint32_t time_in_ms)
{
ENTER("sleep_until_timeout_or_stop_request");
ENTER("sleep_until_timeout_or_stop_request");

int a_stop_is_required=0;
struct timespec ts;
@@ -366,18 +365,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",
to.tv_sec, to.tv_nsec,
ts.tv_sec, ts.tv_nsec);
to.tv_sec, to.tv_nsec,
ts.tv_sec, ts.tv_nsec);

while ((err = sem_timedwait(&my_sem_stop_is_required, &ts)) == -1
&& errno == EINTR)
&& 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",
tv.tv_sec, tv.tv_usec*1000);
tv.tv_sec, tv.tv_usec*1000);

if (err == 0)
{
@@ -393,7 +392,7 @@ ENTER("sleep_until_timeout_or_stop_request");

static int get_remaining_time(uint32_t sample, uint32_t* time_in_ms, int* stop_is_required)
{
ENTER("get_remaining_time");
ENTER("get_remaining_time");

int err = 0;
*stop_is_required = 0;
@@ -405,23 +404,23 @@ ENTER("get_remaining_time");

if (err || wave_is_busy(NULL) || (*time_in_ms == 0))
{ // if err, stream not available: quit
// if wave is busy, time_in_ms is known: quit
// if wave is not busy but remaining time == 0, event is reached: quit
break;
}
// if wave is busy, time_in_ms is known: quit
// if wave is not busy but remaining time == 0, event is reached: quit
break;
}

// stream opened but not active
//
// Several possible states:
// * the stream is opened but not yet started:
//
// wait for the start of stream
//
// * some samples have already been played,
// ** the end of stream is reached
// ** or there is an underrun
//
// wait for the close of stream
// stream opened but not active
//
// Several possible states:
// * the stream is opened but not yet started:
//
// wait for the start of stream
//
// * 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);
}
@@ -431,7 +430,7 @@ ENTER("get_remaining_time");

static void* polling_thread(void*p)
{
ENTER("polling_thread");
ENTER("polling_thread");

while(1)
{
@@ -487,8 +486,8 @@ ENTER("polling_thread");
uint32_t time_in_ms = 0;

int err = get_remaining_time((uint32_t)event->sample,
&time_in_ms,
&a_stop_is_required);
&time_in_ms,
&a_stop_is_required);
if (a_stop_is_required > 0)
{
break;
@@ -666,7 +665,7 @@ static void init()

void event_terminate()
{
ENTER("event_terminate");
ENTER("event_terminate");

if (thread_inited)
{

+ 14
- 14
src/libespeak-ng/event.h View File

@@ -1,25 +1,25 @@
#ifndef EVENT_H
#define EVENT_H

/*
Manage events (sentence, word, mark, end,...), is responsible of calling the external
callback as soon as the relevant audio sample is played.
/*
Manage events (sentence, word, mark, end,...), is responsible of calling the external
callback as soon as the relevant audio sample is played.


The audio stream is composed of samples from synthetised messages or audio icons.
Each event is associated to a sample.
The audio stream is composed of samples from synthetised messages or audio icons.
Each event is associated to a sample.

Scenario:
Scenario:

- event_declare is called for each expected event.
- event_declare is called for each expected event.

- A timeout is started for the first pending event.
- A timeout is started for the first pending event.

- When the timeout happens, the synth_callback is called.
- When the timeout happens, the synth_callback is called.

Note: the timeout is checked against the real progress of the audio stream, which depends on pauses or underruns. If the real progress is lower than the expected one, a new timeout starts.
Note: the timeout is checked against the real progress of the audio stream, which depends on pauses or underruns. If the real progress is lower than the expected one, a new timeout starts.

*/
*/

#include "speak_lib.h"

@@ -37,14 +37,14 @@ void event_set_callback(t_espeak_callback* cb);

// Clear any pending event.
//
// Return: EE_OK: operation achieved
// Return: EE_OK: operation achieved
// EE_INTERNAL_ERROR.
espeak_ERROR event_clear_all ();

// Declare a future event
//
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: the event can not be buffered;
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: the event can not be buffered;
// you may try after a while to call the function again.
// EE_INTERNAL_ERROR.
espeak_ERROR event_declare (espeak_EVENT* event);

+ 329
- 330
src/libespeak-ng/fifo.c View File

@@ -59,196 +59,195 @@ static t_espeak_command* pop();
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
MAX_INACTIVITY_CHECK=2
};
INACTIVITY_TIMEOUT=50, // in ms, check that the stream is inactive
MAX_INACTIVITY_CHECK=2};

void fifo_init()
{
ENTER("fifo_init");
// security
pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
init(0);
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;
if (pthread_attr_init (& a_attrib)
|| pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE)
|| pthread_create( &my_thread,
& a_attrib,
say_thread,
(void*)NULL))
{
assert(0);
}
pthread_attr_destroy(&a_attrib);
// leave once the thread is actually started
SHOW_TIME("fifo > wait for my_sem_stop_is_acknowledged\n");
while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
{
continue; // Restart when interrupted by handler
}
SHOW_TIME("fifo > get my_sem_stop_is_acknowledged\n");
ENTER("fifo_init");
// security
pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
init(0);
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;
if (pthread_attr_init (&a_attrib)
|| pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE)
|| pthread_create( &my_thread,
&a_attrib,
say_thread,
(void*)NULL))
{
assert(0);
}
pthread_attr_destroy(&a_attrib);
// leave once the thread is actually started
SHOW_TIME("fifo > wait for my_sem_stop_is_acknowledged\n");
while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
{
continue; // Restart when interrupted by handler
}
SHOW_TIME("fifo > get my_sem_stop_is_acknowledged\n");
}

espeak_ERROR fifo_add_command (t_espeak_command* the_command)
{
ENTER("fifo_add_command");

int a_status = pthread_mutex_lock(&my_mutex);
espeak_ERROR a_error = EE_OK;

if (!a_status)
{
SHOW_TIME("fifo_add_command > locked\n");
a_error = push(the_command);
SHOW_TIME("fifo_add_command > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
}

if (!a_status && !my_command_is_running && (a_error == EE_OK))
{
// 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 > 0)
ENTER("fifo_add_command");

int a_status = pthread_mutex_lock(&my_mutex);
espeak_ERROR a_error = EE_OK;

if (!a_status)
{
SHOW_TIME("fifo_add_command > locked\n");
a_error = push(the_command);
SHOW_TIME("fifo_add_command > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
}

if (!a_status && !my_command_is_running && (a_error == EE_OK))
{
usleep(50000); // TBD: event?
sem_getvalue(&my_sem_start_is_required, &val);
// 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 > 0)
{
usleep(50000); // TBD: event?
sem_getvalue(&my_sem_start_is_required, &val);
}
}
}

if (a_status != 0)
{
a_error = EE_INTERNAL_ERROR;
}
if (a_status != 0)
{
a_error = EE_INTERNAL_ERROR;
}

SHOW_TIME("LEAVE fifo_add_command");
return a_error;
SHOW_TIME("LEAVE fifo_add_command");
return a_error;
}

espeak_ERROR fifo_add_commands (t_espeak_command* command1, t_espeak_command* command2)
{
ENTER("fifo_add_command");
ENTER("fifo_add_command");

int a_status = pthread_mutex_lock(&my_mutex);
espeak_ERROR a_error = EE_OK;
int a_status = pthread_mutex_lock(&my_mutex);
espeak_ERROR a_error = EE_OK;

if (!a_status)
{
SHOW_TIME("fifo_add_commands > locked\n");

if (node_counter+1 >= MAX_NODE_COUNTER)
if (!a_status)
{
SHOW("push > %s\n", "EE_BUFFER_FULL");
a_error = EE_BUFFER_FULL;
SHOW_TIME("fifo_add_commands > locked\n");

if (node_counter+1 >= MAX_NODE_COUNTER)
{
SHOW("push > %s\n", "EE_BUFFER_FULL");
a_error = EE_BUFFER_FULL;
}
else
{
push(command1);
push(command2);
}
SHOW_TIME("fifo_add_command > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
}
else

if (!a_status && !my_command_is_running && (a_error == EE_OK))
{
push(command1);
push(command2);
// 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 > 0)
{
usleep(50000); // TBD: event?
sem_getvalue(&my_sem_start_is_required, &val);
}
}
SHOW_TIME("fifo_add_command > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
}

if (!a_status && !my_command_is_running && (a_error == EE_OK))
{
// 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 > 0)

if (a_status != 0)
{
usleep(50000); // TBD: event?
sem_getvalue(&my_sem_start_is_required, &val);
a_error = EE_INTERNAL_ERROR;
}
}

if (a_status != 0)
{
a_error = EE_INTERNAL_ERROR;
}

SHOW_TIME("LEAVE fifo_add_commands");
return a_error;
SHOW_TIME("LEAVE fifo_add_commands");
return a_error;
}

espeak_ERROR fifo_stop ()
{
ENTER("fifo_stop");

int a_command_is_running = 0;
int a_status = pthread_mutex_lock(&my_mutex);
SHOW_TIME("fifo_stop > locked\n");
if (a_status != 0)
{
return EE_INTERNAL_ERROR;
}

if (my_command_is_running)
{
a_command_is_running = 1;
my_stop_is_required = 1;
SHOW_TIME("fifo_stop > my_stop_is_required = 1\n");
}
SHOW_TIME("fifo_stop > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
if (a_status != 0)
{
return EE_INTERNAL_ERROR;
}

if (a_command_is_running)
{
SHOW_TIME("fifo_stop > wait for my_sem_stop_is_acknowledged\n");
while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
ENTER("fifo_stop");

int a_command_is_running = 0;
int a_status = pthread_mutex_lock(&my_mutex);
SHOW_TIME("fifo_stop > locked\n");
if (a_status != 0)
{
return EE_INTERNAL_ERROR;
}

if (my_command_is_running)
{
continue; // Restart when interrupted by handler
a_command_is_running = 1;
my_stop_is_required = 1;
SHOW_TIME("fifo_stop > my_stop_is_required = 1\n");
}
SHOW_TIME("fifo_stop > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
if (a_status != 0)
{
return EE_INTERNAL_ERROR;
}

if (a_command_is_running)
{
SHOW_TIME("fifo_stop > wait for my_sem_stop_is_acknowledged\n");
while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
{
continue; // Restart when interrupted by handler
}
SHOW_TIME("fifo_stop > get my_sem_stop_is_acknowledged\n");
}
SHOW_TIME("fifo_stop > get my_sem_stop_is_acknowledged\n");
}

SHOW_TIME("fifo_stop > my_stop_is_required = 0\n");
my_stop_is_required = 0;
SHOW_TIME("LEAVE fifo_stop\n");
SHOW_TIME("fifo_stop > my_stop_is_required = 0\n");
my_stop_is_required = 0;
SHOW_TIME("LEAVE fifo_stop\n");

return EE_OK;
return EE_OK;
}

int fifo_is_busy ()
{
SHOW("fifo_is_busy > aResult = %d\n",my_command_is_running);
return my_command_is_running;
SHOW("fifo_is_busy > aResult = %d\n",my_command_is_running);
return my_command_is_running;
}

static int sleep_until_start_request_or_inactivity()
{
SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > ENTER");
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
// for filtering underflow.
//
int i=0;
SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > ENTER");
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
// for filtering underflow.
//
int i=0;
while((i<= MAX_INACTIVITY_CHECK) && !a_start_is_required)
{
if (wave_is_busy( NULL) )
{
i = 0;
}
else
else
{
i++;
}
@@ -268,18 +267,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",
to.tv_sec, to.tv_nsec,
ts.tv_sec, ts.tv_nsec);
to.tv_sec, to.tv_nsec,
ts.tv_sec, ts.tv_nsec);

while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1
&& errno == EINTR)
&& 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,
tv.tv_sec, tv.tv_usec*1000);
tv.tv_sec, tv.tv_usec*1000);

if (err==0)
{
@@ -292,156 +291,156 @@ static int sleep_until_start_request_or_inactivity()

static void close_stream()
{
SHOW_TIME("fifo > close_stream > ENTER\n");
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:
// my_stop_is_required = 1;
// 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);
assert (!a_status);
int a_stop_is_required = my_stop_is_required;
if (!a_stop_is_required)
{
my_command_is_running = 1;
}
a_status = pthread_mutex_unlock(&my_mutex);
int a_status = pthread_mutex_lock(&my_mutex);
assert (!a_status);
int a_stop_is_required = my_stop_is_required;
if (!a_stop_is_required)
{
my_command_is_running = 1;
}
a_status = pthread_mutex_unlock(&my_mutex);

if (!a_stop_is_required)
{
wave_close(NULL);
if (!a_stop_is_required)
{
wave_close(NULL);

int a_status = pthread_mutex_lock(&my_mutex);
assert (!a_status);
my_command_is_running = 0;
int a_status = pthread_mutex_lock(&my_mutex);
assert (!a_status);
my_command_is_running = 0;

a_stop_is_required = my_stop_is_required;
a_status = pthread_mutex_unlock(&my_mutex);
a_stop_is_required = my_stop_is_required;
a_status = pthread_mutex_unlock(&my_mutex);

if (a_stop_is_required)
{
// acknowledge the stop request
SHOW_TIME("fifo > close_stream > post my_sem_stop_is_acknowledged\n");
int a_status = sem_post(&my_sem_stop_is_acknowledged);
assert( a_status != -1);
if (a_stop_is_required)
{
// acknowledge the stop request
SHOW_TIME("fifo > close_stream > post my_sem_stop_is_acknowledged\n");
int a_status = sem_post(&my_sem_stop_is_acknowledged);
assert( a_status != -1);
}
}
}

SHOW_TIME("fifo > close_stream > LEAVE\n");
SHOW_TIME("fifo > close_stream > LEAVE\n");
}

static void* say_thread(void*p)
{
ENTER("say_thread");

SHOW_TIME("say_thread > post my_sem_stop_is_acknowledged\n");

// announce that thread is started
sem_post(&my_sem_stop_is_acknowledged);
ENTER("say_thread");

int look_for_inactivity=0;
SHOW_TIME("say_thread > post my_sem_stop_is_acknowledged\n");

while(1)
{
SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");
// announce that thread is started
sem_post(&my_sem_stop_is_acknowledged);

int a_start_is_required = 0;
if (look_for_inactivity)
{
a_start_is_required = sleep_until_start_request_or_inactivity();
if (!a_start_is_required)
{
close_stream();
}
}
look_for_inactivity = 1;
int look_for_inactivity=0;

if (!a_start_is_required)
while(1)
{
while ((sem_wait(&my_sem_start_is_required) == -1) && errno == EINTR)
{
continue; // Restart when interrupted by handler
}
}
SHOW_TIME("say_thread > get my_sem_start_is_required\n");
SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");

SHOW_TIME("say_thread > my_command_is_running = 1\n");
my_command_is_running = 1;

while( my_command_is_running)
{
SHOW_TIME("say_thread > locking\n");
int a_status = pthread_mutex_lock(&my_mutex);
assert (!a_status);
t_espeak_command* a_command = (t_espeak_command*)pop();

if (a_command == NULL)
{
SHOW_TIME("say_thread > text empty (talking=0) \n");
a_status = pthread_mutex_unlock(&my_mutex);
SHOW_TIME("say_thread > unlocked\n");
SHOW_TIME("say_thread > my_command_is_running = 0\n");
my_command_is_running = 0;
}
else
{
display_espeak_command(a_command);
// purge start semaphore
SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
while(0 == sem_trywait(&my_sem_start_is_required))
int a_start_is_required = 0;
if (look_for_inactivity)
{
};
a_start_is_required = sleep_until_start_request_or_inactivity();
if (!a_start_is_required)
{
close_stream();
}
}
look_for_inactivity = 1;

if (my_stop_is_required)
if (!a_start_is_required)
{
SHOW_TIME("say_thread > my_command_is_running = 0\n");
my_command_is_running = 0;
while ((sem_wait(&my_sem_start_is_required) == -1) && errno == EINTR)
{
continue; // Restart when interrupted by handler
}
}
SHOW_TIME("say_thread > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);
SHOW_TIME("say_thread > get my_sem_start_is_required\n");

SHOW_TIME("say_thread > my_command_is_running = 1\n");
my_command_is_running = 1;

if (my_command_is_running)
while( my_command_is_running)
{
process_espeak_command(a_command);
SHOW_TIME("say_thread > locking\n");
int a_status = pthread_mutex_lock(&my_mutex);
assert (!a_status);
t_espeak_command* a_command = (t_espeak_command*)pop();

if (a_command == NULL)
{
SHOW_TIME("say_thread > text empty (talking=0) \n");
a_status = pthread_mutex_unlock(&my_mutex);
SHOW_TIME("say_thread > unlocked\n");
SHOW_TIME("say_thread > my_command_is_running = 0\n");
my_command_is_running = 0;
}
else
{
display_espeak_command(a_command);
// purge start semaphore
SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
while(0 == sem_trywait(&my_sem_start_is_required))
{
};

if (my_stop_is_required)
{
SHOW_TIME("say_thread > my_command_is_running = 0\n");
my_command_is_running = 0;
}
SHOW_TIME("say_thread > unlocking\n");
a_status = pthread_mutex_unlock(&my_mutex);

if (my_command_is_running)
{
process_espeak_command(a_command);
}
delete_espeak_command(a_command);
}
}
delete_espeak_command(a_command);
}
}

if (my_stop_is_required)
{
// no mutex required since the stop command is synchronous
// and waiting for my_sem_stop_is_acknowledged
init(1);

// purge start semaphore
SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
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);
if (my_stop_is_required)
{
// no mutex required since the stop command is synchronous
// and waiting for my_sem_stop_is_acknowledged
init(1);

// purge start semaphore
SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
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");
}
// and wait for the next start
SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");
}

return NULL;
return NULL;
}

int fifo_is_command_enabled()
{
SHOW("ENTER fifo_is_command_enabled=%d\n",(int)(0 == my_stop_is_required));
return (0 == my_stop_is_required);
SHOW("ENTER fifo_is_command_enabled=%d\n",(int)(0 == my_stop_is_required));
return (0 == my_stop_is_required);
}

typedef struct t_node
{
t_espeak_command* data;
struct t_node *next;
t_espeak_command* data;
struct t_node *next;
} node;

static node* head=NULL;
@@ -449,76 +448,76 @@ static node* tail=NULL;

static espeak_ERROR push(t_espeak_command* the_command)
{
ENTER("fifo > push");
assert((!head && !tail) || (head && tail));
if (the_command == NULL)
{
SHOW("push > command=0x%x\n", NULL);
return EE_INTERNAL_ERROR;
}
if (node_counter >= MAX_NODE_COUNTER)
{
SHOW("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;
tail = n;
}
else
{
tail->next = n;
tail = n;
}
tail->next = NULL;
tail->data = the_command;
node_counter++;
SHOW("push > counter=%d\n",node_counter);
the_command->state = CS_PENDING;
display_espeak_command(the_command);
return EE_OK;
ENTER("fifo > push");
assert((!head && !tail) || (head && tail));
if (the_command == NULL)
{
SHOW("push > command=0x%x\n", NULL);
return EE_INTERNAL_ERROR;
}
if (node_counter >= MAX_NODE_COUNTER)
{
SHOW("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;
tail = n;
}
else
{
tail->next = n;
tail = n;
}
tail->next = NULL;
tail->data = the_command;
node_counter++;
SHOW("push > counter=%d\n",node_counter);
the_command->state = CS_PENDING;
display_espeak_command(the_command);
return EE_OK;
}

static t_espeak_command* pop()
{
ENTER("fifo > pop");
t_espeak_command* the_command = NULL;
ENTER("fifo > pop");
t_espeak_command* the_command = NULL;

assert((!head && !tail) || (head && tail));
assert((!head && !tail) || (head && tail));

if (head != NULL)
{
node* n = head;
the_command = n->data;
head = n->next;
free(n);
node_counter--;
SHOW("pop > command=0x%x (counter=%d)\n",the_command, node_counter);
}
if (head != NULL)
{
node* n = head;
the_command = n->data;
head = n->next;
free(n);
node_counter--;
SHOW("pop > command=0x%x (counter=%d)\n",the_command, node_counter);
}

if(head == NULL)
{
tail = NULL;
}
if(head == NULL)
{
tail = NULL;
}

display_espeak_command(the_command);
display_espeak_command(the_command);

return the_command;
return the_command;
}

static void init(int process_parameters)
@@ -539,13 +538,13 @@ static void init(int process_parameters)

void fifo_terminate()
{
ENTER("fifo_terminate");
ENTER("fifo_terminate");

pthread_cancel(my_thread);
pthread_join(my_thread,NULL);
pthread_mutex_destroy(&my_mutex);
sem_destroy(&my_sem_start_is_required);
sem_destroy(&my_sem_stop_is_acknowledged);
pthread_cancel(my_thread);
pthread_join(my_thread,NULL);
pthread_mutex_destroy(&my_mutex);
sem_destroy(&my_sem_start_is_required);
sem_destroy(&my_sem_stop_is_acknowledged);

init(0); // purge fifo
init(0); // purge fifo
}

+ 10
- 10
src/libespeak-ng/fifo.h View File

@@ -1,7 +1,7 @@
#ifndef FIFO_H
#define FIFO_H

// Helps to add espeak commands in a first-in first-out queue
// Helps to add espeak commands in a first-in first-out queue
// and run them asynchronously.

#include "espeak_command.h"
@@ -19,10 +19,10 @@ void fifo_init();
// Add an espeak command.
//
// Note: this function fails if too many commands are already buffered.
// In such a case, the calling function could wait and then add again its command.
// In such a case, the calling function could wait and then add again its command.
//
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: the command can not be buffered;
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: the command can not be buffered;
// you may try after a while to call the function again.
// EE_INTERNAL_ERROR.
espeak_ERROR fifo_add_command (t_espeak_command* c);
@@ -30,16 +30,16 @@ espeak_ERROR fifo_add_command (t_espeak_command* c);
// Add two espeak commands in a single transaction.
//
// Note: this function fails if too many commands are already buffered.
// In such a case, the calling function could wait and then add again these commands.
// In such a case, the calling function could wait and then add again these commands.
//
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: at least one command can not be buffered;
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: at least one command can not be buffered;
// you may try after a while to call the function again.
// EE_INTERNAL_ERROR.
espeak_ERROR fifo_add_commands (t_espeak_command* c1, t_espeak_command* c2);

// The current running command must be stopped and the awaiting commands are cleared.
// Return: EE_OK: operation achieved
// Return: EE_OK: operation achieved
// EE_INTERNAL_ERROR.
espeak_ERROR fifo_stop ();

@@ -54,8 +54,8 @@ void fifo_terminate();
// Indicates if the running command is still enabled.
//
// Note: this function is mainly called by the SynthCallback (speak_lib.cpp)
// It indicates if the actual wave sample can still be played. It is helpful for
// stopping speech as soon as a cancel command is applied.
// It indicates if the actual wave sample can still be played. It is helpful for
// stopping speech as soon as a cancel command is applied.
//
// Returns 1 if yes, or 0 otherwise.
int fifo_is_command_enabled();

+ 214
- 202
src/libespeak-ng/intonation.c View File

@@ -33,7 +33,7 @@

/* Note this module is mostly old code that needs to be rewritten to
provide a more flexible intonation system.
*/
*/

// bits in SYLLABLE.flags
#define SYL_RISE 1
@@ -68,125 +68,137 @@ static int tone_pitch_env; /* used to return pitch envelope */

/* 0 fall */
unsigned char env_fall[128] = {
0xff, 0xfd, 0xfa, 0xf8, 0xf6, 0xf4, 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0,
0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xd0, 0xce, 0xcc, 0xca, 0xc8, 0xc6, 0xc4, 0xc2, 0xc0,
0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0, 0xae, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0xa2, 0xa0,
0x9e, 0x9c, 0x9a, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8e, 0x8c, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x80,
0x7e, 0x7c, 0x7a, 0x78, 0x76, 0x74, 0x72, 0x70, 0x6e, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x62, 0x60,
0x5e, 0x5c, 0x5a, 0x58, 0x56, 0x54, 0x52, 0x50, 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x42, 0x40,
0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
0x1e, 0x1c, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x00 };
0xff, 0xfd, 0xfa, 0xf8, 0xf6, 0xf4, 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0,
0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xd0, 0xce, 0xcc, 0xca, 0xc8, 0xc6, 0xc4, 0xc2, 0xc0,
0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0, 0xae, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0xa2, 0xa0,
0x9e, 0x9c, 0x9a, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8e, 0x8c, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x80,
0x7e, 0x7c, 0x7a, 0x78, 0x76, 0x74, 0x72, 0x70, 0x6e, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x62, 0x60,
0x5e, 0x5c, 0x5a, 0x58, 0x56, 0x54, 0x52, 0x50, 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x42, 0x40,
0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
0x1e, 0x1c, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x00
};

/* 1 rise */
unsigned char env_rise[128] = {
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfd, 0xff };
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfd, 0xff
};

unsigned char env_frise[128] = {
0xff, 0xf4, 0xea, 0xe0, 0xd6, 0xcc, 0xc3, 0xba, 0xb1, 0xa8, 0x9f, 0x97, 0x8f, 0x87, 0x7f, 0x78,
0x71, 0x6a, 0x63, 0x5c, 0x56, 0x50, 0x4a, 0x44, 0x3f, 0x39, 0x34, 0x2f, 0x2b, 0x26, 0x22, 0x1e,
0x1a, 0x17, 0x13, 0x10, 0x0d, 0x0b, 0x08, 0x06, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x13, 0x15, 0x17,
0x1a, 0x1d, 0x1f, 0x22, 0x25, 0x28, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3b, 0x3d, 0x40,
0x42, 0x45, 0x47, 0x4a, 0x4c, 0x4f, 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x68, 0x6b,
0x6e, 0x71, 0x74, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0,
0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0 };
0xff, 0xf4, 0xea, 0xe0, 0xd6, 0xcc, 0xc3, 0xba, 0xb1, 0xa8, 0x9f, 0x97, 0x8f, 0x87, 0x7f, 0x78,
0x71, 0x6a, 0x63, 0x5c, 0x56, 0x50, 0x4a, 0x44, 0x3f, 0x39, 0x34, 0x2f, 0x2b, 0x26, 0x22, 0x1e,
0x1a, 0x17, 0x13, 0x10, 0x0d, 0x0b, 0x08, 0x06, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x13, 0x15, 0x17,
0x1a, 0x1d, 0x1f, 0x22, 0x25, 0x28, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3b, 0x3d, 0x40,
0x42, 0x45, 0x47, 0x4a, 0x4c, 0x4f, 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x68, 0x6b,
0x6e, 0x71, 0x74, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0,
0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0
};

static unsigned char env_r_frise[128] = {
0xcf, 0xcc, 0xc9, 0xc6, 0xc3, 0xc0, 0xbd, 0xb9, 0xb4, 0xb0, 0xab, 0xa7, 0xa2, 0x9c, 0x97, 0x92,
0x8c, 0x86, 0x81, 0x7b, 0x75, 0x6f, 0x69, 0x63, 0x5d, 0x57, 0x50, 0x4a, 0x44, 0x3e, 0x38, 0x33,
0x2d, 0x27, 0x22, 0x1c, 0x17, 0x12, 0x0d, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x12, 0x14, 0x16,
0x19, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2d, 0x30, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3f, 0x41,
0x43, 0x46, 0x48, 0x4b, 0x4d, 0x50, 0x52, 0x55, 0x58, 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6c,
0x6f, 0x72, 0x75, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0,
0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0 };
0xcf, 0xcc, 0xc9, 0xc6, 0xc3, 0xc0, 0xbd, 0xb9, 0xb4, 0xb0, 0xab, 0xa7, 0xa2, 0x9c, 0x97, 0x92,
0x8c, 0x86, 0x81, 0x7b, 0x75, 0x6f, 0x69, 0x63, 0x5d, 0x57, 0x50, 0x4a, 0x44, 0x3e, 0x38, 0x33,
0x2d, 0x27, 0x22, 0x1c, 0x17, 0x12, 0x0d, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x12, 0x14, 0x16,
0x19, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2d, 0x30, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3f, 0x41,
0x43, 0x46, 0x48, 0x4b, 0x4d, 0x50, 0x52, 0x55, 0x58, 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6c,
0x6f, 0x72, 0x75, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0,
0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0
};

static unsigned char env_frise2[128] = {
0xff, 0xf9, 0xf4, 0xee, 0xe9, 0xe4, 0xdf, 0xda, 0xd5, 0xd0, 0xcb, 0xc6, 0xc1, 0xbd, 0xb8, 0xb3,
0xaf, 0xaa, 0xa6, 0xa1, 0x9d, 0x99, 0x95, 0x90, 0x8c, 0x88, 0x84, 0x80, 0x7d, 0x79, 0x75, 0x71,
0x6e, 0x6a, 0x67, 0x63, 0x60, 0x5d, 0x59, 0x56, 0x53, 0x50, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3e,
0x3c, 0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a,
0x19, 0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05,
0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20 };
0xff, 0xf9, 0xf4, 0xee, 0xe9, 0xe4, 0xdf, 0xda, 0xd5, 0xd0, 0xcb, 0xc6, 0xc1, 0xbd, 0xb8, 0xb3,
0xaf, 0xaa, 0xa6, 0xa1, 0x9d, 0x99, 0x95, 0x90, 0x8c, 0x88, 0x84, 0x80, 0x7d, 0x79, 0x75, 0x71,
0x6e, 0x6a, 0x67, 0x63, 0x60, 0x5d, 0x59, 0x56, 0x53, 0x50, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3e,
0x3c, 0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a,
0x19, 0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05,
0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20
};

static unsigned char env_r_frise2[128] = {
0xd0, 0xce, 0xcd, 0xcc, 0xca, 0xc8, 0xc7, 0xc5, 0xc3, 0xc1, 0xc0, 0xbd, 0xbb, 0xb8, 0xb5, 0xb3,
0xb0, 0xad, 0xaa, 0xa7, 0xa3, 0xa0, 0x9d, 0x99, 0x96, 0x92, 0x8f, 0x8b, 0x87, 0x84, 0x80, 0x7c,
0x78, 0x74, 0x70, 0x6d, 0x69, 0x65, 0x61, 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x4a, 0x46, 0x42, 0x3e,
0x3b, 0x37, 0x34, 0x31, 0x2f, 0x2d, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x19,
0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x05,
0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20 };
0xd0, 0xce, 0xcd, 0xcc, 0xca, 0xc8, 0xc7, 0xc5, 0xc3, 0xc1, 0xc0, 0xbd, 0xbb, 0xb8, 0xb5, 0xb3,
0xb0, 0xad, 0xaa, 0xa7, 0xa3, 0xa0, 0x9d, 0x99, 0x96, 0x92, 0x8f, 0x8b, 0x87, 0x84, 0x80, 0x7c,
0x78, 0x74, 0x70, 0x6d, 0x69, 0x65, 0x61, 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x4a, 0x46, 0x42, 0x3e,
0x3b, 0x37, 0x34, 0x31, 0x2f, 0x2d, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x19,
0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x05,
0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20
};

static unsigned char env_risefall[128] = {
0x98, 0x99, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, 0xa1, 0xa4, 0xa7, 0xa9, 0xac, 0xb0, 0xb3, 0xb6, 0xba,
0xbe, 0xc1, 0xc5, 0xc9, 0xcd, 0xd1, 0xd4, 0xd8, 0xdc, 0xdf, 0xe3, 0xe6, 0xea, 0xed, 0xf0, 0xf2,
0xf5, 0xf7, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd,
0xfb, 0xfa, 0xf8, 0xf6, 0xf3, 0xf1, 0xee, 0xec, 0xe9, 0xe6, 0xe4, 0xe0, 0xdd, 0xda, 0xd7, 0xd3,
0xd0, 0xcc, 0xc8, 0xc4, 0xc0, 0xbc, 0xb8, 0xb4, 0xb0, 0xac, 0xa7, 0xa3, 0x9f, 0x9a, 0x96, 0x91,
0x8d, 0x88, 0x84, 0x7f, 0x7b, 0x76, 0x72, 0x6d, 0x69, 0x65, 0x60, 0x5c, 0x58, 0x54, 0x50, 0x4c,
0x48, 0x44, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2f, 0x2b, 0x28, 0x26, 0x23, 0x20, 0x1d, 0x1a, 0x17,
0x15, 0x12, 0x0f, 0x0d, 0x0a, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
0x98, 0x99, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, 0xa1, 0xa4, 0xa7, 0xa9, 0xac, 0xb0, 0xb3, 0xb6, 0xba,
0xbe, 0xc1, 0xc5, 0xc9, 0xcd, 0xd1, 0xd4, 0xd8, 0xdc, 0xdf, 0xe3, 0xe6, 0xea, 0xed, 0xf0, 0xf2,
0xf5, 0xf7, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd,
0xfb, 0xfa, 0xf8, 0xf6, 0xf3, 0xf1, 0xee, 0xec, 0xe9, 0xe6, 0xe4, 0xe0, 0xdd, 0xda, 0xd7, 0xd3,
0xd0, 0xcc, 0xc8, 0xc4, 0xc0, 0xbc, 0xb8, 0xb4, 0xb0, 0xac, 0xa7, 0xa3, 0x9f, 0x9a, 0x96, 0x91,
0x8d, 0x88, 0x84, 0x7f, 0x7b, 0x76, 0x72, 0x6d, 0x69, 0x65, 0x60, 0x5c, 0x58, 0x54, 0x50, 0x4c,
0x48, 0x44, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2f, 0x2b, 0x28, 0x26, 0x23, 0x20, 0x1d, 0x1a, 0x17,
0x15, 0x12, 0x0f, 0x0d, 0x0a, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};

static unsigned char env_rise2[128] = {
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x06, 0x06,
0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1f, 0x20, 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b,
0x2d, 0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x47, 0x49, 0x4b,
0x4e, 0x50, 0x52, 0x55, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x67, 0x6a, 0x6d, 0x70, 0x73, 0x76,
0x79, 0x7c, 0x7f, 0x82, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96, 0x9a, 0x9d, 0xa0, 0xa3, 0xa6, 0xa9,
0xac, 0xaf, 0xb2, 0xb5, 0xb8, 0xbb, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 0xd0, 0xd3, 0xd6, 0xd9,
0xdc, 0xdf, 0xe2, 0xe4, 0xe7, 0xe9, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfd };
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x06, 0x06,
0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1f, 0x20, 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b,
0x2d, 0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x47, 0x49, 0x4b,
0x4e, 0x50, 0x52, 0x55, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x67, 0x6a, 0x6d, 0x70, 0x73, 0x76,
0x79, 0x7c, 0x7f, 0x82, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96, 0x9a, 0x9d, 0xa0, 0xa3, 0xa6, 0xa9,
0xac, 0xaf, 0xb2, 0xb5, 0xb8, 0xbb, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 0xd0, 0xd3, 0xd6, 0xd9,
0xdc, 0xdf, 0xe2, 0xe4, 0xe7, 0xe9, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfd
};

static unsigned char env_fall2[128] = {
0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6,
0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1, 0xf0, 0xf0, 0xef, 0xee, 0xee, 0xed, 0xec, 0xeb,
0xea, 0xea, 0xe9, 0xe8, 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xde, 0xdd, 0xdc, 0xdb,
0xd9, 0xd8, 0xd6, 0xd5, 0xd3, 0xd2, 0xd0, 0xce, 0xcc, 0xcb, 0xc9, 0xc7, 0xc5, 0xc3, 0xc0, 0xbe,
0xbc, 0xb9, 0xb7, 0xb5, 0xb2, 0xaf, 0xad, 0xaa, 0xa7, 0xa4, 0xa1, 0x9e, 0x9a, 0x97, 0x94, 0x90,
0x8d, 0x89, 0x85, 0x81, 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x68, 0x64, 0x61, 0x5e, 0x5b, 0x57, 0x54,
0x51, 0x4d, 0x4a, 0x46, 0x43, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2e, 0x2a, 0x27, 0x23, 0x1f, 0x1c,
0x18, 0x14, 0x11, 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 };
0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6,
0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1, 0xf0, 0xf0, 0xef, 0xee, 0xee, 0xed, 0xec, 0xeb,
0xea, 0xea, 0xe9, 0xe8, 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xde, 0xdd, 0xdc, 0xdb,
0xd9, 0xd8, 0xd6, 0xd5, 0xd3, 0xd2, 0xd0, 0xce, 0xcc, 0xcb, 0xc9, 0xc7, 0xc5, 0xc3, 0xc0, 0xbe,
0xbc, 0xb9, 0xb7, 0xb5, 0xb2, 0xaf, 0xad, 0xaa, 0xa7, 0xa4, 0xa1, 0x9e, 0x9a, 0x97, 0x94, 0x90,
0x8d, 0x89, 0x85, 0x81, 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x68, 0x64, 0x61, 0x5e, 0x5b, 0x57, 0x54,
0x51, 0x4d, 0x4a, 0x46, 0x43, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2e, 0x2a, 0x27, 0x23, 0x1f, 0x1c,
0x18, 0x14, 0x11, 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
};

static unsigned char env_fallrise3[128] = {
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfc, 0xfa, 0xf8, 0xf6, 0xf4, 0xf1, 0xee, 0xeb,
0xe8, 0xe5, 0xe1, 0xde, 0xda, 0xd6, 0xd2, 0xcd, 0xc9, 0xc4, 0xbf, 0xba, 0xb6, 0xb0, 0xab, 0xa6,
0xa1, 0x9c, 0x96, 0x91, 0x8b, 0x86, 0x80, 0x7b, 0x75, 0x6f, 0x6a, 0x64, 0x5f, 0x59, 0x54, 0x4f,
0x49, 0x44, 0x3f, 0x3a, 0x35, 0x30, 0x2b, 0x26, 0x22, 0x1d, 0x19, 0x15, 0x11, 0x0d, 0x0a, 0x07,
0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x05,
0x07, 0x09, 0x0b, 0x0d, 0x10, 0x12, 0x15, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
0x3a, 0x3e, 0x43, 0x48, 0x4c, 0x51, 0x57, 0x5b, 0x5e, 0x62, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0x74,
0x76, 0x78, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x82, 0x81 };
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfc, 0xfa, 0xf8, 0xf6, 0xf4, 0xf1, 0xee, 0xeb,
0xe8, 0xe5, 0xe1, 0xde, 0xda, 0xd6, 0xd2, 0xcd, 0xc9, 0xc4, 0xbf, 0xba, 0xb6, 0xb0, 0xab, 0xa6,
0xa1, 0x9c, 0x96, 0x91, 0x8b, 0x86, 0x80, 0x7b, 0x75, 0x6f, 0x6a, 0x64, 0x5f, 0x59, 0x54, 0x4f,
0x49, 0x44, 0x3f, 0x3a, 0x35, 0x30, 0x2b, 0x26, 0x22, 0x1d, 0x19, 0x15, 0x11, 0x0d, 0x0a, 0x07,
0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x05,
0x07, 0x09, 0x0b, 0x0d, 0x10, 0x12, 0x15, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
0x3a, 0x3e, 0x43, 0x48, 0x4c, 0x51, 0x57, 0x5b, 0x5e, 0x62, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0x74,
0x76, 0x78, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x82, 0x81
};

static unsigned char env_fallrise4[128] = {
0x72, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x61, 0x5f, 0x5c, 0x5a,
0x57, 0x54, 0x51, 0x4e, 0x4b, 0x48, 0x45, 0x42, 0x3f, 0x3b, 0x38, 0x35, 0x32, 0x2f, 0x2c, 0x29,
0x26, 0x23, 0x20, 0x1d, 0x1b, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06,
0x07, 0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0f, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1d, 0x20,
0x23, 0x26, 0x29, 0x2c, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4c, 0x51, 0x56, 0x5b, 0x60,
0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7f, 0x84, 0x89, 0x8f, 0x95, 0x9b, 0xa1, 0xa7, 0xad, 0xb3, 0xba,
0xc0, 0xc7, 0xce, 0xd5, 0xdc, 0xe3, 0xea, 0xf1, 0xf5, 0xf7, 0xfa, 0xfc, 0xfd, 0xfe, 0xff, 0xff };
0x72, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x61, 0x5f, 0x5c, 0x5a,
0x57, 0x54, 0x51, 0x4e, 0x4b, 0x48, 0x45, 0x42, 0x3f, 0x3b, 0x38, 0x35, 0x32, 0x2f, 0x2c, 0x29,
0x26, 0x23, 0x20, 0x1d, 0x1b, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06,
0x07, 0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0f, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1d, 0x20,
0x23, 0x26, 0x29, 0x2c, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4c, 0x51, 0x56, 0x5b, 0x60,
0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7f, 0x84, 0x89, 0x8f, 0x95, 0x9b, 0xa1, 0xa7, 0xad, 0xb3, 0xba,
0xc0, 0xc7, 0xce, 0xd5, 0xdc, 0xe3, 0xea, 0xf1, 0xf5, 0xf7, 0xfa, 0xfc, 0xfd, 0xfe, 0xff, 0xff
};

static unsigned char env_risefallrise[128] = {
0x7f, 0x7f, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x87, 0x89, 0x8c, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa1,
0xa5, 0xaa, 0xae, 0xb2, 0xb7, 0xbb, 0xc0, 0xc5, 0xc9, 0xcd, 0xd2, 0xd6, 0xda, 0xde, 0xe2, 0xe6,
0xea, 0xed, 0xf0, 0xf3, 0xf5, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xfd, 0xfc, 0xfb, 0xf9,
0xf7, 0xf4, 0xf0, 0xec, 0xe7, 0xe2, 0xdc, 0xd5, 0xce, 0xc6, 0xbd, 0xb4, 0xa9, 0x9e, 0x92, 0x88,
0x82, 0x7d, 0x77, 0x72, 0x6c, 0x66, 0x60, 0x5a, 0x54, 0x4e, 0x49, 0x42, 0x3c, 0x37, 0x32, 0x2d,
0x28, 0x24, 0x1f, 0x1b, 0x18, 0x14, 0x11, 0x0e, 0x0c, 0x09, 0x07, 0x06, 0x05, 0x04, 0x04, 0x04,
0x04, 0x05, 0x06, 0x08, 0x0a, 0x0d, 0x10, 0x14, 0x18, 0x1d, 0x23, 0x29, 0x2f, 0x37, 0x3e, 0x47,
0x50, 0x5a, 0x64, 0x70, 0x7c, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x93 };
0x7f, 0x7f, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x87, 0x89, 0x8c, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa1,
0xa5, 0xaa, 0xae, 0xb2, 0xb7, 0xbb, 0xc0, 0xc5, 0xc9, 0xcd, 0xd2, 0xd6, 0xda, 0xde, 0xe2, 0xe6,
0xea, 0xed, 0xf0, 0xf3, 0xf5, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xfd, 0xfc, 0xfb, 0xf9,
0xf7, 0xf4, 0xf0, 0xec, 0xe7, 0xe2, 0xdc, 0xd5, 0xce, 0xc6, 0xbd, 0xb4, 0xa9, 0x9e, 0x92, 0x88,
0x82, 0x7d, 0x77, 0x72, 0x6c, 0x66, 0x60, 0x5a, 0x54, 0x4e, 0x49, 0x42, 0x3c, 0x37, 0x32, 0x2d,
0x28, 0x24, 0x1f, 0x1b, 0x18, 0x14, 0x11, 0x0e, 0x0c, 0x09, 0x07, 0x06, 0x05, 0x04, 0x04, 0x04,
0x04, 0x05, 0x06, 0x08, 0x0a, 0x0d, 0x10, 0x14, 0x18, 0x1d, 0x23, 0x29, 0x2f, 0x37, 0x3e, 0x47,
0x50, 0x5a, 0x64, 0x70, 0x7c, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x93
};



@@ -203,7 +215,7 @@ unsigned char *envelope_data[N_ENVELOPE_DATA] = {
env_fall2, env_fall2,
env_rise2, env_rise2,
env_risefallrise, env_risefallrise
};
};



@@ -258,36 +270,36 @@ typedef struct {
#define T_EMPH 1

static TONE_HEAD tone_head_table[N_TONE_HEAD_TABLE] = {
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 0 statement
{46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 1 comma
{46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 2 question
{46, 57, 90, 50, drops_0, 3, 9, 5, oflow_emf}, // 3 exclamation
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 4 statement, emphatic
{46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less}, // 5 statement, less intonation
{46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less}, // 6 comma, less intonation
{46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less}, // 7 comma, less intonation, less rise
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 8 pitch raises at end of sentence
{46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 9 comma
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 10 question
{34, 41, 41, 32, drops_0, 3, 7, 5, oflow_less}, // 11 test
{46, 57, 55, 50, drops_0, 3, 7, 5, oflow_less}, // 12 test
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 0 statement
{46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 1 comma
{46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 2 question
{46, 57, 90, 50, drops_0, 3, 9, 5, oflow_emf}, // 3 exclamation
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 4 statement, emphatic
{46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less},// 5 statement, less intonation
{46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less},// 6 comma, less intonation
{46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less},// 7 comma, less intonation, less rise
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 8 pitch raises at end of sentence
{46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 9 comma
{46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 10 question
{34, 41, 41, 32, drops_0, 3, 7, 5, oflow_less}, // 11 test
{46, 57, 55, 50, drops_0, 3, 7, 5, oflow_less}, // 12 test
};

static TONE_NUCLEUS tone_nucleus_table[N_TONE_NUCLEUS_TABLE] = {
{PITCHfall, 64, 8, PITCHfall, 70,18, NULL, 24, 12, 0}, // 0 statement
{PITCHfrise, 80,18, PITCHfrise2, 78,22, NULL, 34, 52, 0}, // 1 comma
{PITCHfrise, 88,22, PITCHfrise2, 82,22, NULL, 34, 64, 0}, // 2 question
{PITCHfall, 92, 8, PITCHfall, 92,80, NULL, 76, 8, T_EMPH}, // 3 exclamation
{PITCHfall, 86, 4, PITCHfall, 94,66, NULL, 34, 10, 0}, // 4 statement, emphatic
{PITCHfall, 62,10, PITCHfall, 62,20, NULL, 28, 16, 0}, // 5 statement, less intonation
{PITCHfrise, 68,18, PITCHfrise2, 68,22, NULL, 30, 44, 0}, // 6 comma, less intonation
{PITCHfrise2, 64,16, PITCHfall, 66,32, NULL, 32, 18, 0}, // 7 comma, less intonation, less rise
{PITCHrise, 68,46, PITCHfall, 42,32, NULL, 46, 58, 0}, // 8 pitch raises at end of sentence
{PITCHfrise, 78,24, PITCHfrise2, 72,22, NULL, 42, 52, 0}, // 9 comma
{PITCHfrise, 88,34, PITCHfall, 64,32, NULL, 46, 82, 0}, // 10 question
{PITCHfall, 56,12, PITCHfall, 56,20, NULL, 24, 12, 0}, // 11 test
{PITCHfall, 70,18, PITCHfall, 70,24, NULL, 32, 20, 0}, // 12 test
{PITCHfall, 64, 8, PITCHfall, 70,18, NULL, 24, 12, 0}, // 0 statement
{PITCHfrise, 80,18, PITCHfrise2, 78,22, NULL, 34, 52, 0}, // 1 comma
{PITCHfrise, 88,22, PITCHfrise2, 82,22, NULL, 34, 64, 0}, // 2 question
{PITCHfall, 92, 8, PITCHfall, 92,80, NULL, 76, 8, T_EMPH}, // 3 exclamation
{PITCHfall, 86, 4, PITCHfall, 94,66, NULL, 34, 10, 0}, // 4 statement, emphatic
{PITCHfall, 62,10, PITCHfall, 62,20, NULL, 28, 16, 0}, // 5 statement, less intonation
{PITCHfrise, 68,18, PITCHfrise2, 68,22, NULL, 30, 44, 0}, // 6 comma, less intonation
{PITCHfrise2, 64,16, PITCHfall, 66,32, NULL, 32, 18, 0}, // 7 comma, less intonation, less rise
{PITCHrise, 68,46, PITCHfall, 42,32, NULL, 46, 58, 0}, // 8 pitch raises at end of sentence
{PITCHfrise, 78,24, PITCHfrise2, 72,22, NULL, 42, 52, 0}, // 9 comma
{PITCHfrise, 88,34, PITCHfall, 64,32, NULL, 46, 82, 0}, // 10 question
{PITCHfall, 56,12, PITCHfall, 56,20, NULL, 24, 12, 0}, // 11 test
{PITCHfall, 70,18, PITCHfall, 70,24, NULL, 32, 20, 0}, // 12 test
};


@@ -315,22 +327,22 @@ TUNE *tunes = NULL;
#define PRIMARY_LAST 7


static int number_pre;
static int number_body;
static int number_tail;
static int last_primary;
static int tone_posn;
static int tone_posn2;
static int no_tonic;
static int number_pre;
static int number_body;
static int number_tail;
static int last_primary;
static int tone_posn;
static int tone_posn2;
static int no_tonic;


static void count_pitch_vowels(int start, int end, int clause_end)
{
int ix;
int stress;
int max_stress = 0;
int max_stress_posn = 0; // last syllable ot the highest stress
int max_stress_posn2 = 0; // penuntimate syllable of the highest stress
int ix;
int stress;
int max_stress = 0;
int max_stress_posn = 0; // last syllable ot the highest stress
int max_stress_posn2 = 0; // penuntimate syllable of the highest stress

number_pre = -1; /* number of vowels before 1st primary stress */
number_body = 0;
@@ -396,8 +408,8 @@ static void count_pitch_vowels(int start, int end, int clause_end)
/* Count number of primary stresses up to tonic syllable or body_reset */
static int count_increments(int ix, int end_ix, int min_stress)
{
int count = 0;
int stress;
int count = 0;
int stress;

while(ix < end_ix)
{
@@ -417,8 +429,8 @@ static int count_increments(int ix, int end_ix, int min_stress)
// Set the pitch of a vowel in syllable_tab
static void set_pitch(SYLLABLE *syl, int base, int drop)
{
int pitch1, pitch2;
int flags = 0;
int pitch1, pitch2;
int flags = 0;

if(base < 0) base = 0;

@@ -457,24 +469,24 @@ static int CountUnstressed(int start, int end, int limit)

static int SetHeadIntonation(TUNE *tune, int syl_ix, int end_ix, int control)
{
int stress;
int stress;
SYLLABLE *syl;
int ix;
int pitch=0;
int increment=0;
int n_steps=0;
int stage; // onset, head, last
int initial;
int overflow_ix=0;
int pitch_range;
int pitch_range_abs;
int ix;
int pitch=0;
int increment=0;
int n_steps=0;
int stage; // onset, head, last
int initial;
int overflow_ix=0;
int pitch_range;
int pitch_range_abs;
int *drops;
int n_unstressed=0;
int unstressed_ix=0;
int unstressed_inc;
int used_onset = 0;
int head_final = end_ix;
int secondary=2; // 2
int n_unstressed=0;
int unstressed_ix=0;
int unstressed_inc;
int used_onset = 0;
int head_final = end_ix;
int secondary=2; // 2

pitch_range = (tune->head_end - tune->head_start) << 8;
pitch_range_abs = abs(pitch_range);
@@ -603,20 +615,20 @@ int secondary=2; // 2


/* Calculate pitches until next RESET or tonic syllable, or end.
Increment pitch if stress is >= min_stress.
Used for tonic segment */
Increment pitch if stress is >= min_stress.
Used for tonic segment */
static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *tn, int min_stress, int continuing)
{
int stress;
int pitch=0;
int increment=0;
int n_primary=0;
int n_steps=0;
int initial;
int overflow=0;
int n_overflow;
int pitch_range;
int pitch_range_abs;
int stress;
int pitch=0;
int increment=0;
int n_primary=0;
int n_steps=0;
int initial;
int overflow=0;
int n_overflow;
int pitch_range;
int pitch_range_abs;
int *drops;
signed char *overflow_tab;
SYLLABLE *syl;
@@ -689,7 +701,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;
}
}

@@ -724,12 +736,12 @@ static void SetPitchGradient(int start_ix, int end_ix, int start_pitch, int end_
// Set a linear pitch change over a number of syllables.
// Used for pre-head, unstressed syllables in the body, and the tail

int ix;
int stress;
int pitch;
int increment;
int n_increments;
int drop;
int ix;
int stress;
int pitch;
int increment;
int n_increments;
int drop;
SYLLABLE *syl;

increment = (end_pitch - start_pitch) << 8;
@@ -775,9 +787,9 @@ static void SetPitchGradient(int start_ix, int end_ix, int start_pitch, int end_
// Calculate pitch values for the vowels in this tone group
static int calc_pitches2(int start, int end, int tune_number)
{
int ix;
int ix;
TUNE *tune;
int drop;
int drop;

tune = &tunes[tune_number];
ix = start;
@@ -833,10 +845,10 @@ static int calc_pitches2(int start, int end, int tune_number)
// Calculate pitch values for the vowels in this tone group
static int calc_pitches(int control, int start, int end, int tune_number)
{
int ix;
int ix;
TONE_HEAD *th;
TONE_NUCLEUS *tn;
int drop;
int drop;
int continuing = 0;

if(control == 0)
@@ -911,11 +923,11 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
{
// clause_tone: 0=. 1=, 2=?, 3=! 4=none
PHONEME_LIST *p;
int ix;
int count_stressed=0;
int final_stressed=0;
int ix;
int count_stressed=0;
int final_stressed=0;

int tone_ph;
int tone_ph;
int pause;
int tone_promoted;
PHONEME_TAB *tph;
@@ -923,10 +935,10 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
PHONEME_TAB *prevw_tph; // remember across word boundary
PHONEME_LIST *prev_p;

int pitch_adjust = 0; // pitch gradient through the clause - inital value
int pitch_decrement = 0; // decrease by this for each stressed syllable
int pitch_low = 0; // until it drops to this
int pitch_high = 0; // then reset to this
int pitch_adjust = 0; // pitch gradient through the clause - inital value
int pitch_decrement = 0; // decrease by this for each stressed syllable
int pitch_low = 0; // until it drops to this
int pitch_high = 0; // then reset to this

// count number of stressed syllables
p = &phoneme_list[0];
@@ -1091,14 +1103,14 @@ void CalcPitches(Translator *tr, int clause_type)
// clause_type: 0=. 1=, 2=?, 3=! 4=none
PHONEME_LIST *p;
SYLLABLE *syl;
int ix;
int x;
int st_ix;
int ix;
int x;
int st_ix;
int n_st;
int option;
int group_tone;
int group_tone_emph;
int group_tone_comma;
int option;
int group_tone;
int group_tone_emph;
int group_tone_comma;
int ph_start=0;
int st_start;
int st_clause_end;
@@ -1290,13 +1302,13 @@ void CalcPitches(Translator *tr, int clause_type)
p->pitch2 = x;
}

if(p->tone_ph)
{
ph = phoneme_tab[p->tone_ph];
x = (p->pitch1 + p->pitch2)/2;
p->pitch2 = x + ph->end_type;
p->pitch1 = x + ph->start_type;
}
if(p->tone_ph)
{
ph = phoneme_tab[p->tone_ph];
x = (p->pitch1 + p->pitch2)/2;
p->pitch2 = x + ph->end_type;
p->pitch1 = x + ph->start_type;
}

if(syl->flags & SYL_EMPHASIS)
{

+ 174
- 173
src/libespeak-ng/klatt.c View File

@@ -64,7 +64,7 @@ static void frame_init (klatt_frame_ptr);
static void setabc (long,long,resonator_ptr);
static void setzeroabc (long,long,resonator_ptr);

static klatt_frame_t kt_frame;
static klatt_frame_t kt_frame;
static klatt_global_t kt_globals;

#define NUMBER_OF_SAMPLES 100
@@ -72,57 +72,57 @@ static klatt_global_t kt_globals;
static int scale_wav_tab[] = {45,38,45,45,55}; // scale output from different voicing sources

// For testing, this can be overwritten in KlattInit()
static short natural_samples2[256]= {
2583, 2516, 2450, 2384, 2319, 2254, 2191, 2127,
2067, 2005, 1946, 1890, 1832, 1779, 1726, 1675,
1626, 1579, 1533, 1491, 1449, 1409, 1372, 1336,
1302, 1271, 1239, 1211, 1184, 1158, 1134, 1111,
1089, 1069, 1049, 1031, 1013, 996, 980, 965,
950, 936, 921, 909, 895, 881, 869, 855,
843, 830, 818, 804, 792, 779, 766, 754,
740, 728, 715, 702, 689, 676, 663, 651,
637, 626, 612, 601, 588, 576, 564, 552,
540, 530, 517, 507, 496, 485, 475, 464,
454, 443, 434, 424, 414, 404, 394, 385,
375, 366, 355, 347, 336, 328, 317, 308,
299, 288, 280, 269, 260, 250, 240, 231,
220, 212, 200, 192, 181, 172, 161, 152,
142, 133, 123, 113, 105, 94, 86, 76,
67, 57, 49, 39, 30, 22, 11, 4,
-5, -14, -23, -32, -41, -50, -60, -69,
-78, -87, -96, -107, -115, -126, -134, -144,
-154, -164, -174, -183, -193, -203, -213, -222,
-233, -242, -252, -262, -271, -281, -291, -301,
-310, -320, -330, -339, -349, -357, -368, -377,
-387, -397, -406, -417, -426, -436, -446, -456,
-467, -477, -487, -499, -509, -521, -532, -543,
-555, -567, -579, -591, -603, -616, -628, -641,
-653, -666, -679, -692, -705, -717, -732, -743,
-758, -769, -783, -795, -808, -820, -834, -845,
-860, -872, -885, -898, -911, -926, -939, -955,
-968, -986, -999, -1018, -1034, -1054, -1072, -1094,
-1115, -1138, -1162, -1188, -1215, -1244, -1274, -1307,
-1340, -1377, -1415, -1453, -1496, -1538, -1584, -1631,
-1680, -1732, -1783, -1839, -1894, -1952, -2010, -2072,
-2133, -2196, -2260, -2325, -2390, -2456, -2522, -2589,
static short natural_samples2[256]= {
2583, 2516, 2450, 2384, 2319, 2254, 2191, 2127,
2067, 2005, 1946, 1890, 1832, 1779, 1726, 1675,
1626, 1579, 1533, 1491, 1449, 1409, 1372, 1336,
1302, 1271, 1239, 1211, 1184, 1158, 1134, 1111,
1089, 1069, 1049, 1031, 1013, 996, 980, 965,
950, 936, 921, 909, 895, 881, 869, 855,
843, 830, 818, 804, 792, 779, 766, 754,
740, 728, 715, 702, 689, 676, 663, 651,
637, 626, 612, 601, 588, 576, 564, 552,
540, 530, 517, 507, 496, 485, 475, 464,
454, 443, 434, 424, 414, 404, 394, 385,
375, 366, 355, 347, 336, 328, 317, 308,
299, 288, 280, 269, 260, 250, 240, 231,
220, 212, 200, 192, 181, 172, 161, 152,
142, 133, 123, 113, 105, 94, 86, 76,
67, 57, 49, 39, 30, 22, 11, 4,
-5, -14, -23, -32, -41, -50, -60, -69,
-78, -87, -96, -107, -115, -126, -134, -144,
-154, -164, -174, -183, -193, -203, -213, -222,
-233, -242, -252, -262, -271, -281, -291, -301,
-310, -320, -330, -339, -349, -357, -368, -377,
-387, -397, -406, -417, -426, -436, -446, -456,
-467, -477, -487, -499, -509, -521, -532, -543,
-555, -567, -579, -591, -603, -616, -628, -641,
-653, -666, -679, -692, -705, -717, -732, -743,
-758, -769, -783, -795, -808, -820, -834, -845,
-860, -872, -885, -898, -911, -926, -939, -955,
-968, -986, -999, -1018, -1034, -1054, -1072, -1094,
-1115, -1138, -1162, -1188, -1215, -1244, -1274, -1307,
-1340, -1377, -1415, -1453, -1496, -1538, -1584, -1631,
-1680, -1732, -1783, -1839, -1894, -1952, -2010, -2072,
-2133, -2196, -2260, -2325, -2390, -2456, -2522, -2589,
};
static short natural_samples[100]=
{
-310,-400,530,356,224,89,23,-10,-58,-16,461,599,536,701,770,
605,497,461,560,404,110,224,131,104,-97,155,278,-154,-1165,
-598,737,125,-592,41,11,-247,-10,65,92,80,-304,71,167,-1,122,
233,161,-43,278,479,485,407,266,650,134,80,236,68,260,269,179,
53,140,275,293,296,104,257,152,311,182,263,245,125,314,140,44,
203,230,-235,-286,23,107,92,-91,38,464,443,176,98,-784,-2449,
-1891,-1045,-1600,-1462,-1384,-1261,-949,-730
};
static short natural_samples[100]=
{
-310,-400,530,356,224,89,23,-10,-58,-16,461,599,536,701,770,
605,497,461,560,404,110,224,131,104,-97,155,278,-154,-1165,
-598,737,125,-592,41,11,-247,-10,65,92,80,-304,71,167,-1,122,
233,161,-43,278,479,485,407,266,650,134,80,236,68,260,269,179,
53,140,275,293,296,104,257,152,311,182,263,245,125,314,140,44,
203,230,-235,-286,23,107,92,-91,38,464,443,176,98,-784,-2449,
-1891,-1045,-1600,-1462,-1384,-1261,-949,-730
};

/*
function RESONATOR
function RESONATOR

This is a generic resonator function. Internal memory for the resonator
is stored in the globals structure.
*/
This is a generic resonator function. Internal memory for the resonator
is stored in the globals structure.
*/

static double resonator(resonator_ptr r, double input)
{
@@ -166,16 +166,16 @@ static double antiresonator2(resonator_ptr r, double input)


/*
function FLUTTER
function FLUTTER

This function adds F0 flutter, as specified in:
This function adds F0 flutter, as specified in:

"Analysis, synthesis and perception of voice quality variations among
female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990.
"Analysis, synthesis and perception of voice quality variations among
female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990.

Flutter is added by applying a quasi-random element constructed from three
slowly varying sine waves.
*/
Flutter is added by applying a quasi-random element constructed from three
slowly varying sine waves.
*/

static void flutter(klatt_frame_ptr frame)
{
@@ -196,11 +196,11 @@ static void flutter(klatt_frame_ptr frame)


/*
function SAMPLED_SOURCE
function SAMPLED_SOURCE

Allows the use of a glottal excitation waveform sampled from a real
voice.
*/
Allows the use of a glottal excitation waveform sampled from a real
voice.
*/

static double sampled_source(int source_num)
{
@@ -253,10 +253,10 @@ static double sampled_source(int source_num)


/*
function PARWAVE
function PARWAVE

Converts synthesis parameters to a waveform.
*/
Converts synthesis parameters to a waveform.
*/


static int parwave(klatt_frame_ptr frame)
@@ -281,14 +281,14 @@ static int parwave(klatt_frame_ptr frame)
flutter(frame); /* add f0 flutter */

#ifdef LOG_FRAMES
if(option_log_frames)
{
FILE *f;
f=fopen("log-klatt","a");
fprintf(f,"%4dhz %2dAV %4d %3d, %4d %3d, %4d %3d, %4d %3d, %4d, %3d, FNZ=%3d TLT=%2d\n",frame->F0hz10,frame->AVdb,
frame->Fhz[1],frame->Bhz[1],frame->Fhz[2],frame->Bhz[2],frame->Fhz[3],frame->Bhz[3],frame->Fhz[4],frame->Bhz[4],frame->Fhz[5],frame->Bhz[5],frame->Fhz[0],frame->TLTdb);
fclose(f);
}
if(option_log_frames)
{
FILE *f;
f=fopen("log-klatt","a");
fprintf(f,"%4dhz %2dAV %4d %3d, %4d %3d, %4d %3d, %4d %3d, %4d, %3d, FNZ=%3d TLT=%2d\n",frame->F0hz10,frame->AVdb,
frame->Fhz[1],frame->Bhz[1],frame->Fhz[2],frame->Bhz[2],frame->Fhz[3],frame->Bhz[3],frame->Fhz[4],frame->Bhz[4],frame->Fhz[5],frame->Bhz[5],frame->Fhz[0],frame->TLTdb);
fclose(f);
}
#endif

/* MAIN LOOP, for each output sample of current frame: */
@@ -299,9 +299,9 @@ if(option_log_frames)
noise = gen_noise(noise);

/*
Amplitude modulate noise (reduce noise amplitude during
second half of glottal period) if voicing simultaneously present.
*/
Amplitude modulate noise (reduce noise amplitude during
second half of glottal period) if voicing simultaneously present.
*/

if (kt_globals.nper > kt_globals.nmod)
{
@@ -312,10 +312,10 @@ if(option_log_frames)
frics = kt_globals.amp_frica * noise;

/*
Compute voicing waveform. Run glottal source simulation at 4
times normal sample rate to minimize quantization noise in
period of female voice.
*/
Compute voicing waveform. Run glottal source simulation at 4
times normal sample rate to minimize quantization noise in
period of female voice.
*/

for (n4=0; n4<4; n4++)
{
@@ -343,9 +343,9 @@ if(option_log_frames)
}

/*
Low-pass filter voicing waveform before downsampling from 4*samrate
to samrate samples/sec. Resonator f=.09*samrate, bw=.06*samrate
*/
Low-pass filter voicing waveform before downsampling from 4*samrate
to samrate samples/sec. Resonator f=.09*samrate, bw=.06*samrate
*/

voice = resonator(&(kt_globals.rsn[RLP]),voice);

@@ -354,18 +354,18 @@ if(option_log_frames)
}

/*
Tilt spectrum of voicing source down by soft low-pass filtering, amount
of tilt determined by TLTdb
*/
Tilt spectrum of voicing source down by soft low-pass filtering, amount
of tilt determined by TLTdb
*/

voice = (voice * kt_globals.onemd) + (vlast * kt_globals.decay);
vlast = voice;

/*
Add breathiness during glottal open phase. Amount of breathiness
determined by parameter Aturb Use nrand rather than noise because
noise is low-passed.
*/
Add breathiness during glottal open phase. Amount of breathiness
determined by parameter Aturb Use nrand rather than noise because
noise is low-passed.
*/


if (kt_globals.nper < kt_globals.nopen)
@@ -384,9 +384,9 @@ if(option_log_frames)
par_glotout += aspiration;

/*
Cascade vocal tract, excited by laryngeal sources.
Nasal antiresonator, then formants FNP, F5, F4, F3, F2, F1
*/
Cascade vocal tract, excited by laryngeal sources.
Nasal antiresonator, then formants FNP, F5, F4, F3, F2, F1
*/

out=0;
if(kt_globals.synthesis_model != ALL_PARALLEL)
@@ -407,11 +407,11 @@ if(option_log_frames)
sourc = par_glotout; /* Source is voicing plus aspiration */

/*
Standard parallel vocal tract Formants F6,F5,F4,F3,F2,
outputs added with alternating sign. Sound source for other
parallel resonators is frication plus first difference of
voicing waveform.
*/
Standard parallel vocal tract Formants F6,F5,F4,F3,F2,
outputs added with alternating sign. Sound source for other
parallel resonators is frication plus first difference of
voicing waveform.
*/

out += resonator(&(kt_globals.rsn[R1p]),sourc);
out += resonator(&(kt_globals.rsn[Rnpp]),sourc);
@@ -429,7 +429,7 @@ if(option_log_frames)
out = outbypas - out;

out = resonator(&(kt_globals.rsn[Rout]),out);
temp = (int)(out * wdata.amplitude * kt_globals.amp_gain0) ; /* Convert back to integer */
temp = (int)(out * wdata.amplitude * kt_globals.amp_gain0); /* Convert back to integer */


// mix with a recorded WAV if required for this phoneme
@@ -539,10 +539,10 @@ void KlattReset(int control)


/*
function FRAME_INIT
function FRAME_INIT

Use parameters from the input frame to set up resonator coefficients.
*/
Use parameters from the input frame to set up resonator coefficients.
*/

static void frame_init(klatt_frame_ptr frame)
{
@@ -618,13 +618,13 @@ static void frame_init(klatt_frame_ptr frame)


/*
function IMPULSIVE_SOURCE
function IMPULSIVE_SOURCE

Generate a low pass filtered train of impulses as an approximation of
a natural excitation waveform. Low-pass filter the differentiated impulse
with a critically-damped second-order filter, time constant proportional
to Kopen.
*/
Generate a low pass filtered train of impulses as an approximation of
a natural excitation waveform. Low-pass filter the differentiated impulse
with a critically-damped second-order filter, time constant proportional
to Kopen.
*/


static double impulsive_source()
@@ -647,11 +647,11 @@ static double impulsive_source()


/*
function NATURAL_SOURCE
function NATURAL_SOURCE

Vwave is the differentiated glottal flow waveform, there is a weak
spectral zero around 800 Hz, magic constants a,b reset pitch synchronously.
*/
Vwave is the differentiated glottal flow waveform, there is a weak
spectral zero around 800 Hz, magic constants a,b reset pitch synchronously.
*/

static double natural_source()
{
@@ -678,36 +678,36 @@ static double natural_source()


/*
function PITCH_SYNC_PAR_RESET
function PITCH_SYNC_PAR_RESET

Reset selected parameters pitch-synchronously.
Reset selected parameters pitch-synchronously.


Constant B0 controls shape of glottal pulse as a function
of desired duration of open phase N0
(Note that N0 is specified in terms of 40,000 samples/sec of speech)
Constant B0 controls shape of glottal pulse as a function
of desired duration of open phase N0
(Note that N0 is specified in terms of 40,000 samples/sec of speech)

Assume voicing waveform V(t) has form: k1 t**2 - k2 t**3
Assume voicing waveform V(t) has form: k1 t**2 - k2 t**3

If the radiation characterivative, a temporal derivative
is folded in, and we go from continuous time to discrete
integers n: dV/dt = vwave[n]
If the radiation characterivative, a temporal derivative
is folded in, and we go from continuous time to discrete
integers n: dV/dt = vwave[n]
= sum over i=1,2,...,n of { a - (i * b) }
= a n - b/2 n**2

where the constants a and b control the detailed shape
and amplitude of the voicing waveform over the open
potion of the voicing cycle "nopen".
where the constants a and b control the detailed shape
and amplitude of the voicing waveform over the open
potion of the voicing cycle "nopen".

Let integral of dV/dt have no net dc flow --> a = (b * nopen) / 3
Let integral of dV/dt have no net dc flow --> a = (b * nopen) / 3

Let maximum of dUg(n)/dn be constant --> b = gain / (nopen * nopen)
meaning as nopen gets bigger, V has bigger peak proportional to n
Let maximum of dUg(n)/dn be constant --> b = gain / (nopen * nopen)
meaning as nopen gets bigger, V has bigger peak proportional to n

Thus, to generate the table below for 40 <= nopen <= 263:
Thus, to generate the table below for 40 <= nopen <= 263:

B0[nopen - 40] = 1920000 / (nopen * nopen)
*/
B0[nopen - 40] = 1920000 / (nopen * nopen)
*/

static void pitch_synch_par_reset(klatt_frame_ptr frame)
{
@@ -791,9 +791,9 @@ static void pitch_synch_par_reset(klatt_frame_ptr frame)
kt_globals.rsn[RGL].a *= temp1 * temp1;

/*
Truncate skewness so as not to exceed duration of closed phase
of glottal period.
*/
Truncate skewness so as not to exceed duration of closed phase
of glottal period.
*/


temp = kt_globals.T0 - kt_globals.nopen;
@@ -807,12 +807,12 @@ static void pitch_synch_par_reset(klatt_frame_ptr frame)
}
else
{
skew = - frame->Kskew;
skew = -frame->Kskew;
}

/* Add skewness to closed portion of voicing period */
kt_globals.T0 = kt_globals.T0 + skew;
skew = - skew;
skew = -skew;
}
else
{
@@ -846,11 +846,11 @@ static void pitch_synch_par_reset(klatt_frame_ptr frame)


/*
function SETABC
function SETABC

Convert formant freqencies and bandwidth into resonator difference
equation constants.
*/
Convert formant freqencies and bandwidth into resonator difference
equation constants.
*/


static void setabc(long int f, long int bw, resonator_ptr rp)
@@ -875,11 +875,11 @@ static void setabc(long int f, long int bw, resonator_ptr rp)


/*
function SETZEROABC
function SETZEROABC

Convert formant freqencies and bandwidth into anti-resonator difference
equation constants.
*/
Convert formant freqencies and bandwidth into anti-resonator difference
equation constants.
*/

static void setzeroabc(long int f, long int bw, resonator_ptr rp)
{
@@ -919,12 +919,12 @@ static void setzeroabc(long int f, long int bw, resonator_ptr rp)


/*
function GEN_NOISE
function GEN_NOISE

Random number generator (return a number between -8191 and +8191)
Noise spectrum is tilted down by soft low-pass filter having a pole near
the origin in the z-plane, i.e. output = input + (0.75 * lastoutput)
*/
Random number generator (return a number between -8191 and +8191)
Noise spectrum is tilted down by soft low-pass filter having a pole near
the origin in the z-plane, i.e. output = input + (0.75 * lastoutput)
*/


static double gen_noise(double noise)
@@ -943,22 +943,22 @@ static double gen_noise(double noise)


/*
function DBTOLIN
function DBTOLIN

Convert from decibels to a linear scale factor
Convert from decibels to a linear scale factor


Conversion table, db to linear, 87 dB --> 32767
Conversion table, db to linear, 87 dB --> 32767
86 dB --> 29491 (1 dB down = 0.5**1/6)
...
81 dB --> 16384 (6 dB down = 0.5)
...
0 dB --> 0

The just noticeable difference for a change in intensity of a vowel
is approximately 1 dB. Thus all amplitudes are quantized to 1 dB
steps.
*/
The just noticeable difference for a change in intensity of a vowel
is approximately 1 dB. Thus all amplitudes are quantized to 1 dB
steps.
*/


static double DBtoLIN(long dB)
@@ -966,14 +966,15 @@ static double DBtoLIN(long dB)
static short amptable[88] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32,
8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32,
35, 40, 45, 51, 57, 64, 71, 80, 90, 101, 114, 128,
142, 159, 179, 202, 227, 256, 284, 318, 359, 405,
455, 512, 568, 638, 719, 881, 911, 1024, 1137, 1276,
1438, 1622, 1823, 2048, 2273, 2552, 2875, 3244, 3645,
4096, 4547, 5104, 5751, 6488, 7291, 8192, 9093, 10207,
11502, 12976, 14582, 16384, 18350, 20644, 23429,
26214, 29491, 32767 };
26214, 29491, 32767
};

if ((dB < 0) || (dB > 87))
{
@@ -1132,7 +1133,7 @@ void SetSynth_Klatt(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v
if(control & 1)
{
end_wave = 1;
for(qix=wcmdq_head+1;;qix++)
for(qix=wcmdq_head+1;; qix++)
{
if(qix >= N_WCMDQ) qix = 0;
if(qix == wcmdq_tail) break;
@@ -1160,27 +1161,27 @@ void SetSynth_Klatt(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v
}

#ifdef LOG_FRAMES
if(option_log_frames)
{
FILE *f_log;
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
{
fprintf(f_log,"K %3dmS %3d %3d %4d %4d %4d %4d (%2d) to %3d %3d %4d %4d %4d %4d (%2d)\n",length*1000/samplerate,
fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr1->klattp[KLATT_AV],
fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr2->klattp[KLATT_AV] );
fclose(f_log);
}
f_log=fopen("log-klatt","a");
if(f_log != NULL)
if(option_log_frames)
{
fprintf(f_log,"K %3dmS %3d %3d %4d %4d (%2d) to %3d %3d %4d %4d (%2d)\n",length*1000/samplerate,
fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->klattp[KLATT_AV],
fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->klattp[KLATT_AV] );
FILE *f_log;
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
{
fprintf(f_log,"K %3dmS %3d %3d %4d %4d %4d %4d (%2d) to %3d %3d %4d %4d %4d %4d (%2d)\n",length*1000/samplerate,
fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr1->klattp[KLATT_AV],
fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr2->klattp[KLATT_AV] );
fclose(f_log);
}
f_log=fopen("log-klatt","a");
if(f_log != NULL)
{
fprintf(f_log,"K %3dmS %3d %3d %4d %4d (%2d) to %3d %3d %4d %4d (%2d)\n",length*1000/samplerate,
fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->klattp[KLATT_AV],
fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->klattp[KLATT_AV] );

fclose(f_log);
fclose(f_log);
}
}
}
#endif

if(control & 1)

+ 34
- 34
src/libespeak-ng/klatt.h View File

@@ -36,37 +36,37 @@ typedef struct

typedef struct
{
flag synthesis_model; /* cascade-parallel or all-parallel */
flag outsl; /* Output waveform selector */
long samrate; /* Number of output samples per second */
long FLPhz ; /* Frequeny of glottal downsample low-pass filter */
long BLPhz ; /* Bandwidth of glottal downsample low-pass filter */
flag glsource; /* Type of glottal source */
int f0_flutter; /* Percentage of f0 flutter 0-100 */
long nspfr; /* number of samples per frame */
long nper; /* Counter for number of samples in a pitch period */
long ns;
long T0; /* Fundamental period in output samples times 4 */
long nopen; /* Number of samples in open phase of period */
long nmod; /* Position in period to begin noise amp. modul */
long nrand; /* Varible used by random number generator */
double pulse_shape_a; /* Makes waveshape of glottal pulse when open */
double pulse_shape_b; /* Makes waveshape of glottal pulse when open */
double minus_pi_t;
double two_pi_t;
double onemd;
double decay;
double amp_bypas; /* AB converted to linear gain */
double amp_voice; /* AVdb converted to linear gain */
double par_amp_voice; /* AVpdb converted to linear gain */
double amp_aspir; /* AP converted to linear gain */
double amp_frica; /* AF converted to linear gain */
double amp_breth; /* ATURB converted to linear gain */
double amp_gain0; /* G0 converted to linear gain */
int num_samples; /* number of glottal samples */
double sample_factor; /* multiplication factor for glottal samples */
short *natural_samples; /* pointer to an array of glottal samples */
long original_f0; /* original value of f0 not modified by flutter */
flag synthesis_model; /* cascade-parallel or all-parallel */
flag outsl; /* Output waveform selector */
long samrate; /* Number of output samples per second */
long FLPhz; /* Frequeny of glottal downsample low-pass filter */
long BLPhz; /* Bandwidth of glottal downsample low-pass filter */
flag glsource; /* Type of glottal source */
int f0_flutter; /* Percentage of f0 flutter 0-100 */
long nspfr; /* number of samples per frame */
long nper; /* Counter for number of samples in a pitch period */
long ns;
long T0; /* Fundamental period in output samples times 4 */
long nopen; /* Number of samples in open phase of period */
long nmod; /* Position in period to begin noise amp. modul */
long nrand; /* Varible used by random number generator */
double pulse_shape_a; /* Makes waveshape of glottal pulse when open */
double pulse_shape_b; /* Makes waveshape of glottal pulse when open */
double minus_pi_t;
double two_pi_t;
double onemd;
double decay;
double amp_bypas; /* AB converted to linear gain */
double amp_voice; /* AVdb converted to linear gain */
double par_amp_voice; /* AVpdb converted to linear gain */
double amp_aspir; /* AP converted to linear gain */
double amp_frica; /* AF converted to linear gain */
double amp_breth; /* ATURB converted to linear gain */
double amp_gain0; /* G0 converted to linear gain */
int num_samples; /* number of glottal samples */
double sample_factor; /* multiplication factor for glottal samples */
short *natural_samples; /* pointer to an array of glottal samples */
long original_f0; /* original value of f0 not modified by flutter */

int fadeout; // set to 64 to cause fadeout over 64 samples
int scale_wav; // depends on the voicing source
@@ -96,8 +96,8 @@ typedef struct
#define RLP 18
#define Rout 19

resonator_t rsn[N_RSN]; // internal storage for resonators
resonator_t rsn_next[N_RSN];
resonator_t rsn[N_RSN]; // internal storage for resonators
resonator_t rsn_next[N_RSN];

} klatt_global_t, *klatt_global_ptr;

@@ -136,7 +136,7 @@ typedef struct
int AVdb_tmp; //copy of AVdb, which is changed within parwave()
int Fhz_next[10]; // Fhz for the next chunk, so we can do interpolation of resonator (a,b,c) parameters
int Bhz_next[10];
} klatt_frame_t, *klatt_frame_ptr;
} klatt_frame_t, *klatt_frame_ptr;


typedef struct {

+ 13
- 13
src/libespeak-ng/mbrowrap.c View File

@@ -151,7 +151,7 @@ static int start_mbrola(const char *voice_path)
dup2(p_stdout[1], 1) == -1 ||
dup2(p_stderr[1], 2) == -1) {
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
"dup2(): %s\n", strerror(errno));
"dup2(): %s\n", strerror(errno));
written = write(p_stderr[1], mbr_errorbuf, strlen(mbr_errorbuf));
(void)written; // suppress 'variable not used' warning
_exit(1);
@@ -166,10 +166,10 @@ static int start_mbrola(const char *voice_path)

snprintf(charbuf, sizeof(charbuf), "%g", mbr_volume);
execlp("mbrola", "mbrola", "-e", "-v", charbuf,
voice_path, "-", "-.wav", (char *)NULL);
voice_path, "-", "-.wav", (char *)NULL);
/* if execution reaches this point then the exec() failed */
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
"mbrola: %s\n", strerror(errno));
"mbrola: %s\n", strerror(errno));
written = write(2, mbr_errorbuf, strlen(mbr_errorbuf));
(void)written; // suppress 'variable not used' warning
_exit(1);
@@ -255,12 +255,12 @@ static int mbrola_died(void)
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
snprintf(msgbuf, sizeof(msgbuf),
"mbrola died by signal %d", sig);
"mbrola died by signal %d", sig);
msg = msgbuf;
} else if (WIFEXITED(status)) {
int exst = WEXITSTATUS(status);
snprintf(msgbuf, sizeof(msgbuf),
"mbrola exited with status %d", exst);
"mbrola exited with status %d", exst);
msg = msgbuf;
} else {
msg = "mbrola died and wait status is weird";
@@ -274,7 +274,7 @@ static int mbrola_died(void)
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "%s", msg);
else
snprintf(mbr_errorbuf + len, sizeof(mbr_errorbuf) - len,
", (%s)", msg);
", (%s)", msg);
return -1;
}

@@ -285,9 +285,9 @@ static int mbrola_has_errors(void)
char *buf_ptr, *lf;

buf_ptr = buffer;
for (;;) {
for (;; ) {
result = read(mbr_error_fd, buf_ptr,
sizeof(buffer) - (buf_ptr - buffer) - 1);
sizeof(buffer) - (buf_ptr - buffer) - 1);
if (result == -1) {
if (errno == EAGAIN)
return 0;
@@ -312,7 +312,7 @@ static int mbrola_has_errors(void)
/* is this the last line? */
if (lf == &buf_ptr[result - 1]) {
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
"%s", buf_ptr);
"%s", buf_ptr);
/* don't consider this fatal at this point */
return 0;
}
@@ -327,7 +327,7 @@ static int send_to_mbrola(const char *cmd)
{
ssize_t result;
int len;
if (!mbr_pid)
return -1;

@@ -345,7 +345,7 @@ static int send_to_mbrola(const char *cmd)
return -1;
}
}
if (result != len) {
struct datablock *data;
data = (struct datablock *)malloc(sizeof(*data) + len - result);
@@ -511,14 +511,14 @@ int init_MBR(const char *voice_path)
return -1;
}
mbr_samplerate = wavhdr[24] + (wavhdr[25]<<8) +
(wavhdr[26]<<16) + (wavhdr[27]<<24);
(wavhdr[26]<<16) + (wavhdr[27]<<24);
//log("mbrowrap: voice samplerate = %d", mbr_samplerate);

/* remember the voice path for setVolumeRatio_MBR() */
if (mbr_voice_path != voice_path) {
free(mbr_voice_path);
mbr_voice_path = strdup(voice_path);
}
}

return 0;
}

+ 2
- 1
src/libespeak-ng/mbrowrap.h View File

@@ -99,7 +99,8 @@ void resetError_MBR(void);
/*
* Tolerance to missing diphones (always active so this is ignored)
*/
static inline void setNoError_MBR(int no_error) { }
static inline void setNoError_MBR(int no_error) {
}

#ifdef __cplusplus
}

+ 80
- 78
src/libespeak-ng/numbers.c View File

@@ -73,7 +73,7 @@ static int number_control;

typedef struct {
const char *name;
int accent_flags; // bit 0, say before the letter name
int accent_flags; // bit 0, say before the letter name
} ACCENTS;

// these are tokens to look up in the *_list file.
@@ -301,7 +301,7 @@ static const unsigned short letter_accents_0e0[] = {

// characters U+0250 to U+029F
static const unsigned short letter_accents_250[] = {
LETTER('a',M_TURNED,0), // U+250
LETTER('a',M_TURNED,0), // U+250
LETTER(L_ALPHA,0,0),
LETTER(L_ALPHA,M_TURNED,0),
LETTER('b',M_IMPLOSIVE,0),
@@ -309,7 +309,7 @@ static const unsigned short letter_accents_250[] = {
LETTER('c',M_CURL,0),
LETTER('d',M_RETROFLEX,0),
LETTER('d',M_IMPLOSIVE,0),
LETTER('e',M_REVERSED,0), // U+258
LETTER('e',M_REVERSED,0), // U+258
0, // schwa
LETTER(L_SCHWA,M_HOOK,0),
0, // open-e
@@ -317,7 +317,7 @@ static const unsigned short letter_accents_250[] = {
LETTER(L_OPEN_E,M_HOOK,M_REVERSED),
0,
LETTER('j',M_BAR,0),
LETTER('g',M_IMPLOSIVE,0), // U+260
LETTER('g',M_IMPLOSIVE,0), // U+260
LETTER('g',0,0),
LETTER('g',M_SMALLCAP,0),
LETTER(L_GAMMA,0,0),
@@ -325,7 +325,7 @@ static const unsigned short letter_accents_250[] = {
LETTER('h',M_TURNED,0),
LETTER('h',M_HOOK,0),
0,
LETTER('i',M_BAR,0), // U+268
LETTER('i',M_BAR,0), // U+268
LETTER(L_IOTA,0,0),
LETTER('i',M_SMALLCAP,0),
LETTER('l',M_TILDE,0),
@@ -341,7 +341,7 @@ static const unsigned short letter_accents_250[] = {
LETTER('o',M_BAR,0),
LIGATURE('o','e',M_SMALLCAP),
0,
LETTER(L_PHI,0,0), // U+278
LETTER(L_PHI,0,0), // U+278
LETTER('r',M_TURNED,0),
LETTER(L_RLONG,M_TURNED,0),
LETTER('r',M_RETROFLEX,M_TURNED),
@@ -349,7 +349,7 @@ static const unsigned short letter_accents_250[] = {
LETTER('r',M_RETROFLEX,0),
0, // r-tap
LETTER(L_RTAP,M_REVERSED,0),
LETTER('r',M_SMALLCAP,0), // U+280
LETTER('r',M_SMALLCAP,0), // U+280
LETTER('r',M_TURNED,M_SMALLCAP),
LETTER('s',M_RETROFLEX,0),
0, // esh
@@ -357,7 +357,7 @@ static const unsigned short letter_accents_250[] = {
LETTER(L_ESH,M_REVERSED,0),
LETTER(L_ESH,M_CURL,0),
LETTER('t',M_TURNED,0),
LETTER('t',M_RETROFLEX,0), // U+288
LETTER('t',M_RETROFLEX,0), // U+288
LETTER('u',M_BAR,0),
LETTER(L_UPSILON,0,0),
LETTER('v',M_HOOK,0),
@@ -365,7 +365,7 @@ static const unsigned short letter_accents_250[] = {
LETTER('w',M_TURNED,0),
LETTER('y',M_TURNED,0),
LETTER('y',M_SMALLCAP,0),
LETTER('z',M_RETROFLEX,0), // U+290
LETTER('z',M_RETROFLEX,0), // U+290
LETTER('z',M_CURL,0),
0, // ezh
LETTER(L_EZH,M_CURL,0),
@@ -588,7 +588,8 @@ static const int number_ranges[] = {
0x660, 0x6f0, // arabic
0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xbe6, 0xc66, 0xce6, 0xd66, // indic
0xe50, 0xed0, 0xf20, 0x1040, 0x1090,
0 }; // these must be in ascending order
0
}; // these must be in ascending order


int NonAsciiNumber(int letter)
@@ -676,7 +677,8 @@ static unsigned short derived_letters[] = {
0x209a, 'p'+L_SUB,
0x209b, 's'+L_SUB,
0x209c, 't'+L_SUB,
0,0};
0,0
};


static const char *hex_letters[] = {"'e:j","b'i:","s'i:","d'i:","'i:","'ef"}; // names, using phonemes available to all languages
@@ -1856,7 +1858,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null

found = 0;
if((ordinal)
&& ((tensunits == 0) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)))
&& ((tensunits == 0) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)))
{
// ordinal number
sprintf(string, "_%dCo", hundreds);
@@ -2060,7 +2062,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
digit_lookup = buf_digit_lookup;
number_control = control;

for(ix=0; IsDigit09(word[ix]); ix++) ;
for(ix=0; IsDigit09(word[ix]); ix++);
n_digits = ix;
value = this_value = atoi(word);

@@ -2241,16 +2243,16 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
}
else

if(speak_missing_thousands == 1)
if(speak_missing_thousands == 1)
{
// speak this thousandplex if there was no word for the previous thousandplex
sprintf(string,"_0M%d",thousandplex+1);
if(Lookup(tr, string, buf1)==0)
{
// speak this thousandplex if there was no word for the previous thousandplex
sprintf(string,"_0M%d",thousandplex+1);
if(Lookup(tr, string, buf1)==0)
{
sprintf(string,"_0M%d",thousandplex);
Lookup(tr, string, ph_append);
}
sprintf(string,"_0M%d",thousandplex);
Lookup(tr, string, ph_append);
}
}

if((ph_append[0] == 0) && (word[n_digits] == '.') && (thousandplex == 0))
{
@@ -2328,69 +2330,69 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
while(IsDigit09(word[n_digits+decimal_count]))
decimal_count++;

max_decimal_count = 2;
switch(decimal_mode = (tr->langopts.numbers & 0xe000))
max_decimal_count = 2;
switch(decimal_mode = (tr->langopts.numbers & 0xe000))
{
case NUM_DFRACTION_4:
max_decimal_count = 5;
case NUM_DFRACTION_2:
// French/Polish decimal fraction
while(word[n_digits] == '0')
{
case NUM_DFRACTION_4:
max_decimal_count = 5;
case NUM_DFRACTION_2:
// French/Polish decimal fraction
while(word[n_digits] == '0')
{
Lookup(tr, "_0", buf1);
strcat(ph_out,buf1);
decimal_count--;
n_digits++;
}
if((decimal_count <= max_decimal_count) && IsDigit09(word[n_digits]))
{
LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
strcat(ph_out,buf1);
n_digits += decimal_count;
}
break;

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_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

if(decimal_mode == NUM_DFRACTION_6)
strcat(ph_out, buf1);
else
strcat(ph_buf, buf1);
}
strcat(ph_out,ph_buf);
Lookup(tr, "_0", buf1);
strcat(ph_out,buf1);
decimal_count--;
n_digits++;
}
if((decimal_count <= max_decimal_count) && IsDigit09(word[n_digits]))
{
LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
strcat(ph_out,buf1);
n_digits += decimal_count;
break;
}
break;

case NUM_DFRACTION_3:
// Romanian decimal fractions
if((decimal_count <= 4) && (word[n_digits] != '0'))
{
LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
strcat(ph_out,buf1);
n_digits += decimal_count;
}
break;
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_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

case NUM_DFRACTION_7:
// alternative form of decimal fraction digits, except the final digit
while(decimal_count-- > 1)
{
sprintf(string,"_%cd", word[n_digits]);
if(Lookup(tr, string, buf1) == 0)
break;
n_digits++;
if(decimal_mode == NUM_DFRACTION_6)
strcat(ph_out, buf1);
}
else
strcat(ph_buf, buf1);
}
strcat(ph_out,ph_buf);
n_digits += decimal_count;
break;

case NUM_DFRACTION_3:
// Romanian decimal fractions
if((decimal_count <= 4) && (word[n_digits] != '0'))
{
LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
strcat(ph_out,buf1);
n_digits += decimal_count;
}
break;

case NUM_DFRACTION_7:
// alternative form of decimal fraction digits, except the final digit
while(decimal_count-- > 1)
{
sprintf(string,"_%cd", word[n_digits]);
if(Lookup(tr, string, buf1) == 0)
break;
n_digits++;
strcat(ph_out, buf1);
}
}

while(IsDigit09(c = word[n_digits]) && (strlen(ph_out) < (N_WORD_PHONEMES - 10)))
{

+ 8
- 8
src/libespeak-ng/phoneme.h View File

@@ -110,15 +110,15 @@ extern const unsigned char pause_phonemes[8]; // 0, vshort, short, pause, long,
// main table of phonemes, index by phoneme number (1-254)

typedef struct {
unsigned int mnemonic; // Up to 4 characters. The first char is in the l.s.byte
unsigned int phflags; // bits 16-19 place of articulation
unsigned int mnemonic; // Up to 4 characters. The first char is in the l.s.byte
unsigned int phflags; // bits 16-19 place of articulation
unsigned short program; // index into phondata file
unsigned char code; // the phoneme number
unsigned char type; // phVOWEL, phPAUSE, phSTOP etc
unsigned char start_type;
unsigned char end_type;
unsigned char std_length; // for vowels, in mS/2; for phSTRESS phonemes, this is the stress/tone type
unsigned char length_mod; // a length_mod group number, used to access length_mod_tab
unsigned char code; // the phoneme number
unsigned char type; // phVOWEL, phPAUSE, phSTOP etc
unsigned char start_type;
unsigned char end_type;
unsigned char std_length; // for vowels, in mS/2; for phSTRESS phonemes, this is the stress/tone type
unsigned char length_mod; // a length_mod group number, used to access length_mod_tab

} PHONEME_TAB;


+ 10
- 10
src/libespeak-ng/phonemelist.c View File

@@ -33,7 +33,7 @@ const unsigned char pause_phonemes[8] = {0, phonPAUSE_VSHORT, phonPAUSE_SHORT, p


extern int n_ph_list2;
extern PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes
extern PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes



@@ -107,9 +107,9 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out)
void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
{

int ix=0;
int j;
int insert_ph = 0;
int ix=0;
int j;
int insert_ph = 0;
PHONEME_LIST *phlist;
PHONEME_TAB *ph;
PHONEME_TAB *next, *next2;
@@ -186,10 +186,10 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
if(plist2[j].phcode == phonSWITCH)
{
if((!(plist2[j].synthflags & SFLAG_EMBEDDED)) && (
(plist2[j].tone_ph == current_phoneme_tab) ||
(plist2[j+1].phcode == phonSWITCH) ||
((plist2[j+1].phcode == phonPAUSE) && (plist2[j+2].phcode == phonSWITCH))
))
(plist2[j].tone_ph == current_phoneme_tab) ||
(plist2[j+1].phcode == phonSWITCH) ||
((plist2[j+1].phcode == phonPAUSE) && (plist2[j+2].phcode == phonSWITCH))
))
{
// delete this phonSWITCH if it's switching to the current phoneme table, or
// delete this phonSWITCH if its followed by another phonSWITCH
@@ -302,7 +302,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)

n_ph_list3 = SubstitutePhonemes(tr,ph_list3) - 2;

for(j=0; (j < n_ph_list3) && (ix < N_PHONEME_LIST-3);)
for(j=0; (j < n_ph_list3) && (ix < N_PHONEME_LIST-3); )
{
if(ph_list3[j].sourceix)
{
@@ -312,7 +312,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
word_stress = 0;

// find the highest stress level in this word
for(nextw=j; nextw < n_ph_list3;)
for(nextw=j; nextw < n_ph_list3; )
{
if(ph_list3[nextw].stresslevel > word_stress)
word_stress = ph_list3[nextw].stresslevel;

+ 213
- 193
src/libespeak-ng/readclause.c View File

@@ -66,103 +66,103 @@ static int ssml_ignore_l_angle = 0;

// punctuations symbols that can end a clause
static const unsigned short punct_chars[] = {',','.','?','!',':',';',
0x00a1, // inverted exclamation
0x00bf, // inverted question
0x2013, // en-dash
0x2014, // em-dash
0x2026, // elipsis
0x037e, // Greek question mark (looks like semicolon)
0x0387, // Greek semicolon, ano teleia
0x0964, // Devanagari Danda (fullstop)
0x0589, // Armenian period
0x055d, // Armenian comma
0x055c, // Armenian exclamation
0x055e, // Armenian question
0x055b, // Armenian emphasis mark
0x060c, // Arabic ,
0x061b, // Arabic ;
0x061f, // Arabic ?
0x06d4, // Arabic .
0x0df4, // Singhalese Kunddaliya
0x0f0d, // Tibet Shad
0x0f0e,
0x1362, // Ethiopic period
0x1363,
0x1364,
0x1365,
0x1366,
0x1367,
0x1368,
0x10fb, // Georgian paragraph
0x3001, // ideograph comma
0x3002, // ideograph period
0xff01, // fullwidth exclamation
0xff0c, // fullwidth comma
0xff0e, // fullwidth period
0xff1a, // fullwidth colon
0xff1b, // fullwidth semicolon
0xff1f, // fullwidth question mark
0};
0x00a1, // inverted exclamation
0x00bf, // inverted question
0x2013, // en-dash
0x2014, // em-dash
0x2026, // elipsis
0x037e, // Greek question mark (looks like semicolon)
0x0387, // Greek semicolon, ano teleia
0x0964, // Devanagari Danda (fullstop)
0x0589, // Armenian period
0x055d, // Armenian comma
0x055c, // Armenian exclamation
0x055e, // Armenian question
0x055b, // Armenian emphasis mark
0x060c, // Arabic ,
0x061b, // Arabic ;
0x061f, // Arabic ?
0x06d4, // Arabic .
0x0df4, // Singhalese Kunddaliya
0x0f0d, // Tibet Shad
0x0f0e,
0x1362, // Ethiopic period
0x1363,
0x1364,
0x1365,
0x1366,
0x1367,
0x1368,
0x10fb, // Georgian paragraph
0x3001, // ideograph comma
0x3002, // ideograph period
0xff01, // fullwidth exclamation
0xff0c, // fullwidth comma
0xff0e, // fullwidth period
0xff1a, // fullwidth colon
0xff1b, // fullwidth semicolon
0xff1f, // fullwidth question mark
0};


// indexed by (entry num. in punct_chars) + 1
// bits 0-7 pause x 10mS, bits 12-14 intonation type, bit 15 don't need following space or bracket
static const unsigned int punct_attributes [] = { 0,
CLAUSE_COMMA, CLAUSE_PERIOD, CLAUSE_QUESTION, CLAUSE_EXCLAMATION, CLAUSE_COLON, CLAUSE_SEMICOLON,
CLAUSE_SEMICOLON | 0x8000, // inverted exclamation
CLAUSE_SEMICOLON | 0x8000, // inverted question
CLAUSE_SEMICOLON, // en-dash
CLAUSE_SEMICOLON, // em-dash
CLAUSE_SEMICOLON | PUNCT_SAY_NAME | 0x8000, // elipsis
CLAUSE_QUESTION, // Greek question mark
CLAUSE_SEMICOLON, // Greek semicolon
CLAUSE_PERIOD | 0x8000, // Devanagari Danda (fullstop)
CLAUSE_PERIOD | 0x8000, // Armenian period
CLAUSE_COMMA, // Armenian comma
CLAUSE_EXCLAMATION | PUNCT_IN_WORD, // Armenian exclamation
CLAUSE_QUESTION | PUNCT_IN_WORD, // Armenian question
CLAUSE_PERIOD | PUNCT_IN_WORD, // Armenian emphasis mark
CLAUSE_COMMA, // Arabic ,
CLAUSE_SEMICOLON, // Arabic ;
CLAUSE_QUESTION, // Arabic question mark
CLAUSE_PERIOD, // Arabic full stop
CLAUSE_PERIOD+0x8000, // Singhalese period
CLAUSE_PERIOD+0x8000, // Tibet period
CLAUSE_PARAGRAPH,
CLAUSE_PERIOD, // Ethiopic period
CLAUSE_COMMA, // Ethiopic comma
CLAUSE_SEMICOLON, // Ethiopic semicolon
CLAUSE_COLON, // Ethiopic colon
CLAUSE_COLON, // Ethiopic preface colon
CLAUSE_QUESTION, // Ethiopic question mark
CLAUSE_PARAGRAPH, // Ethiopic paragraph
CLAUSE_PARAGRAPH, // Georgian paragraph
CLAUSE_COMMA+0x8000, // ideograph comma
CLAUSE_PERIOD+0x8000, // ideograph period
CLAUSE_EXCLAMATION+0x8000, // fullwidth
CLAUSE_COMMA+0x8000,
CLAUSE_PERIOD+0x8000,
CLAUSE_COLON+0x8000,
CLAUSE_SEMICOLON+0x8000,
CLAUSE_QUESTION+0x8000,
CLAUSE_SEMICOLON, // spare
0 };
CLAUSE_COMMA, CLAUSE_PERIOD, CLAUSE_QUESTION, CLAUSE_EXCLAMATION, CLAUSE_COLON, CLAUSE_SEMICOLON,
CLAUSE_SEMICOLON | 0x8000, // inverted exclamation
CLAUSE_SEMICOLON | 0x8000, // inverted question
CLAUSE_SEMICOLON, // en-dash
CLAUSE_SEMICOLON, // em-dash
CLAUSE_SEMICOLON | PUNCT_SAY_NAME | 0x8000, // elipsis
CLAUSE_QUESTION, // Greek question mark
CLAUSE_SEMICOLON, // Greek semicolon
CLAUSE_PERIOD | 0x8000, // Devanagari Danda (fullstop)
CLAUSE_PERIOD | 0x8000, // Armenian period
CLAUSE_COMMA, // Armenian comma
CLAUSE_EXCLAMATION | PUNCT_IN_WORD, // Armenian exclamation
CLAUSE_QUESTION | PUNCT_IN_WORD, // Armenian question
CLAUSE_PERIOD | PUNCT_IN_WORD, // Armenian emphasis mark
CLAUSE_COMMA, // Arabic ,
CLAUSE_SEMICOLON, // Arabic ;
CLAUSE_QUESTION, // Arabic question mark
CLAUSE_PERIOD, // Arabic full stop
CLAUSE_PERIOD+0x8000, // Singhalese period
CLAUSE_PERIOD+0x8000, // Tibet period
CLAUSE_PARAGRAPH,
CLAUSE_PERIOD, // Ethiopic period
CLAUSE_COMMA, // Ethiopic comma
CLAUSE_SEMICOLON, // Ethiopic semicolon
CLAUSE_COLON, // Ethiopic colon
CLAUSE_COLON, // Ethiopic preface colon
CLAUSE_QUESTION, // Ethiopic question mark
CLAUSE_PARAGRAPH, // Ethiopic paragraph
CLAUSE_PARAGRAPH, // Georgian paragraph
CLAUSE_COMMA+0x8000, // ideograph comma
CLAUSE_PERIOD+0x8000, // ideograph period
CLAUSE_EXCLAMATION+0x8000, // fullwidth
CLAUSE_COMMA+0x8000,
CLAUSE_PERIOD+0x8000,
CLAUSE_COLON+0x8000,
CLAUSE_SEMICOLON+0x8000,
CLAUSE_QUESTION+0x8000,
CLAUSE_SEMICOLON, // spare
0 };


// stack for language and voice properties
@@ -193,21 +193,21 @@ static int speech_parameters[N_SPEECH_PARAM]; // current values, from param_
int saved_parameters[N_SPEECH_PARAM]; //Parameters saved on synthesis start

const int param_defaults[N_SPEECH_PARAM] = {
0, // silence (internal use)
175, // rate wpm
100, // volume
50, // pitch
50, // range
0, // punctuation
0, // capital letters
0, // wordgap
0, // options
0, // intonation
0,
0,
0, // emphasis
0, // line length
0, // voice type
0, // silence (internal use)
175, // rate wpm
100, // volume
50, // pitch
50, // range
0, // punctuation
0, // capital letters
0, // wordgap
0, // options
0, // intonation
0,
0,
0, // emphasis
0, // line length
0, // voice type
};


@@ -217,35 +217,36 @@ const int param_defaults[N_SPEECH_PARAM] = {
// 0=not alphabetic, 0xff=lower case, 0xfe=no case, 0xfd=use wchar_tolower
// other=value to add to upper case to convert to lower case
static unsigned char walpha_tab[MAX_WALPHA-0x7f] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 080
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 090
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, // 0a0
0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, // 0b0
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 0c0
32, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 0xff, // 0d0
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0e0
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0f0
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 100
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 110
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 120
0xfd, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xfe, 1, 0xff, 1, 0xff, 1, 0xff, 1, // 130
0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xfe, 1, 0xff, 1, 0xff, 1, 0xff, // 140
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 150
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 160
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xfd, 1, 0xff, 1, 0xff, 1, 0xff, 0xff, // 170
0xff, 210, 1, 0xff, 1, 0xff, 206, 1, 0xff, 205, 205, 1, 0xff, 0xfe, 79, 202, // 180
203, 1, 0xff, 205, 207, 0xff, 211, 209, 1, 0xff, 0xff, 0xfe, 211, 213, 0xff, 214, // 190
1, 0xff, 1, 0xff, 1, 0xff, 218, 1, 0xff, 218, 0xfe, 0xfe, 1, 0xff, 218, 1, // 1a0
0xff, 217, 217, 1, 0xff, 1, 0xff, 219, 1, 0xff, 0xfe, 0xfe, 1, 0xff, 0xfe, 0xff, // 1b0
0xfe, 0xfe, 0xfe, 0xfe, 2, 0xff, 0xff, 2, 0xff, 0xff, 2, 0xff, 0xff, 1, 0xff, 1, // 1c0
0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xff, 1, 0xff, // 1d0
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 1e0
0xfe, 2, 0xff, 0xff, 1, 0xff, 0xfd, 0xfd, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 1f0
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 200
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 210
0xfd, 0xfe, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 220
1, 0xff, 1, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 1, 0xff, 0xfd, 0xfd, 0xfe, // 230
0xfe, 1, 0xff, 0xfd, 69, 71, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff}; // 240
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 080
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 090
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, // 0a0
0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, // 0b0
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,// 0c0
32, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 0xff,// 0d0
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0e0
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,// 0f0
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 100
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 110
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 120
0xfd, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xfe, 1, 0xff, 1, 0xff, 1, 0xff, 1,// 130
0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xfe, 1, 0xff, 1, 0xff, 1, 0xff,// 140
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 150
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 160
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xfd, 1, 0xff, 1, 0xff, 1, 0xff, 0xff, // 170
0xff, 210, 1, 0xff, 1, 0xff, 206, 1, 0xff, 205, 205, 1, 0xff, 0xfe, 79, 202,// 180
203, 1, 0xff, 205, 207, 0xff, 211, 209, 1, 0xff, 0xff, 0xfe, 211, 213, 0xff, 214,// 190
1, 0xff, 1, 0xff, 1, 0xff, 218, 1, 0xff, 218, 0xfe, 0xfe, 1, 0xff, 218, 1, // 1a0
0xff, 217, 217, 1, 0xff, 1, 0xff, 219, 1, 0xff, 0xfe, 0xfe, 1, 0xff, 0xfe, 0xff,// 1b0
0xfe, 0xfe, 0xfe, 0xfe, 2, 0xff, 0xff, 2, 0xff, 0xff, 2, 0xff, 0xff, 1, 0xff, 1,// 1c0
0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 0xff, 1, 0xff,// 1d0
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 1e0
0xfe, 2, 0xff, 0xff, 1, 0xff, 0xfd, 0xfd, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff,// 1f0
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 200
1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, // 210
0xfd, 0xfe, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff,// 220
1, 0xff, 1, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 1, 0xff, 0xfd, 0xfd, 0xfe, // 230
0xfe, 1, 0xff, 0xfd, 69, 71, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff, 1, 0xff
}; // 240

static const short wchar_tolower[] = {
0x130, 0x069,
@@ -257,7 +258,8 @@ static const short wchar_tolower[] = {
0x23d, 0x19a,
0x23e, 0x2c66,
0x243, 0x180,
0,0 };
0,0
};

static const short wchar_toupper[] = {
0x0b5, 0x39c,
@@ -275,7 +277,8 @@ static const short wchar_toupper[] = {
0x1cc, 0x1ca,
0x1dd, 0x18e,
0x1f3, 0x1f1,
0,0 };
0,0
};


#ifdef NEED_WCHAR_FUNCTIONS
@@ -382,13 +385,13 @@ int iswpunct(int c)

const wchar_t *wcschr(const wchar_t *str, int c)
{
while(*str != 0)
{
if(*str == c)
return(str);
str++;
}
return(NULL);
while(*str != 0)
{
if(*str == c)
return(str);
str++;
}
return(NULL);
}

#ifndef WINCE
@@ -407,17 +410,17 @@ const int wcslen(const wchar_t *str)

float wcstod(const wchar_t *str, wchar_t **tailptr)
{
int ix;
char buf[80];
while(isspace(*str)) str++;
for(ix=0; ix<80; ix++)
{
buf[ix] = str[ix];
if(isspace(buf[ix]))
break;
}
*tailptr = (wchar_t *)&str[ix];
return(atof(buf));
int ix;
char buf[80];
while(isspace(*str)) str++;
for(ix=0; ix<80; ix++)
{
buf[ix] = str[ix];
if(isspace(buf[ix]))
break;
}
*tailptr = (wchar_t *)&str[ix];
return(atof(buf));
}
#endif

@@ -700,7 +703,7 @@ static void UngetC(int c)
const char *WordToString2(unsigned int word)
{
// Convert a language mnemonic word into a string
int ix;
int ix;
static char buf[5];
char *p;

@@ -844,7 +847,7 @@ static int LoadSoundFile(const char *fname, int index)
FILE *f;
char *p;
int *ip;
int length;
int length;
char fname_temp[100];
char fname2[sizeof(path_home)+13+40];

@@ -1059,7 +1062,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
else
{
sprintf(buf," %s %d %s",
punctname,punct_count,punctname);
punctname,punct_count,punctname);
}
}
else
@@ -1163,7 +1166,8 @@ static MNEM_TAB ssmltags[] = {
{"strong", HTML_NOSPACE},
{"em", HTML_NOSPACE},
{"code", HTML_NOSPACE},
{NULL,0}};
{NULL,0}
};



@@ -1311,7 +1315,7 @@ static void ProcessParamStack(char *outbuf, int *outix)

static PARAM_STACK *PushParamStack(int tag_type)
{
int ix;
int ix;
PARAM_STACK *sp;

sp = &param_stack[n_param_stack];
@@ -1389,7 +1393,7 @@ static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name)

static int attrcmp(const wchar_t *string1, const char *string2)
{
int ix;
int ix;

if(string1 == NULL)
return(1);
@@ -1602,7 +1606,8 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type)
{"male", 1},
{"female", 2},
{"neutral", 3},
{NULL, 0}};
{NULL, 0}
};

if(tag_type & SSML_CLOSE)
{
@@ -1673,7 +1678,8 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
{"medium",100},
{"loud",150},
{"x-loud",230},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_rate[] = {
{"default",100},
@@ -1682,7 +1688,8 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
{"medium",100},
{"fast",125},
{"x-fast",160},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_pitch[] = {
{"default",100},
@@ -1691,7 +1698,8 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
{"medium",100},
{"high",110},
{"x-high",120},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_range[] = {
{"default",100},
@@ -1700,10 +1708,12 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
{"medium",100},
{"high",140},
{"x-high",180},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB *mnem_tabs[5] = {
NULL, mnem_rate, mnem_volume, mnem_pitch, mnem_range };
NULL, mnem_rate, mnem_volume, mnem_pitch, mnem_range
};


if((value = attrlookup(attr1,mnem_tabs[param_type])) >= 0)
@@ -1736,11 +1746,12 @@ 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[] = {
{"space ",0xe020},
{"tab ", 0xe009},
{"underscore ", 0xe05f},
{"double-quote ", '"'},
{NULL, 0}};
{"space ",0xe020},
{"tab ", 0xe009},
{"underscore ", 0xe05f},
{"double-quote ", '"'},
{NULL, 0}
};

int ix;
int letter;
@@ -1785,20 +1796,23 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outb

static const MNEM_TAB mnem_phoneme_alphabet[] = {
{"espeak",1},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_punct[] = {
{"none", 1},
{"all", 2},
{"some", 3},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_capitals[] = {
{"no", 0},
{"spelling", 2},
{"icon", 1},
{"pitch", 20}, // this is the amount by which to raise the pitch
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_interpret_as[] = {
{"characters",SAYAS_CHARS},
@@ -1806,11 +1820,13 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outb
{"tts:key",SAYAS_KEY},
{"tts:digits",SAYAS_DIGITS},
{"telephone",SAYAS_DIGITS1},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_sayas_format[] = {
{"glyphs",1},
{NULL, -1}};
{NULL, -1}
};

static const MNEM_TAB mnem_break[] = {
{"none",0},
@@ -1819,7 +1835,8 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outb
{"medium",3},
{"strong",4},
{"x-strong",5},
{NULL,-1}};
{NULL,-1}
};

static const MNEM_TAB mnem_emphasis[] = {
{"none",1},
@@ -1827,10 +1844,12 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outb
{"moderate",3},
{"strong",4},
{"x-strong",5},
{NULL,-1}};
{NULL,-1}
};

static const char *prosody_attr[5] = {
NULL, "rate", "volume", "pitch", "range" };
NULL, "rate", "volume", "pitch", "range"
};

for(ix=0; ix<(sizeof(tag_name)-1); ix++)
{
@@ -2162,7 +2181,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outb
n_ssml_stack--;
}

terminator=0; // ?? Sentence intonation, but no pause ??
terminator=0; // ?? Sentence intonation, but no pause ??
return(terminator + GetVoiceAttributes(px, tag_type));

case HTML_BREAK:
@@ -2232,22 +2251,23 @@ static MNEM_TAB xml_char_mnemonics[] = {
{"quot", '"'},
{"nbsp", ' '},
{"apos", '\''},
{NULL,-1}};
{NULL,-1}
};


int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change)
{
/* Find the end of the current clause.
Write the clause into buf
Write the clause into buf

returns: clause type (bits 0-7: pause x10mS, bits 8-11 intonation type)
returns: clause type (bits 0-7: pause x10mS, bits 8-11 intonation type)

Also checks for blank line (paragraph) as end-of-clause indicator.
Also checks for blank line (paragraph) as end-of-clause indicator.

Does not end clause for:
punctuation immediately followed by alphanumeric eg. 1.23 !Speak :path
repeated punctuation, eg. ... !!!
*/
Does not end clause for:
punctuation immediately followed by alphanumeric eg. 1.23 !Speak :path
repeated punctuation, eg. ... !!!
*/
int c1=' '; // current character
int c2; // next character
int cprev=' '; // previous character
@@ -2291,7 +2311,7 @@ int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix
*tone_type = 0;
*voice_change = 0;

f_input = f_in; // for GetC etc
f_input = f_in; // for GetC etc

if(ungot_word != NULL)
{
@@ -2666,7 +2686,7 @@ f_input = f_in; // for GetC etc
buf[ix+1] = 0;
if(parag > 3)
parag = 3;
if(option_ssml) parag=1;
if(option_ssml) parag=1;
return((CLAUSE_PARAGRAPH-30) + 30*parag); // several blank lines, longer pause
}

@@ -2804,7 +2824,7 @@ if(option_ssml) parag=1;
if(c1 == '.')
{
if((tr->langopts.numbers & NUM_ORDINAL_DOT) &&
(iswdigit(cprev) || (IsRomanU(cprev) && (IsRomanU(cprev2) || iswspace(cprev2))))) // lang=hu
(iswdigit(cprev) || (IsRomanU(cprev) && (IsRomanU(cprev2) || iswspace(cprev2))))) // lang=hu
{
// dot after a number indicates an ordinal number
if(!iswdigit(cprev))

+ 108
- 106
src/libespeak-ng/setlengths.c View File

@@ -37,95 +37,97 @@ extern int saved_parameters[];
// convert from words-per-minute to internal speed factor
// Use this to calibrate speed for wpm 80-350
static unsigned char speed_lookup[] = {
255, 255, 255, 255, 255, // 80
253, 249, 245, 242, 238, // 85
235, 232, 228, 225, 222, // 90
218, 216, 213, 210, 207, // 95
204, 201, 198, 196, 193, // 100
191, 188, 186, 183, 181, // 105
179, 176, 174, 172, 169, // 110
168, 165, 163, 161, 159, // 115
158, 155, 153, 152, 150, // 120
148, 146, 145, 143, 141, // 125
139, 137, 136, 135, 133, // 130
131, 130, 129, 127, 126, // 135
124, 123, 122, 120, 119, // 140
118, 117, 115, 114, 113, // 145
112, 111, 110, 109, 107, // 150
106, 105, 104, 103, 102, // 155
101, 100, 99, 98, 97, // 160
96, 95, 94, 93, 92, // 165
91, 90, 89, 89, 88, // 170
87, 86, 85, 84, 83, // 175
82, 82, 81, 80, 80, // 180
79, 78, 77, 76, 76, // 185
75, 75, 74, 73, 72, // 190
71, 71, 70, 69, 69, // 195
68, 67, 67, 66, 66, // 200
65, 64, 64, 63, 62, // 205
62, 61, 61, 60, 59, // 210
59, 58, 58, 57, 57, // 215
56, 56, 55, 54, 54, // 220
53, 53, 52, 52, 52, // 225
51, 50, 50, 49, 49, // 230
48, 48, 47, 47, 46, // 235
46, 46, 45, 45, 44, // 240
44, 44, 43, 43, 42, // 245
41, 40, 40, 40, 39, // 250
39, 39, 38, 38, 38, // 255
37, 37, 37, 36, 36, // 260
35, 35, 35, 35, 34, // 265
34, 34, 33, 33, 33, // 270
32, 32, 31, 31, 31, // 275
30, 30, 30, 29, 29, // 280
29, 29, 28, 28, 27, // 285
27, 27, 27, 26, 26, // 290
26, 26, 25, 25, 25, // 295
24, 24, 24, 24, 23, // 300
23, 23, 23, 22, 22, // 305
22, 21, 21, 21, 21, // 310
20, 20, 20, 20, 19, // 315
19, 19, 18, 18, 17, // 320
17, 17, 16, 16, 16, // 325
16, 16, 16, 15, 15, // 330
15, 15, 14, 14, 14, // 335
13, 13, 13, 12, 12, // 340
12, 12, 11, 11, 11, // 345
11, 10, 10, 10, 9, // 350
9, 9, 8, 8, 8, // 355
255, 255, 255, 255, 255, // 80
253, 249, 245, 242, 238, // 85
235, 232, 228, 225, 222, // 90
218, 216, 213, 210, 207, // 95
204, 201, 198, 196, 193, // 100
191, 188, 186, 183, 181, // 105
179, 176, 174, 172, 169, // 110
168, 165, 163, 161, 159, // 115
158, 155, 153, 152, 150, // 120
148, 146, 145, 143, 141, // 125
139, 137, 136, 135, 133, // 130
131, 130, 129, 127, 126, // 135
124, 123, 122, 120, 119, // 140
118, 117, 115, 114, 113, // 145
112, 111, 110, 109, 107, // 150
106, 105, 104, 103, 102, // 155
101, 100, 99, 98, 97,// 160
96, 95, 94, 93, 92, // 165
91, 90, 89, 89, 88, // 170
87, 86, 85, 84, 83, // 175
82, 82, 81, 80, 80, // 180
79, 78, 77, 76, 76, // 185
75, 75, 74, 73, 72, // 190
71, 71, 70, 69, 69, // 195
68, 67, 67, 66, 66, // 200
65, 64, 64, 63, 62, // 205
62, 61, 61, 60, 59, // 210
59, 58, 58, 57, 57, // 215
56, 56, 55, 54, 54, // 220
53, 53, 52, 52, 52, // 225
51, 50, 50, 49, 49, // 230
48, 48, 47, 47, 46, // 235
46, 46, 45, 45, 44, // 240
44, 44, 43, 43, 42, // 245
41, 40, 40, 40, 39, // 250
39, 39, 38, 38, 38, // 255
37, 37, 37, 36, 36, // 260
35, 35, 35, 35, 34, // 265
34, 34, 33, 33, 33, // 270
32, 32, 31, 31, 31, // 275
30, 30, 30, 29, 29, // 280
29, 29, 28, 28, 27, // 285
27, 27, 27, 26, 26, // 290
26, 26, 25, 25, 25, // 295
24, 24, 24, 24, 23, // 300
23, 23, 23, 22, 22, // 305
22, 21, 21, 21, 21, // 310
20, 20, 20, 20, 19, // 315
19, 19, 18, 18, 17, // 320
17, 17, 16, 16, 16, // 325
16, 16, 16, 15, 15, // 330
15, 15, 14, 14, 14, // 335
13, 13, 13, 12, 12, // 340
12, 12, 11, 11, 11, // 345
11, 10, 10, 10, 9, // 350
9, 9, 8, 8, 8, // 355
};


// speed_factor1 adjustments for speeds 350 to 374: pauses
static unsigned char pause_factor_350[] = {
22,22,22,22,22,22,22,21,21,21, // 350
21,20,20,19,19,18,17,16,15,15, // 360
15,15,15,15,15}; // 370
22,22,22,22,22,22,22,21,21,21, // 350
21,20,20,19,19,18,17,16,15,15, // 360
15,15,15,15,15
}; // 370

// wav_factor adjustments for speeds 350 to 450
// Use this to calibrate speed for wpm 350-450
static unsigned char wav_factor_350[] = {
120, 121, 120, 119, 119, // 350
118, 118, 117, 116, 116, // 355
115, 114, 113, 112, 112, // 360
111, 111, 110, 109, 108, // 365
107, 106, 106, 104, 103, // 370
103, 102, 102, 102, 101, // 375
101, 99, 98, 98, 97, // 380
96, 96, 95, 94, 93, // 385
91, 90, 91, 90, 89, // 390
88, 86, 85, 86, 85, // 395
85, 84, 82, 81, 80, // 400
79, 77, 78, 78, 76, // 405
77, 75, 75, 74, 73, // 410
71, 72, 70, 69, 69, // 415
69, 67, 65, 64, 63, // 420
63, 63, 61, 61, 59, // 425
59, 59, 58, 56, 57, // 430
58, 56, 54, 53, 52, // 435
52, 53, 52, 52, 50, // 440
48, 47, 47, 45, 46, // 445
45}; // 450
120, 121, 120, 119, 119, // 350
118, 118, 117, 116, 116, // 355
115, 114, 113, 112, 112, // 360
111, 111, 110, 109, 108, // 365
107, 106, 106, 104, 103, // 370
103, 102, 102, 102, 101, // 375
101, 99, 98, 98, 97,// 380
96, 96, 95, 94, 93, // 385
91, 90, 91, 90, 89, // 390
88, 86, 85, 86, 85, // 395
85, 84, 82, 81, 80, // 400
79, 77, 78, 78, 76, // 405
77, 75, 75, 74, 73, // 410
71, 72, 70, 69, 69, // 415
69, 67, 65, 64, 63, // 420
63, 63, 61, 61, 59, // 425
59, 59, 58, 56, 57, // 430
58, 56, 54, 53, 52, // 435
52, 53, 52, 52, 50, // 440
48, 47, 47, 45, 46, // 445
45
}; // 450

static int speed1 = 130;
static int speed2 = 121;
@@ -263,7 +265,7 @@ void SetSpeed(int control)
}

// adjust for different sample rates
speed.min_sample_len = (speed.min_sample_len * samplerate_native) / 22050;
speed.min_sample_len = (speed.min_sample_len * samplerate_native) / 22050;

speed.pause_factor = (256 * s1)/115; // full speed adjustment, used for pause length
speed.clause_pause_factor = 0;
@@ -517,23 +519,23 @@ void CalcLengths(Translator *tr)
PHONEME_LIST *p;
PHONEME_LIST *p2;

int stress;
int type;
static int more_syllables=0;
int pre_sonorant=0;
int pre_voiced=0;
int last_pitch = 0;
int pitch_start;
int length_mod;
int next2type;
int len;
int env2;
int end_of_clause;
int embedded_ix = 0;
int min_drop;
int pitch1;
int stress;
int type;
static int more_syllables=0;
int pre_sonorant=0;
int pre_voiced=0;
int last_pitch = 0;
int pitch_start;
int length_mod;
int next2type;
int len;
int env2;
int end_of_clause;
int embedded_ix = 0;
int min_drop;
int pitch1;
int emphasized;
int tone_mod;
int tone_mod;
unsigned char *pitch_env=NULL;
PHONEME_DATA phdata_tone;

@@ -742,10 +744,10 @@ void CalcLengths(Translator *tr)

if(stress > 7) stress = 7;

if(stress <= 1)
{
stress = stress ^ 1; // swap diminished and unstressed (until we swap stress_amps,stress_lengths in tr_languages)
}
if(stress <= 1)
{
stress = stress ^ 1; // swap diminished and unstressed (until we swap stress_amps,stress_lengths in tr_languages)
}
if(pre_sonorant)
p->amp = tr->stress_amps[stress]-1;
else
@@ -875,11 +877,11 @@ if(stress <= 1)

length_mod = length_mod / 128;

if(p->type != phVOWEL)
{
length_mod = 256; // syllabic consonant
min_drop = 16;
}
if(p->type != phVOWEL)
{
length_mod = 256; // syllabic consonant
min_drop = 16;
}
p->length = length_mod;

if(p->env >= (N_ENVELOPE_DATA-1))

+ 257
- 257
src/libespeak-ng/sintab.h View File

@@ -4,263 +4,263 @@ extern "C"
#endif

short int sin_tab[2048] = {
0, -25, -50, -75, -100, -125, -150, -175,
-201, -226, -251, -276, -301, -326, -351, -376,
-401, -427, -452, -477, -502, -527, -552, -577,
-602, -627, -652, -677, -702, -727, -752, -777,
-802, -827, -852, -877, -902, -927, -952, -977,
-1002, -1027, -1052, -1077, -1102, -1127, -1152, -1177,
-1201, -1226, -1251, -1276, -1301, -1326, -1350, -1375,
-1400, -1425, -1449, -1474, -1499, -1523, -1548, -1573,
-1597, -1622, -1647, -1671, -1696, -1721, -1745, -1770,
-1794, -1819, -1843, -1868, -1892, -1917, -1941, -1965,
-1990, -2014, -2038, -2063, -2087, -2111, -2136, -2160,
-2184, -2208, -2233, -2257, -2281, -2305, -2329, -2353,
-2377, -2401, -2425, -2449, -2473, -2497, -2521, -2545,
-2569, -2593, -2617, -2640, -2664, -2688, -2712, -2735,
-2759, -2783, -2806, -2830, -2853, -2877, -2900, -2924,
-2947, -2971, -2994, -3018, -3041, -3064, -3088, -3111,
-3134, -3157, -3180, -3204, -3227, -3250, -3273, -3296,
-3319, -3342, -3365, -3388, -3410, -3433, -3456, -3479,
-3502, -3524, -3547, -3570, -3592, -3615, -3637, -3660,
-3682, -3705, -3727, -3749, -3772, -3794, -3816, -3839,
-3861, -3883, -3905, -3927, -3949, -3971, -3993, -4015,
-4037, -4059, -4080, -4102, -4124, -4146, -4167, -4189,
-4211, -4232, -4254, -4275, -4296, -4318, -4339, -4360,
-4382, -4403, -4424, -4445, -4466, -4487, -4508, -4529,
-4550, -4571, -4592, -4613, -4633, -4654, -4675, -4695,
-4716, -4736, -4757, -4777, -4798, -4818, -4838, -4859,
-4879, -4899, -4919, -4939, -4959, -4979, -4999, -5019,
-5039, -5059, -5078, -5098, -5118, -5137, -5157, -5176,
-5196, -5215, -5235, -5254, -5273, -5292, -5311, -5331,
-5350, -5369, -5388, -5406, -5425, -5444, -5463, -5482,
-5500, -5519, -5537, -5556, -5574, -5593, -5611, -5629,
-5648, -5666, -5684, -5702, -5720, -5738, -5756, -5774,
-5791, -5809, -5827, -5844, -5862, -5880, -5897, -5914,
-5932, -5949, -5966, -5984, -6001, -6018, -6035, -6052,
-6069, -6085, -6102, -6119, -6136, -6152, -6169, -6185,
-6202, -6218, -6235, -6251, -6267, -6283, -6299, -6315,
-6331, -6347, -6363, -6379, -6395, -6410, -6426, -6441,
-6457, -6472, -6488, -6503, -6518, -6533, -6549, -6564,
-6579, -6594, -6608, -6623, -6638, -6653, -6667, -6682,
-6696, -6711, -6725, -6739, -6754, -6768, -6782, -6796,
-6810, -6824, -6838, -6852, -6865, -6879, -6893, -6906,
-6920, -6933, -6946, -6960, -6973, -6986, -6999, -7012,
-7025, -7038, -7051, -7064, -7076, -7089, -7101, -7114,
-7126, -7139, -7151, -7163, -7175, -7187, -7199, -7211,
-7223, -7235, -7247, -7259, -7270, -7282, -7293, -7305,
-7316, -7327, -7338, -7349, -7361, -7372, -7382, -7393,
-7404, -7415, -7425, -7436, -7446, -7457, -7467, -7478,
-7488, -7498, -7508, -7518, -7528, -7538, -7548, -7557,
-7567, -7577, -7586, -7596, -7605, -7614, -7623, -7633,
-7642, -7651, -7660, -7668, -7677, -7686, -7695, -7703,
-7712, -7720, -7728, -7737, -7745, -7753, -7761, -7769,
-7777, -7785, -7793, -7800, -7808, -7816, -7823, -7830,
-7838, -7845, -7852, -7859, -7866, -7873, -7880, -7887,
-7894, -7900, -7907, -7914, -7920, -7926, -7933, -7939,
-7945, -7951, -7957, -7963, -7969, -7975, -7980, -7986,
-7991, -7997, -8002, -8008, -8013, -8018, -8023, -8028,
-8033, -8038, -8043, -8047, -8052, -8057, -8061, -8066,
-8070, -8074, -8078, -8082, -8086, -8090, -8094, -8098,
-8102, -8105, -8109, -8113, -8116, -8119, -8123, -8126,
-8129, -8132, -8135, -8138, -8141, -8143, -8146, -8149,
-8151, -8153, -8156, -8158, -8160, -8162, -8164, -8166,
-8168, -8170, -8172, -8174, -8175, -8177, -8178, -8179,
-8181, -8182, -8183, -8184, -8185, -8186, -8187, -8187,
-8188, -8189, -8189, -8190, -8190, -8190, -8190, -8190,
-8191, -8190, -8190, -8190, -8190, -8190, -8189, -8189,
-8188, -8187, -8187, -8186, -8185, -8184, -8183, -8182,
-8181, -8179, -8178, -8177, -8175, -8174, -8172, -8170,
-8168, -8166, -8164, -8162, -8160, -8158, -8156, -8153,
-8151, -8149, -8146, -8143, -8141, -8138, -8135, -8132,
-8129, -8126, -8123, -8119, -8116, -8113, -8109, -8105,
-8102, -8098, -8094, -8090, -8086, -8082, -8078, -8074,
-8070, -8066, -8061, -8057, -8052, -8047, -8043, -8038,
-8033, -8028, -8023, -8018, -8013, -8008, -8002, -7997,
-7991, -7986, -7980, -7975, -7969, -7963, -7957, -7951,
-7945, -7939, -7933, -7926, -7920, -7914, -7907, -7900,
-7894, -7887, -7880, -7873, -7866, -7859, -7852, -7845,
-7838, -7830, -7823, -7816, -7808, -7800, -7793, -7785,
-7777, -7769, -7761, -7753, -7745, -7737, -7728, -7720,
-7712, -7703, -7695, -7686, -7677, -7668, -7660, -7651,
-7642, -7633, -7623, -7614, -7605, -7596, -7586, -7577,
-7567, -7557, -7548, -7538, -7528, -7518, -7508, -7498,
-7488, -7478, -7467, -7457, -7446, -7436, -7425, -7415,
-7404, -7393, -7382, -7372, -7361, -7349, -7338, -7327,
-7316, -7305, -7293, -7282, -7270, -7259, -7247, -7235,
-7223, -7211, -7199, -7187, -7175, -7163, -7151, -7139,
-7126, -7114, -7101, -7089, -7076, -7064, -7051, -7038,
-7025, -7012, -6999, -6986, -6973, -6960, -6946, -6933,
-6920, -6906, -6893, -6879, -6865, -6852, -6838, -6824,
-6810, -6796, -6782, -6768, -6754, -6739, -6725, -6711,
-6696, -6682, -6667, -6653, -6638, -6623, -6608, -6594,
-6579, -6564, -6549, -6533, -6518, -6503, -6488, -6472,
-6457, -6441, -6426, -6410, -6395, -6379, -6363, -6347,
-6331, -6315, -6299, -6283, -6267, -6251, -6235, -6218,
-6202, -6185, -6169, -6152, -6136, -6119, -6102, -6085,
-6069, -6052, -6035, -6018, -6001, -5984, -5966, -5949,
-5932, -5914, -5897, -5880, -5862, -5844, -5827, -5809,
-5791, -5774, -5756, -5738, -5720, -5702, -5684, -5666,
-5648, -5629, -5611, -5593, -5574, -5556, -5537, -5519,
-5500, -5482, -5463, -5444, -5425, -5406, -5388, -5369,
-5350, -5331, -5311, -5292, -5273, -5254, -5235, -5215,
-5196, -5176, -5157, -5137, -5118, -5098, -5078, -5059,
-5039, -5019, -4999, -4979, -4959, -4939, -4919, -4899,
-4879, -4859, -4838, -4818, -4798, -4777, -4757, -4736,
-4716, -4695, -4675, -4654, -4633, -4613, -4592, -4571,
-4550, -4529, -4508, -4487, -4466, -4445, -4424, -4403,
-4382, -4360, -4339, -4318, -4296, -4275, -4254, -4232,
-4211, -4189, -4167, -4146, -4124, -4102, -4080, -4059,
-4037, -4015, -3993, -3971, -3949, -3927, -3905, -3883,
-3861, -3839, -3816, -3794, -3772, -3749, -3727, -3705,
-3682, -3660, -3637, -3615, -3592, -3570, -3547, -3524,
-3502, -3479, -3456, -3433, -3410, -3388, -3365, -3342,
-3319, -3296, -3273, -3250, -3227, -3204, -3180, -3157,
-3134, -3111, -3088, -3064, -3041, -3018, -2994, -2971,
-2947, -2924, -2900, -2877, -2853, -2830, -2806, -2783,
-2759, -2735, -2712, -2688, -2664, -2640, -2617, -2593,
-2569, -2545, -2521, -2497, -2473, -2449, -2425, -2401,
-2377, -2353, -2329, -2305, -2281, -2257, -2233, -2208,
-2184, -2160, -2136, -2111, -2087, -2063, -2038, -2014,
-1990, -1965, -1941, -1917, -1892, -1868, -1843, -1819,
-1794, -1770, -1745, -1721, -1696, -1671, -1647, -1622,
-1597, -1573, -1548, -1523, -1499, -1474, -1449, -1425,
-1400, -1375, -1350, -1326, -1301, -1276, -1251, -1226,
-1201, -1177, -1152, -1127, -1102, -1077, -1052, -1027,
-1002, -977, -952, -927, -902, -877, -852, -827,
-802, -777, -752, -727, -702, -677, -652, -627,
-602, -577, -552, -527, -502, -477, -452, -427,
-401, -376, -351, -326, -301, -276, -251, -226,
-201, -175, -150, -125, -100, -75, -50, -25,
0, 25, 50, 75, 100, 125, 150, 175,
201, 226, 251, 276, 301, 326, 351, 376,
401, 427, 452, 477, 502, 527, 552, 577,
602, 627, 652, 677, 702, 727, 752, 777,
802, 827, 852, 877, 902, 927, 952, 977,
1002, 1027, 1052, 1077, 1102, 1127, 1152, 1177,
1201, 1226, 1251, 1276, 1301, 1326, 1350, 1375,
1400, 1425, 1449, 1474, 1499, 1523, 1548, 1573,
1597, 1622, 1647, 1671, 1696, 1721, 1745, 1770,
1794, 1819, 1843, 1868, 1892, 1917, 1941, 1965,
1990, 2014, 2038, 2063, 2087, 2111, 2136, 2160,
2184, 2208, 2233, 2257, 2281, 2305, 2329, 2353,
2377, 2401, 2425, 2449, 2473, 2497, 2521, 2545,
2569, 2593, 2617, 2640, 2664, 2688, 2712, 2735,
2759, 2783, 2806, 2830, 2853, 2877, 2900, 2924,
2947, 2971, 2994, 3018, 3041, 3064, 3088, 3111,
3134, 3157, 3180, 3204, 3227, 3250, 3273, 3296,
3319, 3342, 3365, 3388, 3410, 3433, 3456, 3479,
3502, 3524, 3547, 3570, 3592, 3615, 3637, 3660,
3682, 3705, 3727, 3749, 3772, 3794, 3816, 3839,
3861, 3883, 3905, 3927, 3949, 3971, 3993, 4015,
4037, 4059, 4080, 4102, 4124, 4146, 4167, 4189,
4211, 4232, 4254, 4275, 4296, 4318, 4339, 4360,
4382, 4403, 4424, 4445, 4466, 4487, 4508, 4529,
4550, 4571, 4592, 4613, 4633, 4654, 4675, 4695,
4716, 4736, 4757, 4777, 4798, 4818, 4838, 4859,
4879, 4899, 4919, 4939, 4959, 4979, 4999, 5019,
5039, 5059, 5078, 5098, 5118, 5137, 5157, 5176,
5196, 5215, 5235, 5254, 5273, 5292, 5311, 5331,
5350, 5369, 5388, 5406, 5425, 5444, 5463, 5482,
5500, 5519, 5537, 5556, 5574, 5593, 5611, 5629,
5648, 5666, 5684, 5702, 5720, 5738, 5756, 5774,
5791, 5809, 5827, 5844, 5862, 5880, 5897, 5914,
5932, 5949, 5966, 5984, 6001, 6018, 6035, 6052,
6069, 6085, 6102, 6119, 6136, 6152, 6169, 6185,
6202, 6218, 6235, 6251, 6267, 6283, 6299, 6315,
6331, 6347, 6363, 6379, 6395, 6410, 6426, 6441,
6457, 6472, 6488, 6503, 6518, 6533, 6549, 6564,
6579, 6594, 6608, 6623, 6638, 6653, 6667, 6682,
6696, 6711, 6725, 6739, 6754, 6768, 6782, 6796,
6810, 6824, 6838, 6852, 6865, 6879, 6893, 6906,
6920, 6933, 6946, 6960, 6973, 6986, 6999, 7012,
7025, 7038, 7051, 7064, 7076, 7089, 7101, 7114,
7126, 7139, 7151, 7163, 7175, 7187, 7199, 7211,
7223, 7235, 7247, 7259, 7270, 7282, 7293, 7305,
7316, 7327, 7338, 7349, 7361, 7372, 7382, 7393,
7404, 7415, 7425, 7436, 7446, 7457, 7467, 7478,
7488, 7498, 7508, 7518, 7528, 7538, 7548, 7557,
7567, 7577, 7586, 7596, 7605, 7614, 7623, 7633,
7642, 7651, 7660, 7668, 7677, 7686, 7695, 7703,
7712, 7720, 7728, 7737, 7745, 7753, 7761, 7769,
7777, 7785, 7793, 7800, 7808, 7816, 7823, 7830,
7838, 7845, 7852, 7859, 7866, 7873, 7880, 7887,
7894, 7900, 7907, 7914, 7920, 7926, 7933, 7939,
7945, 7951, 7957, 7963, 7969, 7975, 7980, 7986,
7991, 7997, 8002, 8008, 8013, 8018, 8023, 8028,
8033, 8038, 8043, 8047, 8052, 8057, 8061, 8066,
8070, 8074, 8078, 8082, 8086, 8090, 8094, 8098,
8102, 8105, 8109, 8113, 8116, 8119, 8123, 8126,
8129, 8132, 8135, 8138, 8141, 8143, 8146, 8149,
8151, 8153, 8156, 8158, 8160, 8162, 8164, 8166,
8168, 8170, 8172, 8174, 8175, 8177, 8178, 8179,
8181, 8182, 8183, 8184, 8185, 8186, 8187, 8187,
8188, 8189, 8189, 8190, 8190, 8190, 8190, 8190,
8191, 8190, 8190, 8190, 8190, 8190, 8189, 8189,
8188, 8187, 8187, 8186, 8185, 8184, 8183, 8182,
8181, 8179, 8178, 8177, 8175, 8174, 8172, 8170,
8168, 8166, 8164, 8162, 8160, 8158, 8156, 8153,
8151, 8149, 8146, 8143, 8141, 8138, 8135, 8132,
8129, 8126, 8123, 8119, 8116, 8113, 8109, 8105,
8102, 8098, 8094, 8090, 8086, 8082, 8078, 8074,
8070, 8066, 8061, 8057, 8052, 8047, 8043, 8038,
8033, 8028, 8023, 8018, 8013, 8008, 8002, 7997,
7991, 7986, 7980, 7975, 7969, 7963, 7957, 7951,
7945, 7939, 7933, 7926, 7920, 7914, 7907, 7900,
7894, 7887, 7880, 7873, 7866, 7859, 7852, 7845,
7838, 7830, 7823, 7816, 7808, 7800, 7793, 7785,
7777, 7769, 7761, 7753, 7745, 7737, 7728, 7720,
7712, 7703, 7695, 7686, 7677, 7668, 7660, 7651,
7642, 7633, 7623, 7614, 7605, 7596, 7586, 7577,
7567, 7557, 7548, 7538, 7528, 7518, 7508, 7498,
7488, 7478, 7467, 7457, 7446, 7436, 7425, 7415,
7404, 7393, 7382, 7372, 7361, 7349, 7338, 7327,
7316, 7305, 7293, 7282, 7270, 7259, 7247, 7235,
7223, 7211, 7199, 7187, 7175, 7163, 7151, 7139,
7126, 7114, 7101, 7089, 7076, 7064, 7051, 7038,
7025, 7012, 6999, 6986, 6973, 6960, 6946, 6933,
6920, 6906, 6893, 6879, 6865, 6852, 6838, 6824,
6810, 6796, 6782, 6768, 6754, 6739, 6725, 6711,
6696, 6682, 6667, 6653, 6638, 6623, 6608, 6594,
6579, 6564, 6549, 6533, 6518, 6503, 6488, 6472,
6457, 6441, 6426, 6410, 6395, 6379, 6363, 6347,
6331, 6315, 6299, 6283, 6267, 6251, 6235, 6218,
6202, 6185, 6169, 6152, 6136, 6119, 6102, 6085,
6069, 6052, 6035, 6018, 6001, 5984, 5966, 5949,
5932, 5914, 5897, 5880, 5862, 5844, 5827, 5809,
5791, 5774, 5756, 5738, 5720, 5702, 5684, 5666,
5648, 5629, 5611, 5593, 5574, 5556, 5537, 5519,
5500, 5482, 5463, 5444, 5425, 5406, 5388, 5369,
5350, 5331, 5311, 5292, 5273, 5254, 5235, 5215,
5196, 5176, 5157, 5137, 5118, 5098, 5078, 5059,
5039, 5019, 4999, 4979, 4959, 4939, 4919, 4899,
4879, 4859, 4838, 4818, 4798, 4777, 4757, 4736,
4716, 4695, 4675, 4654, 4633, 4613, 4592, 4571,
4550, 4529, 4508, 4487, 4466, 4445, 4424, 4403,
4382, 4360, 4339, 4318, 4296, 4275, 4254, 4232,
4211, 4189, 4167, 4146, 4124, 4102, 4080, 4059,
4037, 4015, 3993, 3971, 3949, 3927, 3905, 3883,
3861, 3839, 3816, 3794, 3772, 3749, 3727, 3705,
3682, 3660, 3637, 3615, 3592, 3570, 3547, 3524,
3502, 3479, 3456, 3433, 3410, 3388, 3365, 3342,
3319, 3296, 3273, 3250, 3227, 3204, 3180, 3157,
3134, 3111, 3088, 3064, 3041, 3018, 2994, 2971,
2947, 2924, 2900, 2877, 2853, 2830, 2806, 2783,
2759, 2735, 2712, 2688, 2664, 2640, 2617, 2593,
2569, 2545, 2521, 2497, 2473, 2449, 2425, 2401,
2377, 2353, 2329, 2305, 2281, 2257, 2233, 2208,
2184, 2160, 2136, 2111, 2087, 2063, 2038, 2014,
1990, 1965, 1941, 1917, 1892, 1868, 1843, 1819,
1794, 1770, 1745, 1721, 1696, 1671, 1647, 1622,
1597, 1573, 1548, 1523, 1499, 1474, 1449, 1425,
1400, 1375, 1350, 1326, 1301, 1276, 1251, 1226,
1201, 1177, 1152, 1127, 1102, 1077, 1052, 1027,
1002, 977, 952, 927, 902, 877, 852, 827,
802, 777, 752, 727, 702, 677, 652, 627,
602, 577, 552, 527, 502, 477, 452, 427,
401, 376, 351, 326, 301, 276, 251, 226,
201, 175, 150, 125, 100, 75, 50, 25,
};
0, -25, -50, -75, -100, -125, -150, -175,
-201, -226, -251, -276, -301, -326, -351, -376,
-401, -427, -452, -477, -502, -527, -552, -577,
-602, -627, -652, -677, -702, -727, -752, -777,
-802, -827, -852, -877, -902, -927, -952, -977,
-1002, -1027, -1052, -1077, -1102, -1127, -1152, -1177,
-1201, -1226, -1251, -1276, -1301, -1326, -1350, -1375,
-1400, -1425, -1449, -1474, -1499, -1523, -1548, -1573,
-1597, -1622, -1647, -1671, -1696, -1721, -1745, -1770,
-1794, -1819, -1843, -1868, -1892, -1917, -1941, -1965,
-1990, -2014, -2038, -2063, -2087, -2111, -2136, -2160,
-2184, -2208, -2233, -2257, -2281, -2305, -2329, -2353,
-2377, -2401, -2425, -2449, -2473, -2497, -2521, -2545,
-2569, -2593, -2617, -2640, -2664, -2688, -2712, -2735,
-2759, -2783, -2806, -2830, -2853, -2877, -2900, -2924,
-2947, -2971, -2994, -3018, -3041, -3064, -3088, -3111,
-3134, -3157, -3180, -3204, -3227, -3250, -3273, -3296,
-3319, -3342, -3365, -3388, -3410, -3433, -3456, -3479,
-3502, -3524, -3547, -3570, -3592, -3615, -3637, -3660,
-3682, -3705, -3727, -3749, -3772, -3794, -3816, -3839,
-3861, -3883, -3905, -3927, -3949, -3971, -3993, -4015,
-4037, -4059, -4080, -4102, -4124, -4146, -4167, -4189,
-4211, -4232, -4254, -4275, -4296, -4318, -4339, -4360,
-4382, -4403, -4424, -4445, -4466, -4487, -4508, -4529,
-4550, -4571, -4592, -4613, -4633, -4654, -4675, -4695,
-4716, -4736, -4757, -4777, -4798, -4818, -4838, -4859,
-4879, -4899, -4919, -4939, -4959, -4979, -4999, -5019,
-5039, -5059, -5078, -5098, -5118, -5137, -5157, -5176,
-5196, -5215, -5235, -5254, -5273, -5292, -5311, -5331,
-5350, -5369, -5388, -5406, -5425, -5444, -5463, -5482,
-5500, -5519, -5537, -5556, -5574, -5593, -5611, -5629,
-5648, -5666, -5684, -5702, -5720, -5738, -5756, -5774,
-5791, -5809, -5827, -5844, -5862, -5880, -5897, -5914,
-5932, -5949, -5966, -5984, -6001, -6018, -6035, -6052,
-6069, -6085, -6102, -6119, -6136, -6152, -6169, -6185,
-6202, -6218, -6235, -6251, -6267, -6283, -6299, -6315,
-6331, -6347, -6363, -6379, -6395, -6410, -6426, -6441,
-6457, -6472, -6488, -6503, -6518, -6533, -6549, -6564,
-6579, -6594, -6608, -6623, -6638, -6653, -6667, -6682,
-6696, -6711, -6725, -6739, -6754, -6768, -6782, -6796,
-6810, -6824, -6838, -6852, -6865, -6879, -6893, -6906,
-6920, -6933, -6946, -6960, -6973, -6986, -6999, -7012,
-7025, -7038, -7051, -7064, -7076, -7089, -7101, -7114,
-7126, -7139, -7151, -7163, -7175, -7187, -7199, -7211,
-7223, -7235, -7247, -7259, -7270, -7282, -7293, -7305,
-7316, -7327, -7338, -7349, -7361, -7372, -7382, -7393,
-7404, -7415, -7425, -7436, -7446, -7457, -7467, -7478,
-7488, -7498, -7508, -7518, -7528, -7538, -7548, -7557,
-7567, -7577, -7586, -7596, -7605, -7614, -7623, -7633,
-7642, -7651, -7660, -7668, -7677, -7686, -7695, -7703,
-7712, -7720, -7728, -7737, -7745, -7753, -7761, -7769,
-7777, -7785, -7793, -7800, -7808, -7816, -7823, -7830,
-7838, -7845, -7852, -7859, -7866, -7873, -7880, -7887,
-7894, -7900, -7907, -7914, -7920, -7926, -7933, -7939,
-7945, -7951, -7957, -7963, -7969, -7975, -7980, -7986,
-7991, -7997, -8002, -8008, -8013, -8018, -8023, -8028,
-8033, -8038, -8043, -8047, -8052, -8057, -8061, -8066,
-8070, -8074, -8078, -8082, -8086, -8090, -8094, -8098,
-8102, -8105, -8109, -8113, -8116, -8119, -8123, -8126,
-8129, -8132, -8135, -8138, -8141, -8143, -8146, -8149,
-8151, -8153, -8156, -8158, -8160, -8162, -8164, -8166,
-8168, -8170, -8172, -8174, -8175, -8177, -8178, -8179,
-8181, -8182, -8183, -8184, -8185, -8186, -8187, -8187,
-8188, -8189, -8189, -8190, -8190, -8190, -8190, -8190,
-8191, -8190, -8190, -8190, -8190, -8190, -8189, -8189,
-8188, -8187, -8187, -8186, -8185, -8184, -8183, -8182,
-8181, -8179, -8178, -8177, -8175, -8174, -8172, -8170,
-8168, -8166, -8164, -8162, -8160, -8158, -8156, -8153,
-8151, -8149, -8146, -8143, -8141, -8138, -8135, -8132,
-8129, -8126, -8123, -8119, -8116, -8113, -8109, -8105,
-8102, -8098, -8094, -8090, -8086, -8082, -8078, -8074,
-8070, -8066, -8061, -8057, -8052, -8047, -8043, -8038,
-8033, -8028, -8023, -8018, -8013, -8008, -8002, -7997,
-7991, -7986, -7980, -7975, -7969, -7963, -7957, -7951,
-7945, -7939, -7933, -7926, -7920, -7914, -7907, -7900,
-7894, -7887, -7880, -7873, -7866, -7859, -7852, -7845,
-7838, -7830, -7823, -7816, -7808, -7800, -7793, -7785,
-7777, -7769, -7761, -7753, -7745, -7737, -7728, -7720,
-7712, -7703, -7695, -7686, -7677, -7668, -7660, -7651,
-7642, -7633, -7623, -7614, -7605, -7596, -7586, -7577,
-7567, -7557, -7548, -7538, -7528, -7518, -7508, -7498,
-7488, -7478, -7467, -7457, -7446, -7436, -7425, -7415,
-7404, -7393, -7382, -7372, -7361, -7349, -7338, -7327,
-7316, -7305, -7293, -7282, -7270, -7259, -7247, -7235,
-7223, -7211, -7199, -7187, -7175, -7163, -7151, -7139,
-7126, -7114, -7101, -7089, -7076, -7064, -7051, -7038,
-7025, -7012, -6999, -6986, -6973, -6960, -6946, -6933,
-6920, -6906, -6893, -6879, -6865, -6852, -6838, -6824,
-6810, -6796, -6782, -6768, -6754, -6739, -6725, -6711,
-6696, -6682, -6667, -6653, -6638, -6623, -6608, -6594,
-6579, -6564, -6549, -6533, -6518, -6503, -6488, -6472,
-6457, -6441, -6426, -6410, -6395, -6379, -6363, -6347,
-6331, -6315, -6299, -6283, -6267, -6251, -6235, -6218,
-6202, -6185, -6169, -6152, -6136, -6119, -6102, -6085,
-6069, -6052, -6035, -6018, -6001, -5984, -5966, -5949,
-5932, -5914, -5897, -5880, -5862, -5844, -5827, -5809,
-5791, -5774, -5756, -5738, -5720, -5702, -5684, -5666,
-5648, -5629, -5611, -5593, -5574, -5556, -5537, -5519,
-5500, -5482, -5463, -5444, -5425, -5406, -5388, -5369,
-5350, -5331, -5311, -5292, -5273, -5254, -5235, -5215,
-5196, -5176, -5157, -5137, -5118, -5098, -5078, -5059,
-5039, -5019, -4999, -4979, -4959, -4939, -4919, -4899,
-4879, -4859, -4838, -4818, -4798, -4777, -4757, -4736,
-4716, -4695, -4675, -4654, -4633, -4613, -4592, -4571,
-4550, -4529, -4508, -4487, -4466, -4445, -4424, -4403,
-4382, -4360, -4339, -4318, -4296, -4275, -4254, -4232,
-4211, -4189, -4167, -4146, -4124, -4102, -4080, -4059,
-4037, -4015, -3993, -3971, -3949, -3927, -3905, -3883,
-3861, -3839, -3816, -3794, -3772, -3749, -3727, -3705,
-3682, -3660, -3637, -3615, -3592, -3570, -3547, -3524,
-3502, -3479, -3456, -3433, -3410, -3388, -3365, -3342,
-3319, -3296, -3273, -3250, -3227, -3204, -3180, -3157,
-3134, -3111, -3088, -3064, -3041, -3018, -2994, -2971,
-2947, -2924, -2900, -2877, -2853, -2830, -2806, -2783,
-2759, -2735, -2712, -2688, -2664, -2640, -2617, -2593,
-2569, -2545, -2521, -2497, -2473, -2449, -2425, -2401,
-2377, -2353, -2329, -2305, -2281, -2257, -2233, -2208,
-2184, -2160, -2136, -2111, -2087, -2063, -2038, -2014,
-1990, -1965, -1941, -1917, -1892, -1868, -1843, -1819,
-1794, -1770, -1745, -1721, -1696, -1671, -1647, -1622,
-1597, -1573, -1548, -1523, -1499, -1474, -1449, -1425,
-1400, -1375, -1350, -1326, -1301, -1276, -1251, -1226,
-1201, -1177, -1152, -1127, -1102, -1077, -1052, -1027,
-1002, -977, -952, -927, -902, -877, -852, -827,
-802, -777, -752, -727, -702, -677, -652, -627,
-602, -577, -552, -527, -502, -477, -452, -427,
-401, -376, -351, -326, -301, -276, -251, -226,
-201, -175, -150, -125, -100, -75, -50, -25,
0, 25, 50, 75, 100, 125, 150, 175,
201, 226, 251, 276, 301, 326, 351, 376,
401, 427, 452, 477, 502, 527, 552, 577,
602, 627, 652, 677, 702, 727, 752, 777,
802, 827, 852, 877, 902, 927, 952, 977,
1002, 1027, 1052, 1077, 1102, 1127, 1152, 1177,
1201, 1226, 1251, 1276, 1301, 1326, 1350, 1375,
1400, 1425, 1449, 1474, 1499, 1523, 1548, 1573,
1597, 1622, 1647, 1671, 1696, 1721, 1745, 1770,
1794, 1819, 1843, 1868, 1892, 1917, 1941, 1965,
1990, 2014, 2038, 2063, 2087, 2111, 2136, 2160,
2184, 2208, 2233, 2257, 2281, 2305, 2329, 2353,
2377, 2401, 2425, 2449, 2473, 2497, 2521, 2545,
2569, 2593, 2617, 2640, 2664, 2688, 2712, 2735,
2759, 2783, 2806, 2830, 2853, 2877, 2900, 2924,
2947, 2971, 2994, 3018, 3041, 3064, 3088, 3111,
3134, 3157, 3180, 3204, 3227, 3250, 3273, 3296,
3319, 3342, 3365, 3388, 3410, 3433, 3456, 3479,
3502, 3524, 3547, 3570, 3592, 3615, 3637, 3660,
3682, 3705, 3727, 3749, 3772, 3794, 3816, 3839,
3861, 3883, 3905, 3927, 3949, 3971, 3993, 4015,
4037, 4059, 4080, 4102, 4124, 4146, 4167, 4189,
4211, 4232, 4254, 4275, 4296, 4318, 4339, 4360,
4382, 4403, 4424, 4445, 4466, 4487, 4508, 4529,
4550, 4571, 4592, 4613, 4633, 4654, 4675, 4695,
4716, 4736, 4757, 4777, 4798, 4818, 4838, 4859,
4879, 4899, 4919, 4939, 4959, 4979, 4999, 5019,
5039, 5059, 5078, 5098, 5118, 5137, 5157, 5176,
5196, 5215, 5235, 5254, 5273, 5292, 5311, 5331,
5350, 5369, 5388, 5406, 5425, 5444, 5463, 5482,
5500, 5519, 5537, 5556, 5574, 5593, 5611, 5629,
5648, 5666, 5684, 5702, 5720, 5738, 5756, 5774,
5791, 5809, 5827, 5844, 5862, 5880, 5897, 5914,
5932, 5949, 5966, 5984, 6001, 6018, 6035, 6052,
6069, 6085, 6102, 6119, 6136, 6152, 6169, 6185,
6202, 6218, 6235, 6251, 6267, 6283, 6299, 6315,
6331, 6347, 6363, 6379, 6395, 6410, 6426, 6441,
6457, 6472, 6488, 6503, 6518, 6533, 6549, 6564,
6579, 6594, 6608, 6623, 6638, 6653, 6667, 6682,
6696, 6711, 6725, 6739, 6754, 6768, 6782, 6796,
6810, 6824, 6838, 6852, 6865, 6879, 6893, 6906,
6920, 6933, 6946, 6960, 6973, 6986, 6999, 7012,
7025, 7038, 7051, 7064, 7076, 7089, 7101, 7114,
7126, 7139, 7151, 7163, 7175, 7187, 7199, 7211,
7223, 7235, 7247, 7259, 7270, 7282, 7293, 7305,
7316, 7327, 7338, 7349, 7361, 7372, 7382, 7393,
7404, 7415, 7425, 7436, 7446, 7457, 7467, 7478,
7488, 7498, 7508, 7518, 7528, 7538, 7548, 7557,
7567, 7577, 7586, 7596, 7605, 7614, 7623, 7633,
7642, 7651, 7660, 7668, 7677, 7686, 7695, 7703,
7712, 7720, 7728, 7737, 7745, 7753, 7761, 7769,
7777, 7785, 7793, 7800, 7808, 7816, 7823, 7830,
7838, 7845, 7852, 7859, 7866, 7873, 7880, 7887,
7894, 7900, 7907, 7914, 7920, 7926, 7933, 7939,
7945, 7951, 7957, 7963, 7969, 7975, 7980, 7986,
7991, 7997, 8002, 8008, 8013, 8018, 8023, 8028,
8033, 8038, 8043, 8047, 8052, 8057, 8061, 8066,
8070, 8074, 8078, 8082, 8086, 8090, 8094, 8098,
8102, 8105, 8109, 8113, 8116, 8119, 8123, 8126,
8129, 8132, 8135, 8138, 8141, 8143, 8146, 8149,
8151, 8153, 8156, 8158, 8160, 8162, 8164, 8166,
8168, 8170, 8172, 8174, 8175, 8177, 8178, 8179,
8181, 8182, 8183, 8184, 8185, 8186, 8187, 8187,
8188, 8189, 8189, 8190, 8190, 8190, 8190, 8190,
8191, 8190, 8190, 8190, 8190, 8190, 8189, 8189,
8188, 8187, 8187, 8186, 8185, 8184, 8183, 8182,
8181, 8179, 8178, 8177, 8175, 8174, 8172, 8170,
8168, 8166, 8164, 8162, 8160, 8158, 8156, 8153,
8151, 8149, 8146, 8143, 8141, 8138, 8135, 8132,
8129, 8126, 8123, 8119, 8116, 8113, 8109, 8105,
8102, 8098, 8094, 8090, 8086, 8082, 8078, 8074,
8070, 8066, 8061, 8057, 8052, 8047, 8043, 8038,
8033, 8028, 8023, 8018, 8013, 8008, 8002, 7997,
7991, 7986, 7980, 7975, 7969, 7963, 7957, 7951,
7945, 7939, 7933, 7926, 7920, 7914, 7907, 7900,
7894, 7887, 7880, 7873, 7866, 7859, 7852, 7845,
7838, 7830, 7823, 7816, 7808, 7800, 7793, 7785,
7777, 7769, 7761, 7753, 7745, 7737, 7728, 7720,
7712, 7703, 7695, 7686, 7677, 7668, 7660, 7651,
7642, 7633, 7623, 7614, 7605, 7596, 7586, 7577,
7567, 7557, 7548, 7538, 7528, 7518, 7508, 7498,
7488, 7478, 7467, 7457, 7446, 7436, 7425, 7415,
7404, 7393, 7382, 7372, 7361, 7349, 7338, 7327,
7316, 7305, 7293, 7282, 7270, 7259, 7247, 7235,
7223, 7211, 7199, 7187, 7175, 7163, 7151, 7139,
7126, 7114, 7101, 7089, 7076, 7064, 7051, 7038,
7025, 7012, 6999, 6986, 6973, 6960, 6946, 6933,
6920, 6906, 6893, 6879, 6865, 6852, 6838, 6824,
6810, 6796, 6782, 6768, 6754, 6739, 6725, 6711,
6696, 6682, 6667, 6653, 6638, 6623, 6608, 6594,
6579, 6564, 6549, 6533, 6518, 6503, 6488, 6472,
6457, 6441, 6426, 6410, 6395, 6379, 6363, 6347,
6331, 6315, 6299, 6283, 6267, 6251, 6235, 6218,
6202, 6185, 6169, 6152, 6136, 6119, 6102, 6085,
6069, 6052, 6035, 6018, 6001, 5984, 5966, 5949,
5932, 5914, 5897, 5880, 5862, 5844, 5827, 5809,
5791, 5774, 5756, 5738, 5720, 5702, 5684, 5666,
5648, 5629, 5611, 5593, 5574, 5556, 5537, 5519,
5500, 5482, 5463, 5444, 5425, 5406, 5388, 5369,
5350, 5331, 5311, 5292, 5273, 5254, 5235, 5215,
5196, 5176, 5157, 5137, 5118, 5098, 5078, 5059,
5039, 5019, 4999, 4979, 4959, 4939, 4919, 4899,
4879, 4859, 4838, 4818, 4798, 4777, 4757, 4736,
4716, 4695, 4675, 4654, 4633, 4613, 4592, 4571,
4550, 4529, 4508, 4487, 4466, 4445, 4424, 4403,
4382, 4360, 4339, 4318, 4296, 4275, 4254, 4232,
4211, 4189, 4167, 4146, 4124, 4102, 4080, 4059,
4037, 4015, 3993, 3971, 3949, 3927, 3905, 3883,
3861, 3839, 3816, 3794, 3772, 3749, 3727, 3705,
3682, 3660, 3637, 3615, 3592, 3570, 3547, 3524,
3502, 3479, 3456, 3433, 3410, 3388, 3365, 3342,
3319, 3296, 3273, 3250, 3227, 3204, 3180, 3157,
3134, 3111, 3088, 3064, 3041, 3018, 2994, 2971,
2947, 2924, 2900, 2877, 2853, 2830, 2806, 2783,
2759, 2735, 2712, 2688, 2664, 2640, 2617, 2593,
2569, 2545, 2521, 2497, 2473, 2449, 2425, 2401,
2377, 2353, 2329, 2305, 2281, 2257, 2233, 2208,
2184, 2160, 2136, 2111, 2087, 2063, 2038, 2014,
1990, 1965, 1941, 1917, 1892, 1868, 1843, 1819,
1794, 1770, 1745, 1721, 1696, 1671, 1647, 1622,
1597, 1573, 1548, 1523, 1499, 1474, 1449, 1425,
1400, 1375, 1350, 1326, 1301, 1276, 1251, 1226,
1201, 1177, 1152, 1127, 1102, 1077, 1052, 1027,
1002, 977, 952, 927, 902, 877, 852, 827,
802, 777, 752, 727, 702, 677, 652, 627,
602, 577, 552, 527, 502, 477, 452, 427,
401, 376, 351, 326, 301, 276, 251, 226,
201, 175, 150, 125, 100, 75, 50, 25,
};

#ifdef __cplusplus
}

+ 65
- 64
src/libespeak-ng/speak_lib.c View File

@@ -96,9 +96,9 @@ static int dispatch_audio(short* outbuf, int length, espeak_EVENT* event)

#ifdef DEBUG_ENABLED
SHOW("*** dispatch_audio > uid=%d, [write=%p (%d bytes)], sample=%d, a_wave_can_be_played = %d\n",
(event) ? event->unique_identifier : 0, wave_test_get_write_buffer(), 2*length,
(event) ? event->sample : 0,
a_wave_can_be_played);
(event) ? event->unique_identifier : 0, wave_test_get_write_buffer(), 2*length,
(event) ? event->sample : 0,
a_wave_can_be_played);
#endif

switch(my_mode)
@@ -204,7 +204,7 @@ static int create_events(short* outbuf, int length, espeak_EVENT* event, uint32_
{
event = NULL;
}
else
else
{
event = event_list + i;
#ifdef DEBUG_ENABLED
@@ -245,7 +245,7 @@ int sync_espeak_terminated_msg( uint32_t unique_identifier, void* user_data)
espeak_ERROR a_error = event_declare(event_list);
if (a_error != EE_BUFFER_FULL)
{
break;
break;
}
SHOW_TIME("sync_espeak_terminated_msg > EE_BUFFER_FULL\n");
usleep(10000);
@@ -269,7 +269,7 @@ static void select_output(espeak_AUDIO_OUTPUT output_type)
my_mode = output_type;
my_audio = NULL;
synchronous_mode = 1;
option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
out_samplerate = 0;

switch(my_mode)
@@ -431,7 +431,7 @@ static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text,
ENTER("Synthesize");
if (text)
{
SHOW("Synthesize > uid=%d, flags=%d, >>>text=%s<<<\n", unique_identifier, flags, text);
SHOW("Synthesize > uid=%d, flags=%d, >>>text=%s<<<\n", unique_identifier, flags, text);
}
#endif

@@ -461,7 +461,7 @@ static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text,

if(my_mode == AUDIO_OUTPUT_SYNCH_PLAYBACK)
{
for(;;)
for(;; )
{
#ifdef PLATFORM_WINDOWS
Sleep(300); // 0.3s
@@ -482,7 +482,7 @@ static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text,
return(EE_OK);
}

for(;;)
for(;; )
{
#ifdef DEBUG_ENABLED
SHOW("Synthesize > %s\n","for (next)");
@@ -554,16 +554,17 @@ static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text,

#ifdef DEBUG_ENABLED
static const char* label[] = {
"END_OF_EVENT_LIST",
"WORD",
"SENTENCE",
"MARK",
"PLAY",
"END",
"MSG_TERMINATED",
"PHONEME",
"SAMPLERATE",
"??" };
"END_OF_EVENT_LIST",
"WORD",
"SENTENCE",
"MARK",
"PLAY",
"END",
"MSG_TERMINATED",
"PHONEME",
"SAMPLERATE",
"??"
};
#endif


@@ -591,8 +592,8 @@ void MarkerEvent(int type, unsigned int char_position, int value, int value2, un
#ifdef DEBUG_ENABLED
SHOW("MarkerEvent > count_samples=%d, out_ptr=%x, out_start=0x%x\n",count_samples, out_ptr, out_start);
SHOW("*** MarkerEvent > type=%s, uid=%d, text_pos=%d, length=%d, audio_position=%d, sample=%d\n",
label[ep->type], ep->unique_identifier, ep->text_position, ep->length,
ep->audio_position, ep->sample);
label[ep->type], ep->unique_identifier, ep->text_position, ep->length,
ep->audio_position, ep->sample);
#endif

if((type == espeakEVENT_MARK) || (type == espeakEVENT_PLAY))
@@ -615,8 +616,8 @@ void MarkerEvent(int type, unsigned int char_position, int value, int value2, un


espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size,
unsigned int position, espeak_POSITION_TYPE position_type,
unsigned int end_position, unsigned int flags, void* user_data)
unsigned int position, espeak_POSITION_TYPE position_type,
unsigned int end_position, unsigned int flags, void* user_data)
{

#ifdef DEBUG_ENABLED
@@ -634,20 +635,20 @@ espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text,
saved_parameters[i] = param_stack[0].parameter[i];

switch(position_type)
{
case POS_CHARACTER:
skip_characters = position;
break;
{
case POS_CHARACTER:
skip_characters = position;
break;

case POS_WORD:
skip_words = position;
break;
case POS_WORD:
skip_words = position;
break;

case POS_SENTENCE:
skip_sentences = position;
break;
case POS_SENTENCE:
skip_sentences = position;
break;

}
}
if(skip_characters || skip_words || skip_sentences)
skipping_text = 1;

@@ -666,8 +667,8 @@ espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text,


espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size,
const char *index_mark, unsigned int end_position,
unsigned int flags, void* user_data)
const char *index_mark, unsigned int end_position,
unsigned int flags, void* user_data)
{
espeak_ERROR aStatus;

@@ -677,10 +678,10 @@ espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *
my_user_data = user_data;

if(index_mark != NULL)
{
{
strncpy0(skip_marker, index_mark, sizeof(skip_marker));
skipping_text = 1;
}
}

end_character_position = end_position;

@@ -769,7 +770,7 @@ ESPEAK_API void espeak_SetPhonemeCallback(int (* PhonemeCallback)(const char*))

ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length, const char *path, int options)
{
ENTER("espeak_Initialize");
ENTER("espeak_Initialize");
int param;

// It seems that the wctype functions don't work until the locale has been set
@@ -831,16 +832,16 @@ ENTER("espeak_Initialize");
fifo_init();
#endif

return(samplerate);
return(samplerate);
}



ESPEAK_API espeak_ERROR espeak_Synth(const void *text, size_t size,
unsigned int position,
espeak_POSITION_TYPE position_type,
unsigned int end_position, unsigned int flags,
unsigned int* unique_identifier, void* user_data)
unsigned int position,
espeak_POSITION_TYPE position_type,
unsigned int end_position, unsigned int flags,
unsigned int* unique_identifier, void* user_data)
{
#ifdef DEBUG_ENABLED
ENTER("espeak_Synth");
@@ -901,15 +902,15 @@ ESPEAK_API espeak_ERROR espeak_Synth(const void *text, size_t size,


ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text, size_t size,
const char *index_mark,
unsigned int end_position,
unsigned int flags,
unsigned int* unique_identifier,
void* user_data)
const char *index_mark,
unsigned int end_position,
unsigned int flags,
unsigned int* unique_identifier,
void* user_data)
{
#ifdef DEBUG_ENABLED
ENTER("espeak_Synth_Mark");
SHOW("espeak_Synth_Mark > index_mark=%s, end_position=%d, flags=%d, text=%s\n", index_mark, end_position, flags, text);
ENTER("espeak_Synth_Mark");
SHOW("espeak_Synth_Mark > index_mark=%s, end_position=%d, flags=%d, text=%s\n", index_mark, end_position, flags, text);
#endif

espeak_ERROR a_error=EE_OK;
@@ -935,7 +936,7 @@ ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text, size_t size,
#ifdef USE_ASYNC
// Create the mark command
t_espeak_command* c1 = create_espeak_mark(text, size, index_mark, end_position,
flags, user_data);
flags, user_data);

// Retrieve the unique identifier
*unique_identifier = c1->u.my_mark.unique_identifier;
@@ -993,14 +994,14 @@ ESPEAK_API espeak_ERROR espeak_Key(const char *key)
}

#endif
return a_error;
return a_error;
}


ESPEAK_API espeak_ERROR espeak_Char(wchar_t character)
{
ENTER("espeak_Char");
// is there a system resource of character names per language?
ENTER("espeak_Char");
// is there a system resource of character names per language?

if(f_logespeak)
{
@@ -1032,7 +1033,7 @@ ESPEAK_API espeak_ERROR espeak_Char(wchar_t character)

ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name)
{
ENTER("espeak_SetVoiceByName");
ENTER("espeak_SetVoiceByName");

return(SetVoiceByName(name));
}
@@ -1041,7 +1042,7 @@ ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name)

ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_selector)
{
ENTER("espeak_SetVoiceByProperties");
ENTER("espeak_SetVoiceByProperties");

return(SetVoiceByProperties(voice_selector));
}
@@ -1064,7 +1065,7 @@ ESPEAK_API int espeak_GetParameter(espeak_PARAMETER parameter, int current)

ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative)
{
ENTER("espeak_SetParameter");
ENTER("espeak_SetParameter");

if(f_logespeak)
{
@@ -1096,8 +1097,8 @@ ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int valu

ESPEAK_API espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist)
{
ENTER("espeak_SetPunctuationList");
// Set the list of punctuation which are spoken for "some".
ENTER("espeak_SetPunctuationList");
// Set the list of punctuation which are spoken for "some".

#ifdef USE_ASYNC
espeak_ERROR a_error;
@@ -1136,7 +1137,7 @@ ESPEAK_API void espeak_SetPhonemeTrace(int phonememode, FILE *stream)
bits 8-23: separator character, between phoneme names

stream output stream for the phoneme symbols (and trace). If stream=NULL then it uses stdout.
*/
*/
option_phonemes = phonememode;
f_trans = stream;
if(stream == NULL)
@@ -1149,9 +1150,9 @@ ESPEAK_API const char *espeak_TextToPhonemes(const void **textptr, int textmode,
{
/* phoneme_mode
bit 1: 0=eSpeak's ascii phoneme names, 1= International Phonetic Alphabet (as UTF-8 characters).
bit 7: use (bits 8-23) as a tie within multi-letter phonemes names
bits 8-23: separator character, between phoneme names
*/
bit 7: use (bits 8-23) as a tie within multi-letter phonemes names
bits 8-23: separator character, between phoneme names
*/

option_multibyte = textmode & 7;
*textptr = TranslateClause(translator, NULL, *textptr, NULL, NULL);

+ 25
- 25
src/libespeak-ng/spect.c View File

@@ -44,11 +44,11 @@ int pk_select;
#define PEAKSHAPEW 256

static int default_freq[N_PEAKS] =
{200,500,1200,3000,3500,4000,6900,7800,9000};
{200,500,1200,3000,3500,4000,6900,7800,9000};
static int default_width[N_PEAKS] =
{750,500,550,550,600,700,700,700,700};
{750,500,550,550,600,700,700,700,700};
static int default_klt_bw[N_PEAKS] =
{89,90,140,260,260,260,500,500,500};
{89,90,140,260,260,260,500,500,500};

static double read_double(FILE *stream)
{
@@ -67,7 +67,7 @@ float polint(float xa[],float ya[],int n,float x)

dif=fabs(x-xa[1]);

for(i=1;i<=n;i++){
for(i=1; i<=n; i++) {
if((dift=fabs(x-xa[i])) < dif) {
ns=i;
dif=dift;
@@ -76,8 +76,8 @@ float polint(float xa[],float ya[],int n,float x)
d[i]=ya[i];
}
y=ya[ns--];
for(m=1;m<n;m++) {
for(i=1;i<=n-m;i++) {
for(m=1; m<n; m++) {
for(i=1; i<=n-m; i++) {
ho=xa[i]-x;
hp=xa[i+m]-x;
w=c[i+1]-d[i];
@@ -108,7 +108,7 @@ static void PeaksZero(peak_t *sp, peak_t *zero)

static SpectFrame *SpectFrameCreate()
{
int ix;
int ix;
SpectFrame *frame;

frame = malloc(sizeof(SpectFrame));
@@ -123,7 +123,7 @@ static SpectFrame *SpectFrameCreate()
frame->length_adjust = 0;

for(ix=0; ix<N_PEAKS; ix++)
{
{
frame->formants[ix].freq = 0;
frame->peaks[ix].pkfreq = default_freq[ix];
frame->peaks[ix].pkheight = 0;
@@ -132,7 +132,7 @@ static SpectFrame *SpectFrameCreate()
frame->peaks[ix].klt_bw = default_klt_bw[ix];
frame->peaks[ix].klt_ap = 0;
frame->peaks[ix].klt_bp = default_klt_bw[ix];
}
}

memset(frame->klatt_param, 0, sizeof(frame->klatt_param));
frame->klatt_param[KLATT_AV] = 59;
@@ -212,7 +212,7 @@ int LoadFrame(SpectFrame *frame, FILE *stream, int file_format_type)
spect_data[ix] = x;
if(x > frame->max_y) frame->max_y = x;
}
frame->spect = spect_data;
frame->spect = spect_data;

return(0);
}
@@ -255,12 +255,12 @@ SpectSeq *SpectSeqCreate()
spect->numframes = 0;
spect->frames = NULL;
spect->name = NULL;
pk_select = 1;
spect->grid = 1;
spect->duration = 0;
spect->pitch1 = 0;
spect->pitch2 = 0;
spect->duration = 0;
spect->pitch1 = 0;
spect->pitch2 = 0;
spect->bass_reduction = 0;

spect->max_x = 3000;
@@ -289,11 +289,11 @@ void SpectSeqDestroy(SpectSeq *spect)

static float GetFrameLength(SpectSeq *spect, int frame)
{
int ix;
float adjust=0;
int ix;
float adjust=0;

if(frame >= spect->numframes-1) return(0);
for(ix=frame+1; ix<spect->numframes-1; ix++)
{
if(spect->frames[ix]->keyframe) break; // reached next keyframe
@@ -324,17 +324,17 @@ int LoadSpectSeq(SpectSeq *spect, const char *filename)

if((id1 == FILEID1_SPECTSEQ) && (id2 == FILEID2_SPECTSEQ))
{
spect->file_format = 0; // eSpeak formants
spect->file_format = 0; // eSpeak formants
}
else
if((id1 == FILEID1_SPECTSEQ) && (id2 == FILEID2_SPECTSEK))
{
spect->file_format = 1; // formants for Klatt synthesizer
spect->file_format = 1; // formants for Klatt synthesizer
}
else
if((id1 == FILEID1_SPECTSEQ) && (id2 == FILEID2_SPECTSQ2))
{
spect->file_format = 2; // formants for Klatt synthesizer
spect->file_format = 2; // formants for Klatt synthesizer
}
else
{
@@ -392,7 +392,7 @@ int LoadSpectSeq(SpectSeq *spect, const char *filename)
spect->max_y = frame->max_y;
if(frame->nx * frame->dx > spect->max_x) spect->max_x = (int)(frame->nx * frame->dx);
}
spect->max_x = 9000; // disable auto-xscaling
spect->max_x = 9000; // disable auto-xscaling

frame_width = (int)((FRAME_WIDTH*spect->max_x)/MAX_DISPLAY_FREQ);
if(frame_width > FRAME_WIDTH) frame_width = FRAME_WIDTH;
@@ -407,10 +407,10 @@ spect->max_x = 9000; // disable auto-xscaling
spect->pitch2 = spect->pitchenv.pitch2;
spect->duration = (int)(spect->frames[spect->numframes-1]->time * 1000);

if(spect->max_y < 400)
spect->max_y = 200;
else
spect->max_y = 29000; // disable auto height scaling
if(spect->max_y < 400)
spect->max_y = 200;
else
spect->max_y = 29000; // disable auto height scaling

for(ix=0; ix<spect->numframes; ix++)
{

+ 20
- 20
src/libespeak-ng/spect.h View File

@@ -95,37 +95,37 @@ typedef struct
float length_adjust;
double rms;

float time;
float pitch;
float length;
float dx;
unsigned short nx;
short markers;
int max_y;
USHORT *spect; // sqrt of harmonic amplitudes, 1-nx at 'pitch'
short klatt_param[N_KLATTP2];
formant_t formants[N_PEAKS]; // this is just the estimate given by Praat
peak_t peaks[N_PEAKS];
float time;
float pitch;
float length;
float dx;
unsigned short nx;
short markers;
int max_y;
USHORT *spect; // sqrt of harmonic amplitudes, 1-nx at 'pitch'
short klatt_param[N_KLATTP2];
formant_t formants[N_PEAKS]; // this is just the estimate given by Praat
peak_t peaks[N_PEAKS];
} SpectFrame;

double GetFrameRms(SpectFrame *frame, int amp);

typedef struct
{
int numframes;
int numframes;
short amplitude;
int spare;
int spare;
char *name;

SpectFrame **frames;
PitchEnvelope pitchenv;
int pitch1;
int pitch2;
int duration;
int grid;
int bass_reduction;
int pitch1;
int pitch2;
int duration;
int grid;
int bass_reduction;
int max_x;
short max_y;
int file_format;

+ 3
- 3
src/libespeak-ng/speech.h View File

@@ -53,15 +53,15 @@ extern "C"
#endif

typedef unsigned short USHORT;
typedef unsigned char UCHAR;
typedef unsigned char UCHAR;
typedef double DOUBLEX;
typedef unsigned long long64; // use this for conversion between pointers and integers



typedef struct {
const char *mnem;
int value;
const char *mnem;
int value;
} MNEM_TAB;
int LookupMnem(MNEM_TAB *table, const char *string);


+ 26
- 26
src/libespeak-ng/synth_mbrola.c View File

@@ -49,25 +49,25 @@ typedef void (WINAPI *PROCVV)(void);
typedef void (WINAPI *PROCVI)(int);
typedef void (WINAPI *PROCVF)(float);
typedef int (WINAPI *PROCIV)();
typedef int (WINAPI *PROCIC) (char *);
typedef int (WINAPI *PROCIC)(char *);
typedef int (WINAPI *PROCISI)(short *,int);
typedef char* (WINAPI *PROCVCI)(char *,int);

PROCIC init_MBR;
PROCIC write_MBR;
PROCIV flush_MBR;
PROCISI read_MBR;
PROCVV close_MBR;
PROCVV reset_MBR;
PROCIV lastError_MBR;
PROCVCI lastErrorStr_MBR;
PROCVI setNoError_MBR;
PROCIV getFreq_MBR;
PROCVF setVolumeRatio_MBR;
PROCIC init_MBR;
PROCIC write_MBR;
PROCIV flush_MBR;
PROCISI read_MBR;
PROCVV close_MBR;
PROCVV reset_MBR;
PROCIV lastError_MBR;
PROCVCI lastErrorStr_MBR;
PROCVI setNoError_MBR;
PROCIV getFreq_MBR;
PROCVF setVolumeRatio_MBR;



HINSTANCE hinstDllMBR = NULL;
HINSTANCE hinstDllMBR = NULL;


BOOL load_MBR()
@@ -77,16 +77,16 @@ BOOL load_MBR()

if ((hinstDllMBR=LoadLibraryA("mbrola.dll")) == 0)
return FALSE;
init_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"init_MBR");
write_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"write_MBR");
flush_MBR =(PROCIV) GetProcAddress(hinstDllMBR,"flush_MBR");
read_MBR =(PROCISI) GetProcAddress(hinstDllMBR,"read_MBR");
close_MBR =(PROCVV) GetProcAddress(hinstDllMBR,"close_MBR");
reset_MBR =(PROCVV) GetProcAddress(hinstDllMBR,"reset_MBR");
lastError_MBR =(PROCIV) GetProcAddress(hinstDllMBR,"lastError_MBR");
lastErrorStr_MBR =(PROCVCI) GetProcAddress(hinstDllMBR,"lastErrorStr_MBR");
setNoError_MBR =(PROCVI) GetProcAddress(hinstDllMBR,"setNoError_MBR");
setVolumeRatio_MBR =(PROCVF) GetProcAddress(hinstDllMBR,"setVolumeRatio_MBR");
init_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"init_MBR");
write_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"write_MBR");
flush_MBR =(PROCIV) GetProcAddress(hinstDllMBR,"flush_MBR");
read_MBR =(PROCISI) GetProcAddress(hinstDllMBR,"read_MBR");
close_MBR =(PROCVV) GetProcAddress(hinstDllMBR,"close_MBR");
reset_MBR =(PROCVV) GetProcAddress(hinstDllMBR,"reset_MBR");
lastError_MBR =(PROCIV) GetProcAddress(hinstDllMBR,"lastError_MBR");
lastErrorStr_MBR =(PROCVCI) GetProcAddress(hinstDllMBR,"lastErrorStr_MBR");
setNoError_MBR =(PROCVI) GetProcAddress(hinstDllMBR,"setNoError_MBR");
setVolumeRatio_MBR =(PROCVF) GetProcAddress(hinstDllMBR,"setVolumeRatio_MBR");
return TRUE;
}

@@ -134,7 +134,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
// usr/share/mbrola/xx, /usr/share/mbrola/xx/xx, /usr/share/mbrola/voices/xx
if(GetFileLength(path) <= 0)
{
sprintf(path,"/usr/share/mbrola/%s",mbrola_voice);
sprintf(path,"/usr/share/mbrola/%s",mbrola_voice);

if(GetFileLength(path) <= 0)
{
@@ -243,8 +243,8 @@ static int GetMbrName(PHONEME_LIST *plist, PHONEME_TAB *ph, PHONEME_TAB *ph_prev
other_ph = ph_next;

if((pr->next_phoneme == other_ph->mnemonic) ||
((pr->next_phoneme == 2) && (other_ph->type == phVOWEL)) ||
((pr->next_phoneme == '_') && (other_ph->type == phPAUSE)))
((pr->next_phoneme == 2) && (other_ph->type == phVOWEL)) ||
((pr->next_phoneme == '_') && (other_ph->type == phPAUSE)))
{
found = 1;
}

+ 75
- 75
src/libespeak-ng/synthdata.c View File

@@ -74,7 +74,7 @@ static char *ReadPhFile(void *ptr, const char *fname, int *size)
{
FILE *f_in;
char *p;
unsigned int length;
unsigned int length;
char buf[sizeof(path_home)+40];

sprintf(buf,"%s%c%s",path_home,PATHSEP,fname);
@@ -127,7 +127,7 @@ int LoadPhData(int *srate)
return(-1);
if((tunes = (TUNE *)ReadPhFile((void *)(tunes),"intonations",&length)) == NULL)
return(-1);
wavefile_data = (unsigned char *)phondata_ptr;
wavefile_data = (unsigned char *)phondata_ptr;
n_tunes = length / sizeof(TUNE);

// read the version number and sample rate from the first 8 bytes of phondata
@@ -166,8 +166,8 @@ int LoadPhData(int *srate)
if(phoneme_tab_number >= n_phoneme_tables)
phoneme_tab_number = 0;

if(srate != NULL)
*srate = rate;
if(srate != NULL)
*srate = rate;
return(result);
}

@@ -202,9 +202,9 @@ int PhonemeCode(unsigned int mnem)

int LookupPhonemeString(const char *string)
{
int ix;
int ix;
unsigned char c;
unsigned int mnem;
unsigned int mnem;

// Pack up to 4 characters into a word
mnem = 0;
@@ -223,14 +223,14 @@ int LookupPhonemeString(const char *string)

frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, int *n_frames, PHONEME_LIST *plist)
{
int ix;
int nf;
int nf1;
int seq_break;
int ix;
int nf;
int nf1;
int seq_break;
frameref_t *frames;
int length1;
int length_std;
int length_factor;
int length1;
int length_std;
int length_factor;
SPECT_SEQ *seq, *seq2;
SPECT_SEQK *seqk, *seqk2;
frame_t *frame;
@@ -604,7 +604,7 @@ static int CountVowelPosition(PHONEME_LIST *plist)
{
int count = 0;

for(;;)
for(;; )
{
if(plist->ph->type == phVOWEL)
count++;
@@ -647,9 +647,9 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,

if(which==6)
{
// the 'which' code is in the next instruction
p_prog++;
which = (*p_prog);
// the 'which' code is in the next instruction
p_prog++;
which = (*p_prog);
}

if(which==4)
@@ -665,37 +665,37 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
return(false);
}
if(which==6)
{
// next2PhW, not word boundary
if(plist[1].sourceix || plist[2].sourceix)
return(false);
}
switch(which)
{
case 0: // prevPh
case 5: // prevPhW
plist--;
check_endtype = 1;
break;
case 1: // thisPh
break;
case 2: // nextPh
case 4: // nextPhW
plist++;
break;
case 3: // next2Ph
case 6: // next2PhW
plist += 2;
break;
case 7:
{
// next2PhW, not word boundary
if(plist[1].sourceix || plist[2].sourceix)
return(false);
}
switch(which)
{
case 0: // prevPh
case 5: // prevPhW
plist--;
check_endtype = 1;
break;
case 1: // thisPh
break;
case 2: // nextPh
case 4: // nextPhW
plist++;
break;
case 3: // next2Ph
case 6: // next2PhW
plist += 2;
break;
case 7:
// nextVowel, not word boundary
for(which=1;;which++)
for(which=1;; which++)
{
if(plist[which].sourceix)
return(false);
@@ -707,12 +707,12 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
}
break;

case 8: // prevVowel in this word
if((worddata==NULL) || (worddata->prev_vowel.ph == NULL))
return(false); // no previous vowel
plist = &(worddata->prev_vowel);
case 8: // prevVowel in this word
if((worddata==NULL) || (worddata->prev_vowel.ph == NULL))
return(false); // no previous vowel
plist = &(worddata->prev_vowel);
check_endtype = 1;
break;
break;

case 9: // next3PhW
for(ix=1; ix<=3; ix++)
@@ -729,7 +729,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
plist-=2;
check_endtype = 1;
break;
}
}

if((which == 0) || (which == 5))
{
@@ -816,7 +816,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
return(ph->type != phVOWEL);

case 11: // isFinalVowel
for(;;)
for(;; )
{
plist++;
// plist->ph = phoneme_tab[plist->phcode]; // Why was this line here?? It corrupts plist if we have language switching if phoneme_tab is wrong language
@@ -842,7 +842,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
return(false); // this is the first phoneme in the word, so no.

count = 0;
for(;;)
for(;; )
{
plist--;
if(plist->ph->type == phVOWEL)
@@ -992,8 +992,8 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_

if((worddata != NULL) && (plist->sourceix))
{
// start of a word, reset word data
worddata->prev_vowel.ph = NULL;
// start of a word, reset word data
worddata->prev_vowel.ph = NULL;
}

memset(phdata, 0, sizeof(PHONEME_DATA));
@@ -1137,7 +1137,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
}
}
prog--;
break;
break;

case 6:
// JUMP
@@ -1159,7 +1159,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
SwitchOnVowelType(plist, phdata, &prog, 3);
break;
}
break;
break;

case 9:
data = ((instn & 0xf) << 16) + prog[1];
@@ -1233,7 +1233,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
phdata->sound_param[instn2] = param_sc; // sign extend
}
}
break;
break;

default:
InvalidInstn(ph,instn);
@@ -1253,21 +1253,21 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
}
}

if((worddata != NULL) && (plist->type == phVOWEL))
{
memcpy(&worddata->prev_vowel, &plist[0], sizeof(PHONEME_LIST));
}
plist->std_length = phdata->pd_param[i_SET_LENGTH];
if(phdata->sound_addr[0] != 0)
{
plist->phontab_addr = phdata->sound_addr[0]; // FMT address
plist->sound_param = phdata->sound_param[0];
}
else
{
plist->phontab_addr = phdata->sound_addr[1]; // WAV address
plist->sound_param = phdata->sound_param[1];
if((worddata != NULL) && (plist->type == phVOWEL))
{
memcpy(&worddata->prev_vowel, &plist[0], sizeof(PHONEME_LIST));
}
plist->std_length = phdata->pd_param[i_SET_LENGTH];
if(phdata->sound_addr[0] != 0)
{
plist->phontab_addr = phdata->sound_addr[0]; // FMT address
plist->sound_param = phdata->sound_param[0];
}
else
{
plist->phontab_addr = phdata->sound_addr[1]; // WAV address
plist->sound_param = phdata->sound_param[1];
}
}


+ 67
- 66
src/libespeak-ng/synthesize.c View File

@@ -46,18 +46,18 @@ char mbrola_name[20];

SPEED_FACTORS speed;

static int last_pitch_cmd;
static int last_amp_cmd;
static int last_pitch_cmd;
static int last_amp_cmd;
static frame_t *last_frame;
static int last_wcmdq;
static int pitch_length;
static int amp_length;
static int modn_flags;
static int fmt_amplitude=0;
static int last_wcmdq;
static int pitch_length;
static int amp_length;
static int modn_flags;
static int fmt_amplitude=0;

static int syllable_start;
static int syllable_end;
static int syllable_centre;
static int syllable_start;
static int syllable_end;
static int syllable_centre;

static voice_t *new_voice=NULL;

@@ -78,7 +78,7 @@ static PHONEME_LIST next_pause;
const char *WordToString(unsigned int word)
{
// Convert a phoneme mnemonic word into a string
int ix;
int ix;
static char buf[5];

for(ix=0; ix<4; ix++)
@@ -457,19 +457,20 @@ static void set_frame_rms(frame_t *fr, int new_rms)
int ix;

static const short sqrt_tab[200] = {
0, 64, 90,110,128,143,156,169,181,192,202,212,221,230,239,247,
256,263,271,278,286,293,300,306,313,320,326,332,338,344,350,356,
362,367,373,378,384,389,394,399,404,409,414,419,424,429,434,438,
443,448,452,457,461,465,470,474,478,483,487,491,495,499,503,507,
512,515,519,523,527,531,535,539,543,546,550,554,557,561,565,568,
572,576,579,583,586,590,593,596,600,603,607,610,613,617,620,623,
627,630,633,636,640,643,646,649,652,655,658,662,665,668,671,674,
677,680,683,686,689,692,695,698,701,704,706,709,712,715,718,721,
724,726,729,732,735,738,740,743,746,749,751,754,757,759,762,765,
768,770,773,775,778,781,783,786,789,791,794,796,799,801,804,807,
809,812,814,817,819,822,824,827,829,832,834,836,839,841,844,846,
849,851,853,856,858,861,863,865,868,870,872,875,877,879,882,884,
886,889,891,893,896,898,900,902};
0, 64, 90,110,128,143,156,169,181,192,202,212,221,230,239,247,
256,263,271,278,286,293,300,306,313,320,326,332,338,344,350,356,
362,367,373,378,384,389,394,399,404,409,414,419,424,429,434,438,
443,448,452,457,461,465,470,474,478,483,487,491,495,499,503,507,
512,515,519,523,527,531,535,539,543,546,550,554,557,561,565,568,
572,576,579,583,586,590,593,596,600,603,607,610,613,617,620,623,
627,630,633,636,640,643,646,649,652,655,658,662,665,668,671,674,
677,680,683,686,689,692,695,698,701,704,706,709,712,715,718,721,
724,726,729,732,735,738,740,743,746,749,751,754,757,759,762,765,
768,770,773,775,778,781,783,786,789,791,794,796,799,801,804,807,
809,812,814,817,819,822,824,827,829,832,834,836,839,841,844,846,
849,851,853,856,858,861,863,865,868,870,872,875,877,879,882,884,
886,889,891,893,896,898,900,902
};

if(voice->klattv[0])
{
@@ -498,8 +499,8 @@ static void set_frame_rms(frame_t *fr, int new_rms)
static void formants_reduce_hf(frame_t *fr, int level)
{
// change height of peaks 2 to 8, percentage
int ix;
int x;
int ix;
int x;

if(voice->klattv[0])
return;
@@ -626,10 +627,10 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig

#define N_VCOLOUR 2
// percentage change for each formant in 256ths
static short vcolouring[N_VCOLOUR][5] = {
{243,272,256,256,256}, // palatal consonant follows
{256,256,240,240,240}, // retroflex
};
static short vcolouring[N_VCOLOUR][5] = {
{243,272,256,256,256}, // palatal consonant follows
{256,256,240,240,240}, // retroflex
};

frame_t *fr = NULL;

@@ -664,10 +665,10 @@ static short vcolouring[N_VCOLOUR][5] = {

next_rms = seq[1].frame->rms;

if(voice->klattv[0])
{
fr->klattp[KLATT_AV] = seq[1].frame->klattp[KLATT_AV] - 4;
}
if(voice->klattv[0])
{
fr->klattp[KLATT_AV] = seq[1].frame->klattp[KLATT_AV] - 4;
}
if(f2 != 0)
{
if(rms & 0x20)
@@ -791,7 +792,7 @@ static void SmoothSpect(void)
// backwards
ix = syllable_centre -1;
frame = frame2 = frame_centre;
for(;;)
for(;; )
{
if(ix < 0) ix = N_WCMDQ-1;
q = wcmdq[ix];
@@ -879,7 +880,7 @@ static void SmoothSpect(void)
ix = syllable_centre;

frame = NULL;
for(;;)
for(;; )
{
q = wcmdq[ix];

@@ -979,21 +980,21 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L
// length_mod: 256 = 100%
// modulation: -1 = don't write to wcmdq

int n_frames;
int n_frames;
frameref_t *frames;
int frameix;
int frameix;
frame_t *frame1;
frame_t *frame2;
frame_t *fr;
int ix;
int ix;
long64 *q;
int len;
int frame_length;
int length_factor;
int length_mod;
int length_sum;
int length_min;
int total_len = 0;
int len;
int frame_length;
int length_factor;
int length_mod;
int length_sum;
int length_min;
int total_len = 0;
static int wave_flag = 0;
int wcmd_spect = WCMD_SPECT;
int frame_lengths[N_SEQ_FRAMES];
@@ -1011,17 +1012,17 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L
length_min *= 2; // ensure long vowels are longer
}

if(which==1)
{
// limit the shortening of sonorants before shortened (eg. unstressed vowels)
if((this_ph->type==phLIQUID) || (plist[-1].type==phLIQUID) || (plist[-1].type==phNASAL))
if(which==1)
{
if(length_mod < (len = translator->langopts.param[LOPT_SONORANT_MIN]))
// limit the shortening of sonorants before shortened (eg. unstressed vowels)
if((this_ph->type==phLIQUID) || (plist[-1].type==phLIQUID) || (plist[-1].type==phNASAL))
{
length_mod = len;
if(length_mod < (len = translator->langopts.param[LOPT_SONORANT_MIN]))
{
length_mod = len;
}
}
}
}

modn_flags = 0;
frames = LookupSpect(this_ph, which, fmt_params, &n_frames, plist);
@@ -1069,7 +1070,7 @@ if(which==1)
if(last_frame != NULL)
{
if(((last_frame->length < 2) || (last_frame->frflags & FRFLAG_VOWEL_CENTRE))
&& !(last_frame->frflags & FRFLAG_BREAK))
&& !(last_frame->frflags & FRFLAG_BREAK))
{
// last frame of previous sequence was zero-length, replace with first of this sequence
wcmdq[last_wcmdq][3] = (long64)frame1;
@@ -1312,19 +1313,19 @@ void DoEmbedded(int *embix, int sourceix)

int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
{
static int ix;
static int embedded_ix;
static int word_count;
static int ix;
static int embedded_ix;
static int word_count;
PHONEME_LIST *prev;
PHONEME_LIST *next;
PHONEME_LIST *next2;
PHONEME_LIST *p;
int released;
int stress;
int modulation;
int pre_voiced;
int free_min;
int value;
int released;
int stress;
int modulation;
int pre_voiced;
int free_min;
int value;
unsigned char *pitch_env=NULL;
unsigned char *amp_env;
PHONEME_TAB *ph;
@@ -1395,7 +1396,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
if(p->newword)
{
if(((p->type == phVOWEL) && (translator->langopts.param[LOPT_WORD_MERGE] & 1)) ||
(p->ph->phflags & phNOPAUSE))
(p->ph->phflags & phNOPAUSE))
{
}
else
@@ -1439,7 +1440,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
{
case phPAUSE:
DoPause(p->length,0);
p->std_length = p->ph->std_length;
p->std_length = p->ph->std_length;
break;

case phSTOP:
@@ -1447,7 +1448,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
ph = p->ph;
if(next->type==phVOWEL)
{
released = 1;
released = 1;
}
else
if(!next->newword)

+ 40
- 40
src/libespeak-ng/synthesize.h View File

@@ -146,24 +146,24 @@ typedef struct {
} wavegen_peaks_t;

typedef struct {
unsigned char *pitch_env;
int pitch; // pitch Hz*256
int pitch_ix; // index into pitch envelope (*256)
int pitch_inc; // increment to pitch_ix
int pitch_base; // Hz*256 low, before modified by envelope
int pitch_range; // Hz*256 range of envelope
unsigned char *mix_wavefile; // wave file to be added to synthesis
int n_mix_wavefile; // length in bytes
int mix_wave_scale; // 0=2 byte samples
int mix_wave_amp;
int mix_wavefile_ix;
int mix_wavefile_max; // length of available WAV data (in bytes)
int mix_wavefile_offset;
int amplitude;
int amplitude_v;
int amplitude_fmt; // percentage amplitude adjustment for formant synthesis
unsigned char *pitch_env;
int pitch; // pitch Hz*256
int pitch_ix; // index into pitch envelope (*256)
int pitch_inc; // increment to pitch_ix
int pitch_base; // Hz*256 low, before modified by envelope
int pitch_range; // Hz*256 range of envelope
unsigned char *mix_wavefile; // wave file to be added to synthesis
int n_mix_wavefile; // length in bytes
int mix_wave_scale; // 0=2 byte samples
int mix_wave_amp;
int mix_wavefile_ix;
int mix_wavefile_max; // length of available WAV data (in bytes)
int mix_wavefile_offset;
int amplitude;
int amplitude_v;
int amplitude_fmt; // percentage amplitude adjustment for formant synthesis
} WGEN_DATA;


@@ -177,17 +177,17 @@ typedef struct {


typedef struct {
short length_total; // not used
unsigned char n_frames;
unsigned char sqflags;
frame_t2 frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
short length_total; // not used
unsigned char n_frames;
unsigned char sqflags;
frame_t2 frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
} SPECT_SEQ; // sequence of espeak formant frames

typedef struct {
short length_total; // not used
unsigned char n_frames;
unsigned char sqflags;
frame_t frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
short length_total; // not used
unsigned char n_frames;
unsigned char sqflags;
frame_t frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
} SPECT_SEQK; // sequence of klatt formants frames


@@ -277,7 +277,7 @@ typedef struct {
} FMT_PARAMS;

typedef struct {
PHONEME_LIST prev_vowel;
PHONEME_LIST prev_vowel;
} WORD_PH_DATA;

// instructions
@@ -373,12 +373,12 @@ typedef struct {
} SOUND_ICON;

typedef struct {
int name;
unsigned int next_phoneme;
int mbr_name;
int mbr_name2;
int percent; // percentage length of first component
int control;
int name;
unsigned int next_phoneme;
int mbr_name;
int mbr_name2;
int percent; // percentage length of first component
int control;
} MBROLA_TAB;

typedef struct {
@@ -457,16 +457,16 @@ extern unsigned char env_frise[128];
extern unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1];

// queue of commands for wavegen
#define WCMD_KLATT 1
#define WCMD_KLATT2 2
#define WCMD_SPECT 3
#define WCMD_SPECT2 4
#define WCMD_PAUSE 5
#define WCMD_KLATT 1
#define WCMD_KLATT2 2
#define WCMD_SPECT 3
#define WCMD_SPECT2 4
#define WCMD_PAUSE 5
#define WCMD_WAVE 6
#define WCMD_WAVE2 7
#define WCMD_AMPLITUDE 8
#define WCMD_PITCH 9
#define WCMD_MARKER 10
#define WCMD_PITCH 9
#define WCMD_MARKER 10
#define WCMD_VOICE 11
#define WCMD_EMBEDDED 12
#define WCMD_MBROLA_DATA 13

+ 1072
- 1066
src/libespeak-ng/tr_languages.c
File diff suppressed because it is too large
View File


+ 39
- 39
src/libespeak-ng/translate.c View File

@@ -86,7 +86,7 @@ char word_phonemes[N_WORD_PHONEMES*2]; // longer, because snprint() is not av
char word_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes
#endif
int n_ph_list2;
PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes
PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes



@@ -374,7 +374,7 @@ int IsAlpha(unsigned int c)
// Replacement for iswalph() which also checks for some in-word symbols

static const unsigned short extra_indic_alphas[] = {
0xa70,0xa71, // Gurmukhi: tippi, addak
0xa70,0xa71, // Gurmukhi: tippi, addak
0
};

@@ -669,7 +669,7 @@ static int CheckDottedAbbrev(char *word1, WORD_TAB *wtab)
wbuf = word_buf;
ix = 0;

for(;;)
for(;; )
{
ok = 0;
nbytes = utf8_in(&wc, word);
@@ -728,13 +728,13 @@ int ChangeEquivalentPhonemes(Translator *tr, int lang2, char *phonemes)

int ix;
int len;
char phon;
char phon;
char *p;
unsigned char *pb;
char *eqlist;
char *p_out;
char *p_in;
int remove_stress = 0;
int remove_stress = 0;
char phonbuf[N_WORD_PHONEMES];

// has a phoneme equivalence table been specified for thus language pair?
@@ -743,7 +743,7 @@ int ChangeEquivalentPhonemes(Translator *tr, int lang2, char *phonemes)

pb = (unsigned char *)&phondata_ptr[ix];

for(;;)
for(;; )
{
if(pb[0] == 0)
return(0); // table not found
@@ -1057,7 +1057,7 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
emphasize_allcaps = FLAG_EMPHASIZED;
}
else if(!found && !(dictionary_flags[0] & FLAG_SKIPWORDS) && (word_length<4) && (tr->clause_lower_count > 3)
&& (tr->clause_upper_count <= tr->clause_lower_count))
&& (tr->clause_upper_count <= tr->clause_lower_count))
{
// An upper case word in a lower case clause. This could be an abbreviation.
spell_word = 1;
@@ -1845,7 +1845,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
{
// switch languages
word+=3;
for(ix=0;;)
for(ix=0;; )
{
c1 = *word++;
if((c1==' ') || (c1==0))
@@ -2224,7 +2224,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
if(first_phoneme && tr->langopts.param[LOPT_IT_DOUBLING])
{
if(((tr->prev_dict_flags[0] & FLAG_DOUBLING) && (tr->langopts.param[LOPT_IT_DOUBLING] & 1)) ||
(tr->end_stressed_vowel && (tr->langopts.param[LOPT_IT_DOUBLING] & 2)))
(tr->end_stressed_vowel && (tr->langopts.param[LOPT_IT_DOUBLING] & 2)))
{
// italian, double the initial consonant if the previous word ends with a
// stressed vowel, or is marked with a flag
@@ -2512,7 +2512,7 @@ int UpperCaseInWord(Translator *tr, char *word, int c)
if(tr->translator_name == L('g','a'))
{
// Irish
for(ix=0; ; ix++)
for(ix=0;; ix++)
{
if((p = UCase_ga[ix]) == NULL)
break;
@@ -2614,7 +2614,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t

clause_pause = (terminator & 0xfff) * 10; // mS
if(terminator & CLAUSE_PAUSE_LONG)
clause_pause = clause_pause * 32 ; // pause value is *320mS not *10mS
clause_pause = clause_pause * 32; // pause value is *320mS not *10mS

tone = (terminator >> 12) & 0x7;
if(tone2 != 0)
@@ -2924,7 +2924,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
if(tr->letter_bits_offset > 0)
{
if(((c < 0x250) && (prev_out >= tr->letter_bits_offset)) ||
((c >= tr->letter_bits_offset) && (letter_count > 1) && (prev_out < 0x250)))
((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
@@ -3109,34 +3109,34 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
}
}
else
if(lookupwchar(breaks,c) != 0)
if(lookupwchar(breaks,c) != 0)
{
c = ' '; // various characters to treat as space
}
else if(iswdigit(c))
{
if(tr->langopts.tone_numbers && IsAlpha(prev_out) && !IsDigit(next_in))
{
}
else if((prev_out != ' ') && !iswdigit(prev_out))
{
if((prev_out != tr->langopts.decimal_sep) || ((decimal_sep_count > 0) && (tr->langopts.decimal_sep == ',')))
{
c = ' '; // various characters to treat as space
c = ' ';
space_inserted = 1;
}
else if(iswdigit(c))
else
{
if(tr->langopts.tone_numbers && IsAlpha(prev_out) && !IsDigit(next_in))
{
}
else if((prev_out != ' ') && !iswdigit(prev_out))
{
if((prev_out != tr->langopts.decimal_sep) || ((decimal_sep_count > 0) && (tr->langopts.decimal_sep == ',')))
{
c = ' ';
space_inserted = 1;
}
else
{
decimal_sep_count = 1;
}
}
else if((prev_out == ' ') && IsAlpha(prev_out2) && !IsAlpha(prev_in))
{
// insert extra space between a word and a number, to distinguish 'a 2' from 'a2'
sbuf[ix++] = ' ';
words[word_count].start++;
}
decimal_sep_count = 1;
}
}
else if((prev_out == ' ') && IsAlpha(prev_out2) && !IsAlpha(prev_in))
{
// insert extra space between a word and a number, to distinguish 'a 2' from 'a2'
sbuf[ix++] = ' ';
words[word_count].start++;
}
}
}

if(IsSpace(c))
@@ -3299,7 +3299,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
*pn++ = *pw++;
}
else if((*pw == tr->langopts.thousands_sep) && (pw[1] == ' ')
&& iswdigit(pw[2]) && (pw[3] != ' ') && (pw[4] != ' ')) // don't allow only 1 or 2 digits in the final part
&& iswdigit(pw[2]) && (pw[3] != ' ') && (pw[4] != ' ')) // don't allow only 1 or 2 digits in the final part
{
pw += 2;
ix++; // skip "word"
@@ -3375,7 +3375,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
pn[16] = 0;
nw = 0;

for(pw = &number_buf[1]; pw < pn;)
for(pw = &number_buf[1]; pw < pn; )
{
// keep wflags for each part, for FLAG_HYPHEN_AFTER
dict_flags = TranslateWord2(tr, pw, &num_wtab[nw++], words[ix].pre_pause,0 );
@@ -3398,7 +3398,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
if(dict_flags & FLAG_SPELLWORD)
{
// redo the word, speaking single letters
for(pw = word; *pw != ' ';)
for(pw = word; *pw != ' '; )
{
memset(number_buf,' ',9);
nx = utf8_in(&c_temp, pw);

+ 76
- 76
src/libespeak-ng/translate.h View File

@@ -158,25 +158,25 @@ extern "C"


// codes in dictionary rules
#define RULE_PRE 1
#define RULE_POST 2
#define RULE_PHONEMES 3
#define RULE_PH_COMMON 4 // At start of rule. Its phoneme string is used by subsequent rules
#define RULE_CONDITION 5 // followed by condition number (byte)
#define RULE_PRE 1
#define RULE_POST 2
#define RULE_PHONEMES 3
#define RULE_PH_COMMON 4 // At start of rule. Its phoneme string is used by subsequent rules
#define RULE_CONDITION 5 // followed by condition number (byte)
#define RULE_GROUP_START 6
#define RULE_GROUP_END 7
#define RULE_GROUP_END 7
#define RULE_PRE_ATSTART 8 // as RULE_PRE but also match with 'start of word'
#define RULE_LINENUM 9 // next 2 bytes give a line number, for debugging purposes
#define RULE_SPACE 32 // ascii space
#define RULE_SYLLABLE 21 // @
#define RULE_STRESSED 10 // &
#define RULE_DOUBLE 11 // %
#define RULE_INC_SCORE 12 // +
#define RULE_DEL_FWD 13 // #
#define RULE_ENDING 14 // S
#define RULE_DIGIT 15 // D digit
#define RULE_NONALPHA 16 // Z non-alpha
#define RULE_LINENUM 9 // next 2 bytes give a line number, for debugging purposes
#define RULE_SPACE 32 // ascii space
#define RULE_SYLLABLE 21 // @
#define RULE_STRESSED 10 // &
#define RULE_DOUBLE 11 // %
#define RULE_INC_SCORE 12 // +
#define RULE_DEL_FWD 13 // #
#define RULE_ENDING 14 // S
#define RULE_DIGIT 15 // D digit
#define RULE_NONALPHA 16 // Z non-alpha
#define RULE_LETTERGP 17 // A B C H F G Y letter group number
#define RULE_LETTERGP2 18 // L + letter group number
#define RULE_CAPITAL 19 // ! word starts with a capital letter
@@ -195,13 +195,13 @@ extern "C"
#define DOLLAR_LIST 0x03


#define LETTERGP_A 0
#define LETTERGP_B 1
#define LETTERGP_C 2
#define LETTERGP_H 3
#define LETTERGP_F 4
#define LETTERGP_G 5
#define LETTERGP_Y 6
#define LETTERGP_A 0
#define LETTERGP_B 1
#define LETTERGP_C 2
#define LETTERGP_H 3
#define LETTERGP_F 4
#define LETTERGP_G 5
#define LETTERGP_Y 6
#define LETTERGP_VOWEL2 7


@@ -256,15 +256,15 @@ extern "C"
typedef const char * constcharptr;

typedef struct {
int points;
int points;
const char *phonemes;
int end_type;
int end_type;
char *del_fwd;
} MatchRecord;


// used to mark words with the source[] buffer
typedef struct{
typedef struct {
unsigned int flags;
unsigned short start;
unsigned char pre_pause;
@@ -284,11 +284,11 @@ extern const int param_defaults[N_SPEECH_PARAM];


typedef struct {
const char *name;
int offset;
unsigned short range_min, range_max;
int language;
int flags;
const char *name;
int offset;
unsigned short range_min, range_max;
int language;
int flags;
} ALPHABET;

extern ALPHABET alphabets[];
@@ -303,85 +303,85 @@ extern ALPHABET *current_alphabet;

#define N_LOPTS 21
#define LOPT_DIERESES 1
// 1=remove [:] from unstressed syllables, 2= remove from unstressed or non-penultimate syllables
// bit 4=0, if stress < 4, bit 4=1, if not the highest stress in the word
// 1=remove [:] from unstressed syllables, 2= remove from unstressed or non-penultimate syllables
// bit 4=0, if stress < 4, bit 4=1, if not the highest stress in the word
#define LOPT_IT_LENGTHEN 2

// 1=german
// 1=german
#define LOPT_PREFIXES 3

// non-zero, change voiced/unoiced to match last consonant in a cluster
// bit 0=use regressive voicing
// bit 1=LANG=cz,bg don't propagate over [v]
// bit 2=don't propagate acress word boundaries
// bit 3=LANG=pl, propagate over liquids and nasals
// bit 4=LANG=cz,sk don't progagate to [v]
// bit 8=devoice word-final consonants
// non-zero, change voiced/unoiced to match last consonant in a cluster
// bit 0=use regressive voicing
// bit 1=LANG=cz,bg don't propagate over [v]
// bit 2=don't propagate acress word boundaries
// bit 3=LANG=pl, propagate over liquids and nasals
// bit 4=LANG=cz,sk don't progagate to [v]
// bit 8=devoice word-final consonants
#define LOPT_REGRESSIVE_VOICING 4

// 0=default, 1=no check, other allow this character as an extra initial letter (default is 's')
// 0=default, 1=no check, other allow this character as an extra initial letter (default is 's')
#define LOPT_UNPRONOUNCABLE 5

// select length_mods tables, (length_mod_tab) + (length_mod_tab0 * 100)
// select length_mods tables, (length_mod_tab) + (length_mod_tab0 * 100)
#define LOPT_LENGTH_MODS 6

// increase this to prevent sonorants being shortened before shortened (eg. unstressed) vowels
// increase this to prevent sonorants being shortened before shortened (eg. unstressed) vowels
#define LOPT_SONORANT_MIN 7

// bit 0: don't break vowels at word boundary
// bit 0: don't break vowels at word boundary
#define LOPT_WORD_MERGE 8

// max. amplitude for vowel at the end of a clause
// max. amplitude for vowel at the end of a clause
#define LOPT_MAXAMP_EOC 9

// bit 0=reduce even if phonemes are specified in the **_list file
// bit 1=don't reduce the strongest vowel in a word which is marked 'unstressed'
// bit 0=reduce even if phonemes are specified in the **_list file
// bit 1=don't reduce the strongest vowel in a word which is marked 'unstressed'
#define LOPT_REDUCE 10

// LANG=cs,sk combine some prepositions with the following word, if the combination has N or fewer syllables
// bits 0-3 N syllables
// bit 4=only if the second word has $alt attribute
// bit 5=not if the second word is end-of-sentence
// LANG=cs,sk combine some prepositions with the following word, if the combination has N or fewer syllables
// bits 0-3 N syllables
// bit 4=only if the second word has $alt attribute
// bit 5=not if the second word is end-of-sentence
#define LOPT_COMBINE_WORDS 11

// change [t] when followed by unstressed vowel
// change [t] when followed by unstressed vowel
#define LOPT_REDUCE_T 12

// 1 = allow capitals inside a word
// 2 = stressed syllable is indicated by capitals
// 1 = allow capitals inside a word
// 2 = stressed syllable is indicated by capitals
#define LOPT_CAPS_IN_WORD 13

// bit 0=Italian "syntactic doubling" of consoants in the word after a word marked with $double attribute
// bit 1=also after a word which ends with a stressed vowel
// bit 0=Italian "syntactic doubling" of consoants in the word after a word marked with $double attribute
// bit 1=also after a word which ends with a stressed vowel
#define LOPT_IT_DOUBLING 14

// Call ApplySpecialAttributes() if $alt or $alt2 is set for a word
// bit 1: stressed syllable: $alt change [e],[o] to [E],[O], $alt2 change [E],[O] to [e],[o]
// Call ApplySpecialAttributes() if $alt or $alt2 is set for a word
// bit 1: stressed syllable: $alt change [e],[o] to [E],[O], $alt2 change [E],[O] to [e],[o]
#define LOPT_ALT 15

// pause for bracket (default=4), pause when annoucing bracket names (default=2)
// pause for bracket (default=4), pause when annoucing bracket names (default=2)
#define LOPT_BRACKET_PAUSE 16

// bit 1, don't break clause before annoucning . ? !
// bit 1, don't break clause before annoucning . ? !
#define LOPT_ANNOUNCE_PUNCT 17

// recognize long vowels (0 = don't recognize)
// recognize long vowels (0 = don't recognize)
#define LOPT_LONG_VOWEL_THRESHOLD 18

// bit 0: Don't allow suffices if there is no previous syllable
// bit 0: Don't allow suffices if there is no previous syllable
#define LOPT_SUFFIX 19

// bit 0 Apostrophe at start of word is part of the word
// bit 1 Apostrophe at end of word is part of the word
// bit 0 Apostrophe at start of word is part of the word
// bit 1 Apostrophe at end of word is part of the word
#define LOPT_APOSTROPHE 20


// stress_rule
#define STRESSPOSN_1L 0 // 1st syllable
#define STRESSPOSN_2L 1 // 2nd syllable
#define STRESSPOSN_2R 2 // penultimate
#define STRESSPOSN_1R 3 // final syllable
#define STRESSPOSN_3R 4 // antipenultimate
#define STRESSPOSN_1L 0 // 1st syllable
#define STRESSPOSN_2L 1 // 2nd syllable
#define STRESSPOSN_2R 2 // penultimate
#define STRESSPOSN_1R 3 // final syllable
#define STRESSPOSN_3R 4 // antipenultimate


typedef struct {
@@ -494,7 +494,7 @@ typedef struct {
// bit5='and' between tens and units
// bit6=add "and" after hundred or thousand
// bit7=don't have "and" both after hundreds and also between tens and units
// bit8=only one primary stress in tens+units
// bit8=only one primary stress in tens+units
// bit9=only one vowel betwen tens and units
// bit10=omit "one" before "hundred"
// bit11=say 19** as nineteen hundred
@@ -514,7 +514,7 @@ typedef struct {
// bit25= Roman numbers only if upper case
// bit26= say "roman" after the number, not before
// bit27= Roman numbers are ordinal numbers
// bit28= only one primary stress in tens+units (on the tens)
// bit28= only one primary stress in tens+units (on the tens)
int numbers;

#define NUM2_THOUSANDS_VAR1 0x40
@@ -613,8 +613,8 @@ typedef struct
char dictionary_name[40];

char phonemes_repeat[20];
int phonemes_repeat_count;
int phoneme_tab_ix;
int phonemes_repeat_count;
int phoneme_tab_ix;

unsigned char stress_amps[8];
unsigned char stress_amps_r[8];
@@ -798,7 +798,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata);
char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa, int *flags);

extern FILE *f_trans; // for logging
extern FILE *f_trans; // for logging
extern FILE *f_logespeak;
extern int logging_type; // from config file


+ 50
- 50
src/libespeak-ng/voices.c View File

@@ -136,7 +136,7 @@ static MNEM_TAB keyword_tab[] = {
{"stressAdd", V_STRESSADD},
{"intonation", V_INTONATION},
{"tunes", V_TUNES},
{"dictrules", V_DICTRULES},
{"dictrules", V_DICTRULES},
{"stressrule", V_STRESSRULE},
{"stressopt", V_STRESSOPT},
{"charset", V_CHARSET},
@@ -277,9 +277,9 @@ void ReadTonePoints(char *string, int *tone_pts)
tone_pts[ix] = -1;

sscanf(string,"%d %d %d %d %d %d %d %d %d %d",
&tone_pts[0],&tone_pts[1],&tone_pts[2],&tone_pts[3],
&tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7],
&tone_pts[8],&tone_pts[9]);
&tone_pts[0],&tone_pts[1],&tone_pts[2],&tone_pts[3],
&tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7],
&tone_pts[8],&tone_pts[9]);
}


@@ -400,7 +400,7 @@ void VoiceReset(int tone_only)
{
// Set voice to the default values

int pk;
int pk;
static unsigned char default_heights[N_PEAKS] = {130,128,120,116,100,100,128,128,128}; // changed for v.1.47
static unsigned char default_widths[N_PEAKS] = {140,128,128,160,171,171,128,128,128};

@@ -500,7 +500,7 @@ static void VoiceFormant(char *p)
static void PhonemeReplacement(int type, char *p)
{
int n;
int phon;
int phon;
int flags = 0;
char phon_string1[12];
char phon_string2[12];
@@ -525,7 +525,7 @@ static int Read8Numbers(char *data_in,int *data)
// Read 8 integer numbers
memset(data, 0, 8+sizeof(int));
return(sscanf(data_in,"%d %d %d %d %d %d %d %d",
&data[0],&data[1],&data[2],&data[3],&data[4],&data[5],&data[6],&data[7]));
&data[0],&data[1],&data[2],&data[3],&data[4],&data[5],&data[6],&data[7]));
}


@@ -553,19 +553,19 @@ voice_t *LoadVoice(const char *vname, int control)

FILE *f_voice = NULL;
char *p;
int key;
int ix;
int n;
int value;
int value2;
int langix = 0;
int tone_only = control & 2;
int language_set = 0;
int phonemes_set = 0;
int stress_amps_set = 0;
int stress_lengths_set = 0;
int stress_add_set = 0;
int conditional_rules = 0;
int key;
int ix;
int n;
int value;
int value2;
int langix = 0;
int tone_only = control & 2;
int language_set = 0;
int phonemes_set = 0;
int stress_amps_set = 0;
int stress_lengths_set = 0;
int stress_add_set = 0;
int conditional_rules = 0;
LANGUAGE_OPTIONS *langopts = NULL;

Translator *new_translator = NULL;
@@ -598,9 +598,9 @@ voice_t *LoadVoice(const char *vname, int control)

// which directory to look for a named voice. List of voice names, must end in a space.
static const char *voices_asia =
"az bn fa fa-pin gu hi hy hy-west id ka kn ku ml ms ne pa ta te tr vi vi-hue vi-sgn zh zh-yue ";
"az bn fa fa-pin gu hi hy hy-west id ka kn ku ml ms ne pa ta te tr vi vi-hue vi-sgn zh zh-yue ";
static const char *voices_europe =
"an bg bs ca cs cy da de el en en-us es et eu fi fr fr-be ga hr hu is it lt lv mk nl no pl pt-pt ro ru sk sq sr sv ";
"an bg bs ca cs cy da de el en en-us es et eu fi fr fr-be ga hr hu is it lt lv mk nl no pl pt-pt ro ru sk sq sr sv ";


strncpy0(voicename, vname, sizeof(voicename));
@@ -888,9 +888,9 @@ voice_t *LoadVoice(const char *vname, int control)

case V_STRESSRULE:
sscanf(p,"%d %d %d %d",&langopts->stress_rule,
&langopts->stress_flags,
&langopts->unstressed_wd1,
&langopts->unstressed_wd2);
&langopts->stress_flags,
&langopts->unstressed_wd1,
&langopts->unstressed_wd2);
break;

case V_CHARSET:
@@ -901,7 +901,7 @@ voice_t *LoadVoice(const char *vname, int control)
case V_OPTION:
value2 = 0;
if(((sscanf(p,"%s %d %d",option_name,&value,&value2) >= 2) && ((ix = LookupMnem(options_tab, option_name)) >= 0)) ||
((sscanf(p,"%d %d %d",&ix,&value,&value2) >= 2) && (ix < N_LOPTS)))
((sscanf(p,"%d %d %d",&ix,&value,&value2) >= 2) && (ix < N_LOPTS)))
{
langopts->param[ix] = value;
langopts->param2[ix] = value2;
@@ -1005,26 +1005,26 @@ voice_t *LoadVoice(const char *vname, int control)
break;

case V_ALPHABET2:
{
ALPHABET *alphabet;
name1[0] = name2[0] = 0;
sscanf(p, "%s %s", name1, name2);
{
ALPHABET *alphabet;
name1[0] = name2[0] = 0;
sscanf(p, "%s %s", name1, name2);

if(strcmp(name1, "latin") == 0)
{
strncpy0(langopts->ascii_language,name2,sizeof(langopts->ascii_language));
}
else if((alphabet = AlphabetFromName(name1)) != 0)
{
langopts->alt_alphabet = alphabet->offset;
langopts->alt_alphabet_lang = StringToWord2(name2);
}
else
{
fprintf(stderr,"alphabet name '%s' not found\n", name1);
}
if(strcmp(name1, "latin") == 0)
{
strncpy0(langopts->ascii_language,name2,sizeof(langopts->ascii_language));
}
break;
else if((alphabet = AlphabetFromName(name1)) != 0)
{
langopts->alt_alphabet = alphabet->offset;
langopts->alt_alphabet_lang = StringToWord2(name2);
}
else
{
fprintf(stderr,"alphabet name '%s' not found\n", name1);
}
}
break;

case V_DICTDIALECT:
// specify a dialect to use for foreign words, eg, en-us for _^_EN
@@ -1275,7 +1275,7 @@ static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int s
matching_parts = 0;
n_parts = 1;

for(ix=0; ; ix++)
for(ix=0;; ix++)
{
if((ix >= spec_lang_len) || ((c1 = spec_language[ix]) == '-'))
c1 = 0;
@@ -1334,7 +1334,7 @@ static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int s
}

if(((voice_spec->gender == 1) || (voice_spec->gender == 2)) &&
((voice->gender == 1) || (voice->gender == 2)))
((voice->gender == 1) || (voice->gender == 2)))
{
if(voice_spec->gender == voice->gender)
score += 50;
@@ -1617,7 +1617,7 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found)
voices2[ix2++] = vp;
}

for(j=0; (j < vp->xx1) && (n_variants < N_VOICE_VARIANTS);)
for(j=0; (j < vp->xx1) && (n_variants < N_VOICE_VARIANTS); )
{
if((variant_number = *p) == 0)
{
@@ -1818,7 +1818,7 @@ espeak_ERROR SetVoiceByName(const char *name)

variant_name = ExtractVoiceVariantName(buf, 0, 1);

for(ix=0; ; ix++)
for(ix=0;; ix++)
{
// convert voice name to lower case (ascii)
if((buf[ix] = tolower(buf[ix])) == 0)
@@ -1935,7 +1935,7 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)

// sort the voices list
qsort(voices_list,n_voices_list,sizeof(espeak_VOICE *),
(int (__cdecl *)(const void *,const void *))VoiceNameSorter);
(int (__cdecl *)(const void *,const void *))VoiceNameSorter);


if(voice_spec)
@@ -1950,7 +1950,7 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)
for(ix=0; (v = voices_list[ix]) != NULL; ix++)
{
if((v->languages[0] != 0) && (strcmp(&v->languages[1],"variant") != 0)
&& (memcmp(v->identifier,"mb/",3) != 0) && (memcmp(v->identifier,"test/",5) != 0))
&& (memcmp(v->identifier,"mb/",3) != 0) && (memcmp(v->identifier,"test/",5) != 0))
{
voices[j++] = v;
}

+ 439
- 420
src/libespeak-ng/wave.c
File diff suppressed because it is too large
View File


+ 528
- 510
src/libespeak-ng/wave_pulse.c
File diff suppressed because it is too large
View File


+ 205
- 186
src/libespeak-ng/wave_sada.c View File

@@ -65,7 +65,7 @@ static uint32_t last_play_position=0;

static uint32_t wave_samplerate;

// wave_init
// wave_init
//
// DESCRIPTION:
//
@@ -77,47 +77,47 @@ static uint32_t wave_samplerate;
// audio device.
//
int wave_init(int srate) {
ENTER("wave_init");
ENTER("wave_init");

audio_info_t ainfo;
char *audio_device = NULL;
audio_info_t ainfo;
char *audio_device = NULL;

wave_samplerate = srate;

audio_device = getenv("AUDIODEV");
if (audio_device != NULL) {
if ((sun_audio_fd = open(audio_device, O_WRONLY)) < 0) {
SHOW("wave_init() could not open: %s (%d)\n",
audio_device, sun_audio_fd);
}
}
if (sun_audio_fd < 0) {
if ((sun_audio_fd = open(sun_audio_device, O_WRONLY)) < 0) {
SHOW("wave_init() could not open: %s (%d)\n",
sun_audio_device, sun_audio_fd);
}
}
SHOW("wave_init() sun_audio_fd: %d\n", sun_audio_fd);
if (sun_audio_fd < 0) {
return(0);
}
ioctl(sun_audio_fd, AUDIO_GETINFO, &ainfo);
SHOW("wave_init() play buffer size: %d\n", ainfo.play.buffer_size);
ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
ainfo.play.channels = 1;
ainfo.play.sample_rate = wave_samplerate;
ainfo.play.precision = SAMPLE_SIZE;
if (ioctl(sun_audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
SHOW("wave_init() failed to set audio params: %s\n", strerror(errno));
close(sun_audio_fd);
return(0);
}
return(1);
audio_device = getenv("AUDIODEV");
if (audio_device != NULL) {
if ((sun_audio_fd = open(audio_device, O_WRONLY)) < 0) {
SHOW("wave_init() could not open: %s (%d)\n",
audio_device, sun_audio_fd);
}
}
if (sun_audio_fd < 0) {
if ((sun_audio_fd = open(sun_audio_device, O_WRONLY)) < 0) {
SHOW("wave_init() could not open: %s (%d)\n",
sun_audio_device, sun_audio_fd);
}
}
SHOW("wave_init() sun_audio_fd: %d\n", sun_audio_fd);
if (sun_audio_fd < 0) {
return(0);
}
ioctl(sun_audio_fd, AUDIO_GETINFO, &ainfo);
SHOW("wave_init() play buffer size: %d\n", ainfo.play.buffer_size);
ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
ainfo.play.channels = 1;
ainfo.play.sample_rate = wave_samplerate;
ainfo.play.precision = SAMPLE_SIZE;
if (ioctl(sun_audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
SHOW("wave_init() failed to set audio params: %s\n", strerror(errno));
close(sun_audio_fd);
return(0);
}
return(1);
}

// wave_open
@@ -144,8 +144,8 @@ int wave_init(int srate) {
//
void* wave_open(const char* the_api)
{
ENTER("wave_open");
return((void*) sun_audio_fd);
ENTER("wave_open");
return((void*) sun_audio_fd);
}

// wave_write
@@ -170,55 +170,55 @@ void* wave_open(const char* the_api)
//
// total_samples_sent: modified based upon 16-bit samples sent
//
// RETURNS:
// RETURNS:
//
// the number of bytes (not 16-bit samples) sent
//
size_t wave_write(void* theHandler,
char* theMono16BitsWaveBuffer,
size_t theSize)
size_t wave_write(void* theHandler,
char* theMono16BitsWaveBuffer,
size_t theSize)
{
size_t num;
ENTER("wave_write");
if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled())) {
SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
return 0;
}
size_t num;
ENTER("wave_write");
if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled())) {
SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
return 0;
}

#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
{
// BIG-ENDIAN, swap the order of bytes in each sound sample
int c;
char *out_ptr;
char *out_end;
out_ptr = (char *)theMono16BitsWaveBuffer;
out_end = out_ptr + theSize;
while(out_ptr < out_end)
{
c = out_ptr[0];
out_ptr[0] = out_ptr[1];
out_ptr[1] = c;
out_ptr += 2;
}
}
{
// BIG-ENDIAN, swap the order of bytes in each sound sample
int c;
char *out_ptr;
char *out_end;
out_ptr = (char *)theMono16BitsWaveBuffer;
out_end = out_ptr + theSize;
while(out_ptr < out_end)
{
c = out_ptr[0];
out_ptr[0] = out_ptr[1];
out_ptr[1] = c;
out_ptr += 2;
}
}
#endif

num = write((int) theHandler, theMono16BitsWaveBuffer, theSize);
num = write((int) theHandler, theMono16BitsWaveBuffer, theSize);

// Keep track of the total number of samples sent -- we use this in
// wave_get_read_position and also use it to help calculate the
// total_samples_skipped in wave_close.
//
total_samples_sent += num / 2;
// Keep track of the total number of samples sent -- we use this in
// wave_get_read_position and also use it to help calculate the
// total_samples_skipped in wave_close.
//
total_samples_sent += num / 2;

if (num < theSize) {
SHOW("ERROR: wave_write only wrote %d of %d bytes\n", num, theSize);
} else {
SHOW("wave_write wrote %d bytes\n", theSize);
}
if (num < theSize) {
SHOW("ERROR: wave_write only wrote %d of %d bytes\n", num, theSize);
} else {
SHOW("wave_write wrote %d bytes\n", theSize);
}

SHOW_TIME("wave_write > LEAVE");
return num;
SHOW_TIME("wave_write > LEAVE");
return num;
}

// wave_close
@@ -241,37 +241,37 @@ size_t wave_write(void* theHandler,
// total_samples_skipped: modified to hold the total number of 16-bit
// samples sent to wave_write, but which were
// never played
// sun_audio_fd: used because some calls to wave_close seem to
// sun_audio_fd: used because some calls to wave_close seem to
// pass a NULL for theHandler for some odd reason
//
// RETURNS:
// RETURNS:
//
// The result of the ioctl call (non-0 means failure)
//
int wave_close(void* theHandler)
{
int ret;
audio_info_t ainfo;
int audio_fd = (int) theHandler;
if (!audio_fd) {
audio_fd = sun_audio_fd;
}
ENTER("wave_close");
// [[[WDW: maybe do a pause/resume ioctl???]]]
ret = ioctl(audio_fd, I_FLUSH, FLUSHRW);
ioctl(audio_fd, AUDIO_GETINFO, &ainfo);
// Calculate the number of samples that won't get
// played. We also keep track of the last_play_position
// because wave_close can be called multiple times
// before another call to wave_write.
//
if (last_play_position != ainfo.play.samples) {
last_play_position = ainfo.play.samples;
total_samples_skipped = total_samples_sent - last_play_position;
}
SHOW_TIME("wave_close > LEAVE");
return ret;
int ret;
audio_info_t ainfo;
int audio_fd = (int) theHandler;
if (!audio_fd) {
audio_fd = sun_audio_fd;
}
ENTER("wave_close");
// [[[WDW: maybe do a pause/resume ioctl???]]]
ret = ioctl(audio_fd, I_FLUSH, FLUSHRW);
ioctl(audio_fd, AUDIO_GETINFO, &ainfo);
// Calculate the number of samples that won't get
// played. We also keep track of the last_play_position
// because wave_close can be called multiple times
// before another call to wave_write.
//
if (last_play_position != ainfo.play.samples) {
last_play_position = ainfo.play.samples;
total_samples_skipped = total_samples_sent - last_play_position;
}
SHOW_TIME("wave_close > LEAVE");
return ret;
}

// wave_is_busy
@@ -286,7 +286,7 @@ int wave_close(void* theHandler)
//
// GLOBALS USED/MODIFIED:
//
// sun_audio_fd: used because some calls to wave_is_busy seem to
// sun_audio_fd: used because some calls to wave_is_busy seem to
// pass a NULL for theHandler for some odd reason
//
// RETURNS:
@@ -295,13 +295,13 @@ int wave_close(void* theHandler)
//
int wave_is_busy(void* theHandler)
{
uint32_t time;
if (total_samples_sent >= 1) {
wave_get_remaining_time(total_samples_sent - 1, &time);
} else {
time = 0;
}
return time != 0;
uint32_t time;
if (total_samples_sent >= 1) {
wave_get_remaining_time(total_samples_sent - 1, &time);
} else {
time = 0;
}
return time != 0;
}

// wave_terminate
@@ -316,10 +316,10 @@ int wave_is_busy(void* theHandler)
//
void wave_terminate()
{
ENTER("wave_terminate");
close(sun_audio_fd);
sun_audio_fd = -1;
SHOW_TIME("wave_terminate > LEAVE");
ENTER("wave_terminate");
close(sun_audio_fd);
sun_audio_fd = -1;
SHOW_TIME("wave_terminate > LEAVE");
}

// wave_flush
@@ -339,8 +339,8 @@ void wave_terminate()
//
void wave_flush(void* theHandler)
{
ENTER("wave_flush");
SHOW_TIME("wave_flush > LEAVE");
ENTER("wave_flush");
SHOW_TIME("wave_flush > LEAVE");
}

// wave_set_callback_is_output_enabled
@@ -357,7 +357,7 @@ void wave_flush(void* theHandler)
//
void wave_set_callback_is_output_enabled(t_wave_callback* cb)
{
my_callback_is_output_enabled = cb;
my_callback_is_output_enabled = cb;
}

// wave_test_get_write_buffer
@@ -373,7 +373,7 @@ void wave_set_callback_is_output_enabled(t_wave_callback* cb)
//
void *wave_test_get_write_buffer()
{
return NULL;
return NULL;
}

// wave_get_read_position
@@ -397,12 +397,12 @@ void *wave_test_get_write_buffer()
//
uint32_t wave_get_read_position(void* theHandler)
{
audio_info_t ainfo;
ENTER("wave_get_read_position");
ioctl((int) theHandler, AUDIO_GETINFO, &ainfo);
SHOW("wave_get_read_position: %d\n", ainfo.play.samples);
SHOW_TIME("wave_get_read_position > LEAVE");
return ainfo.play.samples;
audio_info_t ainfo;
ENTER("wave_get_read_position");
ioctl((int) theHandler, AUDIO_GETINFO, &ainfo);
SHOW("wave_get_read_position: %d\n", ainfo.play.samples);
SHOW_TIME("wave_get_read_position > LEAVE");
return ainfo.play.samples;
}

// wave_get_write_position
@@ -433,10 +433,10 @@ uint32_t wave_get_read_position(void* theHandler)
//
uint32_t wave_get_write_position(void* theHandler)
{
ENTER("wave_get_write_position");
SHOW("wave_get_write_position: %d\n", total_samples_sent);
SHOW_TIME("wave_get_write_position > LEAVE");
return total_samples_sent;
ENTER("wave_get_write_position");
SHOW("wave_get_write_position: %d\n", total_samples_sent);
SHOW_TIME("wave_get_write_position > LEAVE");
return total_samples_sent;
}

// wave_get_remaining_time
@@ -468,48 +468,67 @@ uint32_t wave_get_write_position(void* theHandler)
//
int wave_get_remaining_time(uint32_t sample, uint32_t* time)
{
uint32_t a_time=0;
uint32_t actual_index;
audio_info_t ainfo;
ENTER("wave_get_remaining_time");
if (!time) {
return(-1);
SHOW_TIME("wave_get_remaining_time > LEAVE");
}
ioctl(sun_audio_fd, AUDIO_GETINFO, &ainfo);
// See if this sample has already been played or is currently
// playing.
//
actual_index = sample - total_samples_skipped;
if ((sample < total_samples_skipped) ||
(actual_index <= ainfo.play.samples)) {
*time = 0;
} else {
a_time = ((actual_index - ainfo.play.samples) * 1000) / wave_samplerate;
*time = (uint32_t) a_time;
}
SHOW("wave_get_remaining_time for %d: %d\n", sample, *time);
SHOW_TIME("wave_get_remaining_time > LEAVE");
return 0;
uint32_t a_time=0;
uint32_t actual_index;
audio_info_t ainfo;
ENTER("wave_get_remaining_time");
if (!time) {
return(-1);
SHOW_TIME("wave_get_remaining_time > LEAVE");
}
ioctl(sun_audio_fd, AUDIO_GETINFO, &ainfo);
// See if this sample has already been played or is currently
// playing.
//
actual_index = sample - total_samples_skipped;
if ((sample < total_samples_skipped) ||
(actual_index <= ainfo.play.samples)) {
*time = 0;
} else {
a_time = ((actual_index - ainfo.play.samples) * 1000) / wave_samplerate;
*time = (uint32_t) a_time;
}
SHOW("wave_get_remaining_time for %d: %d\n", sample, *time);
SHOW_TIME("wave_get_remaining_time > LEAVE");
return 0;
}

#else

init wave_init() {return 1;}
void* wave_open(const char* the_api) {return (void *)1;}
size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) {return theSize;}
int wave_close(void* theHandler) {return 0;}
int wave_is_busy(void* theHandler) {return 0;}
void wave_terminate() {}
uint32_t wave_get_read_position(void* theHandler) {return 0;}
uint32_t wave_get_write_position(void* theHandler) {return 0;}
void wave_flush(void* theHandler) {}
init wave_init() {
return 1;
}
void* wave_open(const char* the_api) {
return (void *)1;
}
size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) {
return theSize;
}
int wave_close(void* theHandler) {
return 0;
}
int wave_is_busy(void* theHandler) {
return 0;
}
void wave_terminate() {
}
uint32_t wave_get_read_position(void* theHandler) {
return 0;
}
uint32_t wave_get_write_position(void* theHandler) {
return 0;
}
void wave_flush(void* theHandler) {
}
typedef int (t_wave_callback)(void);
void wave_set_callback_is_output_enabled(t_wave_callback* cb) {}
extern void* wave_test_get_write_buffer() {return NULL;}
void wave_set_callback_is_output_enabled(t_wave_callback* cb) {
}
extern void* wave_test_get_write_buffer() {
return NULL;
}

int wave_get_remaining_time(uint32_t sample, uint32_t* time)
{
@@ -522,33 +541,33 @@ int wave_get_remaining_time(uint32_t sample, uint32_t* time)

void clock_gettime2(struct timespec *ts)
{
struct timeval tv;
struct timeval tv;

if (!ts)
{
return;
}
if (!ts)
{
return;
}

assert (gettimeofday(&tv, NULL) != -1);
ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec*1000;
assert (gettimeofday(&tv, NULL) != -1);
ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec*1000;
}

void add_time_in_ms(struct timespec *ts, int time_in_ms)
{
if (!ts)
{
return;
}
uint64_t t_ns = (uint64_t)ts->tv_nsec + 1000000 * (uint64_t)time_in_ms;
while(t_ns >= ONE_BILLION)
{
SHOW("event > add_time_in_ms ns: %d sec %Lu nsec \n", ts->tv_sec, t_ns);
ts->tv_sec += 1;
t_ns -= ONE_BILLION;
}
ts->tv_nsec = (long int)t_ns;
if (!ts)
{
return;
}
uint64_t t_ns = (uint64_t)ts->tv_nsec + 1000000 * (uint64_t)time_in_ms;
while(t_ns >= ONE_BILLION)
{
SHOW("event > add_time_in_ms ns: %d sec %Lu nsec \n", ts->tv_sec, t_ns);
ts->tv_sec += 1;
t_ns -= ONE_BILLION;
}
ts->tv_nsec = (long int)t_ns;
}

#endif // USE_ASYNC

+ 171
- 165
src/libespeak-ng/wavegen.c View File

@@ -174,57 +174,57 @@ static unsigned char modulation_tab[N_ROUGHNESS][8] = {
#define N_FLUTTER 0x170
static int Flutter_inc;
static const unsigned char Flutter_tab[N_FLUTTER] = {
0x80, 0x9b, 0xb5, 0xcb, 0xdc, 0xe8, 0xed, 0xec,
0xe6, 0xdc, 0xce, 0xbf, 0xb0, 0xa3, 0x98, 0x90,
0x8c, 0x8b, 0x8c, 0x8f, 0x92, 0x94, 0x95, 0x92,
0x8c, 0x83, 0x78, 0x69, 0x59, 0x49, 0x3c, 0x31,
0x2a, 0x29, 0x2d, 0x36, 0x44, 0x56, 0x69, 0x7d,
0x8f, 0x9f, 0xaa, 0xb1, 0xb2, 0xad, 0xa4, 0x96,
0x87, 0x78, 0x69, 0x5c, 0x53, 0x4f, 0x4f, 0x55,
0x5e, 0x6b, 0x7a, 0x88, 0x96, 0xa2, 0xab, 0xb0,
0xb1, 0xae, 0xa8, 0xa0, 0x98, 0x91, 0x8b, 0x88,
0x89, 0x8d, 0x94, 0x9d, 0xa8, 0xb2, 0xbb, 0xc0,
0xc1, 0xbd, 0xb4, 0xa5, 0x92, 0x7c, 0x63, 0x4a,
0x32, 0x1e, 0x0e, 0x05, 0x02, 0x05, 0x0f, 0x1e,
0x30, 0x44, 0x59, 0x6d, 0x7f, 0x8c, 0x96, 0x9c,
0x9f, 0x9f, 0x9d, 0x9b, 0x99, 0x99, 0x9c, 0xa1,
0xa9, 0xb3, 0xbf, 0xca, 0xd5, 0xdc, 0xe0, 0xde,
0xd8, 0xcc, 0xbb, 0xa6, 0x8f, 0x77, 0x60, 0x4b,
0x3a, 0x2e, 0x28, 0x29, 0x2f, 0x3a, 0x48, 0x59,
0x6a, 0x7a, 0x86, 0x90, 0x94, 0x95, 0x91, 0x89,
0x80, 0x75, 0x6b, 0x62, 0x5c, 0x5a, 0x5c, 0x61,
0x69, 0x74, 0x80, 0x8a, 0x94, 0x9a, 0x9e, 0x9d,
0x98, 0x90, 0x86, 0x7c, 0x71, 0x68, 0x62, 0x60,
0x63, 0x6b, 0x78, 0x88, 0x9b, 0xaf, 0xc2, 0xd2,
0xdf, 0xe6, 0xe7, 0xe2, 0xd7, 0xc6, 0xb2, 0x9c,
0x84, 0x6f, 0x5b, 0x4b, 0x40, 0x39, 0x37, 0x38,
0x3d, 0x43, 0x4a, 0x50, 0x54, 0x56, 0x55, 0x52,
0x4d, 0x48, 0x42, 0x3f, 0x3e, 0x41, 0x49, 0x56,
0x67, 0x7c, 0x93, 0xab, 0xc3, 0xd9, 0xea, 0xf6,
0xfc, 0xfb, 0xf4, 0xe7, 0xd5, 0xc0, 0xaa, 0x94,
0x80, 0x71, 0x64, 0x5d, 0x5a, 0x5c, 0x61, 0x68,
0x70, 0x77, 0x7d, 0x7f, 0x7f, 0x7b, 0x74, 0x6b,
0x61, 0x57, 0x4e, 0x48, 0x46, 0x48, 0x4e, 0x59,
0x66, 0x75, 0x84, 0x93, 0x9f, 0xa7, 0xab, 0xaa,
0xa4, 0x99, 0x8b, 0x7b, 0x6a, 0x5b, 0x4e, 0x46,
0x43, 0x45, 0x4d, 0x5a, 0x6b, 0x7f, 0x92, 0xa6,
0xb8, 0xc5, 0xcf, 0xd3, 0xd2, 0xcd, 0xc4, 0xb9,
0xad, 0xa1, 0x96, 0x8e, 0x89, 0x87, 0x87, 0x8a,
0x8d, 0x91, 0x92, 0x91, 0x8c, 0x84, 0x78, 0x68,
0x55, 0x41, 0x2e, 0x1c, 0x0e, 0x05, 0x01, 0x05,
0x0f, 0x1f, 0x34, 0x4d, 0x68, 0x81, 0x9a, 0xb0,
0xc1, 0xcd, 0xd3, 0xd3, 0xd0, 0xc8, 0xbf, 0xb5,
0xab, 0xa4, 0x9f, 0x9c, 0x9d, 0xa0, 0xa5, 0xaa,
0xae, 0xb1, 0xb0, 0xab, 0xa3, 0x96, 0x87, 0x76,
0x63, 0x51, 0x42, 0x36, 0x2f, 0x2d, 0x31, 0x3a,
0x48, 0x59, 0x6b, 0x7e, 0x8e, 0x9c, 0xa6, 0xaa,
0xa9, 0xa3, 0x98, 0x8a, 0x7b, 0x6c, 0x5d, 0x52,
0x4a, 0x48, 0x4a, 0x50, 0x5a, 0x67, 0x75, 0x82
0x80, 0x9b, 0xb5, 0xcb, 0xdc, 0xe8, 0xed, 0xec,
0xe6, 0xdc, 0xce, 0xbf, 0xb0, 0xa3, 0x98, 0x90,
0x8c, 0x8b, 0x8c, 0x8f, 0x92, 0x94, 0x95, 0x92,
0x8c, 0x83, 0x78, 0x69, 0x59, 0x49, 0x3c, 0x31,
0x2a, 0x29, 0x2d, 0x36, 0x44, 0x56, 0x69, 0x7d,
0x8f, 0x9f, 0xaa, 0xb1, 0xb2, 0xad, 0xa4, 0x96,
0x87, 0x78, 0x69, 0x5c, 0x53, 0x4f, 0x4f, 0x55,
0x5e, 0x6b, 0x7a, 0x88, 0x96, 0xa2, 0xab, 0xb0,
0xb1, 0xae, 0xa8, 0xa0, 0x98, 0x91, 0x8b, 0x88,
0x89, 0x8d, 0x94, 0x9d, 0xa8, 0xb2, 0xbb, 0xc0,
0xc1, 0xbd, 0xb4, 0xa5, 0x92, 0x7c, 0x63, 0x4a,
0x32, 0x1e, 0x0e, 0x05, 0x02, 0x05, 0x0f, 0x1e,
0x30, 0x44, 0x59, 0x6d, 0x7f, 0x8c, 0x96, 0x9c,
0x9f, 0x9f, 0x9d, 0x9b, 0x99, 0x99, 0x9c, 0xa1,
0xa9, 0xb3, 0xbf, 0xca, 0xd5, 0xdc, 0xe0, 0xde,
0xd8, 0xcc, 0xbb, 0xa6, 0x8f, 0x77, 0x60, 0x4b,
0x3a, 0x2e, 0x28, 0x29, 0x2f, 0x3a, 0x48, 0x59,
0x6a, 0x7a, 0x86, 0x90, 0x94, 0x95, 0x91, 0x89,
0x80, 0x75, 0x6b, 0x62, 0x5c, 0x5a, 0x5c, 0x61,
0x69, 0x74, 0x80, 0x8a, 0x94, 0x9a, 0x9e, 0x9d,
0x98, 0x90, 0x86, 0x7c, 0x71, 0x68, 0x62, 0x60,
0x63, 0x6b, 0x78, 0x88, 0x9b, 0xaf, 0xc2, 0xd2,
0xdf, 0xe6, 0xe7, 0xe2, 0xd7, 0xc6, 0xb2, 0x9c,
0x84, 0x6f, 0x5b, 0x4b, 0x40, 0x39, 0x37, 0x38,
0x3d, 0x43, 0x4a, 0x50, 0x54, 0x56, 0x55, 0x52,
0x4d, 0x48, 0x42, 0x3f, 0x3e, 0x41, 0x49, 0x56,
0x67, 0x7c, 0x93, 0xab, 0xc3, 0xd9, 0xea, 0xf6,
0xfc, 0xfb, 0xf4, 0xe7, 0xd5, 0xc0, 0xaa, 0x94,
0x80, 0x71, 0x64, 0x5d, 0x5a, 0x5c, 0x61, 0x68,
0x70, 0x77, 0x7d, 0x7f, 0x7f, 0x7b, 0x74, 0x6b,
0x61, 0x57, 0x4e, 0x48, 0x46, 0x48, 0x4e, 0x59,
0x66, 0x75, 0x84, 0x93, 0x9f, 0xa7, 0xab, 0xaa,
0xa4, 0x99, 0x8b, 0x7b, 0x6a, 0x5b, 0x4e, 0x46,
0x43, 0x45, 0x4d, 0x5a, 0x6b, 0x7f, 0x92, 0xa6,
0xb8, 0xc5, 0xcf, 0xd3, 0xd2, 0xcd, 0xc4, 0xb9,
0xad, 0xa1, 0x96, 0x8e, 0x89, 0x87, 0x87, 0x8a,
0x8d, 0x91, 0x92, 0x91, 0x8c, 0x84, 0x78, 0x68,
0x55, 0x41, 0x2e, 0x1c, 0x0e, 0x05, 0x01, 0x05,
0x0f, 0x1f, 0x34, 0x4d, 0x68, 0x81, 0x9a, 0xb0,
0xc1, 0xcd, 0xd3, 0xd3, 0xd0, 0xc8, 0xbf, 0xb5,
0xab, 0xa4, 0x9f, 0x9c, 0x9d, 0xa0, 0xa5, 0xaa,
0xae, 0xb1, 0xb0, 0xab, 0xa3, 0x96, 0x87, 0x76,
0x63, 0x51, 0x42, 0x36, 0x2f, 0x2d, 0x31, 0x3a,
0x48, 0x59, 0x6b, 0x7e, 0x8e, 0x9c, 0xa6, 0xaa,
0xa9, 0xa3, 0x98, 0x8a, 0x7b, 0x6c, 0x5d, 0x52,
0x4a, 0x48, 0x4a, 0x50, 0x5a, 0x67, 0x75, 0x82
};

// waveform shape table for HF peaks, formants 6,7,8
@@ -235,31 +235,33 @@ static int wavemult_max=0;
// the presets are for 22050 Hz sample rate.
// A different rate will need to recalculate the presets in WavegenInit()
static unsigned char wavemult[N_WAVEMULT] = {
0, 0, 0, 2, 3, 5, 8, 11, 14, 18, 22, 27, 32, 37, 43, 49,
55, 62, 69, 76, 83, 90, 98,105,113,121,128,136,144,152,159,166,
174,181,188,194,201,207,213,218,224,228,233,237,240,244,246,249,
251,252,253,253,253,253,252,251,249,246,244,240,237,233,228,224,
218,213,207,201,194,188,181,174,166,159,152,144,136,128,121,113,
105, 98, 90, 83, 76, 69, 62, 55, 49, 43, 37, 32, 27, 22, 18, 14,
11, 8, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 2, 3, 5, 8, 11, 14, 18, 22, 27, 32, 37, 43, 49,
55, 62, 69, 76, 83, 90, 98,105,113,121,128,136,144,152,159,166,
174,181,188,194,201,207,213,218,224,228,233,237,240,244,246,249,
251,252,253,253,253,253,252,251,249,246,244,240,237,233,228,224,
218,213,207,201,194,188,181,174,166,159,152,144,136,128,121,113,
105, 98, 90, 83, 76, 69, 62, 55, 49, 43, 37, 32, 27, 22, 18, 14,
11, 8, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


// set from y = pow(2,x) * 128, x=-1 to 1
unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 86, 87, 88,
89, 91, 92, 93, 94, 96, 97, 98,
100,101,103,104,105,107,108,110,
111,113,115,116,118,119,121,123,
124,126,128,130,132,133,135,137,
139,141,143,145,147,149,151,153,
155,158,160,162,164,167,169,171,
174,176,179,181,184,186,189,191,
194,197,199,202,205,208,211,214,
217,220,223,226,229,232,236,239,
242,246,249,252, 254,255 };
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 86, 87, 88,
89, 91, 92, 93, 94, 96, 97, 98,
100,101,103,104,105,107,108,110,
111,113,115,116,118,119,121,123,
124,126,128,130,132,133,135,137,
139,141,143,145,147,149,151,153,
155,158,160,162,164,167,169,171,
174,176,179,181,184,186,189,191,
194,197,199,202,205,208,211,214,
217,220,223,226,229,232,236,239,
242,246,249,252, 254,255
};


#ifdef LOG_FRAMES
@@ -324,7 +326,7 @@ int WcmdqFree()

int WcmdqUsed()
{
return(N_WCMDQ - WcmdqFree());
return(N_WCMDQ - WcmdqFree());
}


@@ -346,48 +348,52 @@ static void WcmdqIncHead()
#define PEAKSHAPEW 256
static const float pk_shape_x[2][8] = {
{0,-0.6f, 0.0f, 0.6f, 1.4f, 2.5f, 4.5f, 5.5f},
{0,-0.6f, 0.0f, 0.6f, 1.4f, 2.0f, 4.5f, 5.5f }};
{0,-0.6f, 0.0f, 0.6f, 1.4f, 2.0f, 4.5f, 5.5f }
};
static const float pk_shape_y[2][8] = {
{0, 67, 81, 67, 31, 14, 0, -6} ,
{0, 77, 81, 77, 31, 7, 0, -6 }};
{0, 67, 81, 67, 31, 14, 0, -6},
{0, 77, 81, 77, 31, 7, 0, -6 }
};

unsigned char pk_shape1[PEAKSHAPEW+1] = {
255,254,254,254,254,254,253,253,252,251,251,250,249,248,247,246,
245,244,242,241,239,238,236,234,233,231,229,227,225,223,220,218,
216,213,211,209,207,205,203,201,199,197,195,193,191,189,187,185,
183,180,178,176,173,171,169,166,164,161,159,156,154,151,148,146,
143,140,138,135,132,129,126,123,120,118,115,112,108,105,102, 99,
96, 95, 93, 91, 90, 88, 86, 85, 83, 82, 80, 79, 77, 76, 74, 73,
72, 70, 69, 68, 67, 66, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55,
55, 54, 53, 52, 52, 51, 50, 50, 49, 48, 48, 47, 47, 46, 46, 46,
45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 44, 43,
42, 42, 41, 40, 40, 39, 38, 38, 37, 36, 36, 35, 35, 34, 33, 33,
32, 32, 31, 30, 30, 29, 29, 28, 28, 27, 26, 26, 25, 25, 24, 24,
23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16,
16, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 11, 11, 11, 10, 10,
10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5,
5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 };
255,254,254,254,254,254,253,253,252,251,251,250,249,248,247,246,
245,244,242,241,239,238,236,234,233,231,229,227,225,223,220,218,
216,213,211,209,207,205,203,201,199,197,195,193,191,189,187,185,
183,180,178,176,173,171,169,166,164,161,159,156,154,151,148,146,
143,140,138,135,132,129,126,123,120,118,115,112,108,105,102, 99,
96, 95, 93, 91, 90, 88, 86, 85, 83, 82, 80, 79, 77, 76, 74, 73,
72, 70, 69, 68, 67, 66, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55,
55, 54, 53, 52, 52, 51, 50, 50, 49, 48, 48, 47, 47, 46, 46, 46,
45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 44, 43,
42, 42, 41, 40, 40, 39, 38, 38, 37, 36, 36, 35, 35, 34, 33, 33,
32, 32, 31, 30, 30, 29, 29, 28, 28, 27, 26, 26, 25, 25, 24, 24,
23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16,
16, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 11, 11, 11, 10, 10,
10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5,
5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0
};

static unsigned char pk_shape2[PEAKSHAPEW+1] = {
255,254,254,254,254,254,254,254,254,254,253,253,253,253,252,252,
252,251,251,251,250,250,249,249,248,248,247,247,246,245,245,244,
243,243,242,241,239,237,235,233,231,229,227,225,223,221,218,216,
213,211,208,205,203,200,197,194,191,187,184,181,178,174,171,167,
163,160,156,152,148,144,140,136,132,127,123,119,114,110,105,100,
96, 94, 91, 88, 86, 83, 81, 78, 76, 74, 71, 69, 66, 64, 62, 60,
57, 55, 53, 51, 49, 47, 44, 42, 40, 38, 36, 34, 32, 30, 29, 27,
25, 23, 21, 19, 18, 16, 14, 12, 11, 9, 7, 6, 4, 3, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 };
255,254,254,254,254,254,254,254,254,254,253,253,253,253,252,252,
252,251,251,251,250,250,249,249,248,248,247,247,246,245,245,244,
243,243,242,241,239,237,235,233,231,229,227,225,223,221,218,216,
213,211,208,205,203,200,197,194,191,187,184,181,178,174,171,167,
163,160,156,152,148,144,140,136,132,127,123,119,114,110,105,100,
96, 94, 91, 88, 86, 83, 81, 78, 76, 74, 71, 69, 66, 64, 62, 60,
57, 55, 53, 51, 49, 47, 44, 42, 40, 38, 36, 34, 32, 30, 29, 27,
25, 23, 21, 19, 18, 16, 14, 12, 11, 9, 7, 6, 4, 3, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0
};

static unsigned char *pk_shape;

@@ -405,11 +411,11 @@ int outbuffer_size = 0;

#if USE_PORTAUDIO == 18
static int WaveCallback(void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, PaTimestamp outTime, void *userData )
unsigned long framesPerBuffer, PaTimestamp outTime, void *userData )
#else
static int WaveCallback(const void *inputBuffer, void *outputBuffer,
long unsigned int framesPerBuffer, const PaStreamCallbackTimeInfo *outTime,
PaStreamCallbackFlags flags, void *userData )
long unsigned int framesPerBuffer, const PaStreamCallbackTimeInfo *outTime,
PaStreamCallbackFlags flags, void *userData )
#endif
{
int ix;
@@ -539,13 +545,13 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,
is broken */

static PaError Pa_OpenDefaultStream2( PaStream** stream,
int inputChannelCount,
int outputChannelCount,
PaSampleFormat sampleFormat,
double sampleRate,
unsigned long framesPerBuffer,
PaStreamCallback *streamCallback,
void *userData )
int inputChannelCount,
int outputChannelCount,
PaSampleFormat sampleFormat,
double sampleRate,
unsigned long framesPerBuffer,
PaStreamCallback *streamCallback,
void *userData )
{
PaError result;
PaStreamParameters hostApiOutputParameters;
@@ -564,13 +570,13 @@ static PaError Pa_OpenDefaultStream2( PaStream** stream,
defaultLowOutputLatency because it is more important for the default
stream to work reliably than it is for it to work with the lowest
latency.
*/
*/
hostApiOutputParameters.suggestedLatency =
Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;

result = Pa_OpenStream(
stream, NULL, &hostApiOutputParameters, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
stream, NULL, &hostApiOutputParameters, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );

return(result);
}
@@ -707,7 +713,7 @@ int WavegenInitSound()

void WavegenInit(int rate, int wavemult_fact)
{
int ix;
int ix;
double x;

if(wavemult_fact == 0)
@@ -754,8 +760,8 @@ void WavegenInit(int rate, int wavemult_fact)
#endif

#ifdef LOG_FRAMES
remove("log-espeakedit");
remove("log-klatt");
remove("log-espeakedit");
remove("log-klatt");
#endif
}

@@ -823,7 +829,7 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)

// control 0=initial call, 1=every 64 cycles

// pitch and freqs are Hz<<16
// pitch and freqs are Hz<<16

int f;
wavegen_peaks_t *p;
@@ -855,7 +861,7 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
if(hmax > hmax_samplerate)
hmax = hmax_samplerate;

for(h=0;h<=hmax;h++)
for(h=0; h<=hmax; h++)
htab[h]=0;

h=0;
@@ -879,23 +885,23 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
}
}

{
int y;
int h2;
// increase bass
y = peaks[1].height * 10; // addition as a multiple of 1/256s
h2 = (1000<<16)/pitch; // decrease until 1000Hz
if(h2 > 0)
{
x = y/h2;
h = 1;
while(y > 0)
int y;
int h2;
// increase bass
y = peaks[1].height * 10; // addition as a multiple of 1/256s
h2 = (1000<<16)/pitch; // decrease until 1000Hz
if(h2 > 0)
{
htab[h++] += y;
y -= x;
x = y/h2;
h = 1;
while(y > 0)
{
htab[h++] += y;
y -= x;
}
}
}
}

// find the nearest harmonic for HF peaks where we don't use shape
for(; pk<N_PEAKS; pk++)
@@ -993,7 +999,7 @@ static void AdvanceParameters()
peaks[ix].right = peaks[ix].left;
}
}
for(;ix < 8; ix++)
for(; ix < 8; ix++)
{
// formants 6,7,8 don't have a width parameter
if(ix < 7)
@@ -1026,7 +1032,7 @@ static double resonator(RESONATOR *r, double input)
r->x2 = r->x1;
r->x1 = x;

return x;
return x;
}


@@ -1146,7 +1152,7 @@ int Wavegen()
// continue until the output buffer is full, or
// the required number of samples have been produced

for(;;)
for(;; )
{
if((end_wave==0) && (samplecount==nsamples))
return(0);
@@ -1163,7 +1169,7 @@ int Wavegen()
// adjust amplitude to compensate for fewer harmonics at higher pitch
amplitude2 = (wdata.amplitude * (wdata.pitch >> 8) * wdata.amplitude_fmt)/(10000 << 3);

// switch sign of harmonics above about 900Hz, to reduce max peak amplitude
// switch sign of harmonics above about 900Hz, to reduce max peak amplitude
h_switch_sign = 890 / (wdata.pitch >> 12);
}
else
@@ -1646,16 +1652,16 @@ void SetPitch(int length, unsigned char *env, int pitch1, int pitch2)
// length in samples

#ifdef LOG_FRAMES
if(option_log_frames)
{
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
if(option_log_frames)
{
fprintf(f_log," pitch %3d %3d %3dmS\n",pitch1,pitch2,(length*1000)/samplerate);
fclose(f_log);
f_log=NULL;
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
{
fprintf(f_log," pitch %3d %3d %3dmS\n",pitch1,pitch2,(length*1000)/samplerate);
fclose(f_log);
f_log=NULL;
}
}
}
#endif
if((wdata.pitch_env = env)==NULL)
wdata.pitch_env = env_fall; // default
@@ -1690,19 +1696,19 @@ void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
static int glottal_reduce_tab2[4] = {0x90, 0xa0, 0xb0, 0xc0}; // vowel after [?], amp * 1/256

#ifdef LOG_FRAMES
if(option_log_frames)
{
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
if(option_log_frames)
{
fprintf(f_log,"%3dmS %3d %3d %4d %4d (%3d %3d %3d %3d) to %3d %3d %4d %4d (%3d %3d %3d %3d)\n",length*1000/samplerate,
fr1->ffreq[0],fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->fheight[0],fr1->fheight[1],fr1->fheight[2],fr1->fheight[3],
fr2->ffreq[0],fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->fheight[0],fr2->fheight[1],fr2->fheight[2],fr2->fheight[3] );
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
{
fprintf(f_log,"%3dmS %3d %3d %4d %4d (%3d %3d %3d %3d) to %3d %3d %4d %4d (%3d %3d %3d %3d)\n",length*1000/samplerate,
fr1->ffreq[0],fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->fheight[0],fr1->fheight[1],fr1->fheight[2],fr1->fheight[3],
fr2->ffreq[0],fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->fheight[0],fr2->fheight[1],fr2->fheight[2],fr2->fheight[3] );

fclose(f_log);
f_log=NULL;
fclose(f_log);
f_log=NULL;
}
}
}
#endif

harm_sqrt_n = 0;
@@ -1723,7 +1729,7 @@ if(option_log_frames)
glottal_reduce = glottal_reduce_tab2[(modn >> 8) & 3];
}

for(qix=wcmdq_head+1;;qix++)
for(qix=wcmdq_head+1;; qix++)
{
if(qix >= N_WCMDQ) qix = 0;
if(qix == wcmdq_tail) break;
@@ -1977,7 +1983,7 @@ static int SpeedUp(short *outbuf, int length_in, int length_out, int end_of_text
}
if(sonicGetSpeed(sonicSpeedupStream) != sonicSpeed)
{
sonicSetSpeed(sonicSpeedupStream, sonicSpeed);
sonicSetSpeed(sonicSpeedupStream, sonicSpeed);
}

sonicWriteShortToStream(sonicSpeedupStream, outbuf, length_in);

+ 103
- 102
src/speak-ng.c View File

@@ -67,60 +67,60 @@ unsigned int wavefile_count = 0;
int end_of_sentence = 0;

static const char *help_text =
"\nspeak-ng [options] [\"<words>\"]\n\n"
"-f <text file> Text file to speak\n"
"--stdin Read text input from stdin instead of a file\n\n"
"If neither -f nor --stdin, then <words> are spoken, or if none then text\n"
"is spoken from stdin, each line separately.\n\n"
"-a <integer>\n"
"\t Amplitude, 0 to 200, default is 100\n"
"-g <integer>\n"
"\t Word gap. Pause between words, units of 10mS at the default speed\n"
"-k <integer>\n"
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
"\t higher values indicate a pitch increase (try -k20).\n"
"-l <integer>\n"
"\t Line length. If not zero (which is the default), consider\n"
"\t lines less than this length as end-of-clause\n"
"-p <integer>\n"
"\t Pitch adjustment, 0 to 99, default is 50\n"
"-s <integer>\n"
"\t Speed in approximate words per minute. The default is 175\n"
"-v <voice name>\n"
"\t Use voice file of this name from espeak-data/voices\n"
"-w <wave file name>\n"
"\t Write speech to this WAV file, rather than speaking it directly\n"
"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
"-m\t Interpret SSML markup, and ignore other < > tags\n"
"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
"-x\t Write phoneme mnemonics to stdout\n"
"-X\t Write phonemes mnemonics and translation trace to stdout\n"
"-z\t No final sentence pause at the end of the text\n"
"--compile=<voice name>\n"
"\t Compile pronunciation rules and dictionary from the current\n"
"\t directory. <voice name> specifies the language\n"
"--ipa Write phonemes to stdout using International Phonetic Alphabet\n"
"--path=\"<path>\"\n"
"\t Specifies the directory containing the espeak-data directory\n"
"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n"
"--phonout=\"<filename>\"\n"
"\t Write phoneme output from -x -X --ipa and --pho to this file\n"
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
"--sep=<character>\n"
"\t Separate phonemes (from -x --ipa) with <character>.\n"
"\t Default is space, z means ZWJN character.\n"
"--split=<minutes>\n"
"\t Starts a new WAV file every <minutes>. Used with -w\n"
"--stdout Write speech output to stdout\n"
"--tie=<character>\n"
"\t Use a tie character within multi-letter phoneme names.\n"
"\t Default is U+361, z means ZWJ character.\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";
"\nspeak-ng [options] [\"<words>\"]\n\n"
"-f <text file> Text file to speak\n"
"--stdin Read text input from stdin instead of a file\n\n"
"If neither -f nor --stdin, then <words> are spoken, or if none then text\n"
"is spoken from stdin, each line separately.\n\n"
"-a <integer>\n"
"\t Amplitude, 0 to 200, default is 100\n"
"-g <integer>\n"
"\t Word gap. Pause between words, units of 10mS at the default speed\n"
"-k <integer>\n"
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
"\t higher values indicate a pitch increase (try -k20).\n"
"-l <integer>\n"
"\t Line length. If not zero (which is the default), consider\n"
"\t lines less than this length as end-of-clause\n"
"-p <integer>\n"
"\t Pitch adjustment, 0 to 99, default is 50\n"
"-s <integer>\n"
"\t Speed in approximate words per minute. The default is 175\n"
"-v <voice name>\n"
"\t Use voice file of this name from espeak-data/voices\n"
"-w <wave file name>\n"
"\t Write speech to this WAV file, rather than speaking it directly\n"
"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
"-m\t Interpret SSML markup, and ignore other < > tags\n"
"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
"-x\t Write phoneme mnemonics to stdout\n"
"-X\t Write phonemes mnemonics and translation trace to stdout\n"
"-z\t No final sentence pause at the end of the text\n"
"--compile=<voice name>\n"
"\t Compile pronunciation rules and dictionary from the current\n"
"\t directory. <voice name> specifies the language\n"
"--ipa Write phonemes to stdout using International Phonetic Alphabet\n"
"--path=\"<path>\"\n"
"\t Specifies the directory containing the espeak-data directory\n"
"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n"
"--phonout=\"<filename>\"\n"
"\t Write phoneme output from -x -X --ipa and --pho to this file\n"
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
"--sep=<character>\n"
"\t Separate phonemes (from -x --ipa) with <character>.\n"
"\t Default is space, z means ZWJN character.\n"
"--split=<minutes>\n"
"\t Starts a new WAV file every <minutes>. Used with -w\n"
"--stdout Write speech output to stdout\n"
"--tie=<character>\n"
"\t Use a tie character within multi-letter phoneme names.\n"
"\t Default is U+361, z means ZWJ character.\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";


void DisplayVoices(FILE *f_out, char *language);
@@ -187,7 +187,7 @@ void DisplayVoices(FILE *f_out, char *language)
break;
}
fprintf(f_out,"%2d %-12s%s%c %-20s %-13s ",
p[0],lang_name,age_buf,genders[v->gender],buf,v->identifier);
p[0],lang_name,age_buf,genders[v->gender],buf,v->identifier);
}
else
{
@@ -208,7 +208,8 @@ static int OpenWaveFile(const char *path, int rate)
static unsigned char wave_hdr[44] = {
'R','I','F','F',0x24,0xf0,0xff,0x7f,'W','A','V','E','f','m','t',' ',
0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0,
2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f};
2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f
};

if(path == NULL)
return(2);
@@ -246,13 +247,13 @@ static int OpenWaveFile(const char *path, int rate)

static void CloseWaveFile()
{
unsigned int pos;
unsigned int pos;

if((f_wave == NULL) || (f_wave == stdout))
return;
if((f_wave == NULL) || (f_wave == stdout))
return;

fflush(f_wave);
pos = ftell(f_wave);
fflush(f_wave);
pos = ftell(f_wave);

fseek(f_wave,4,SEEK_SET);
Write4Bytes(f_wave,pos - 8);
@@ -261,8 +262,8 @@ static void CloseWaveFile()
Write4Bytes(f_wave,pos - 44);


fclose(f_wave);
f_wave = NULL;
fclose(f_wave);
f_wave = NULL;

}

@@ -352,14 +353,14 @@ static void init_path(char *argv0, char *path_specified)
sprintf(path_home,"%s\\espeak-data",buf);
#else
#ifdef PLATFORM_DOS
strcpy(path_home,PATH_ESPEAK_DATA);
strcpy(path_home,PATH_ESPEAK_DATA);
#else
char *env;
if((env = getenv("ESPEAK_DATA_PATH")) != NULL)
{
snprintf(path_home,sizeof(path_home),"%s/espeak-data",env);
if(GetFileLength(path_home) == -2)
return; // an espeak-data directory exists
return; // an espeak-data directory exists
}

snprintf(path_home,sizeof(path_home),"%s/espeak-data",getenv("HOME"));
@@ -382,7 +383,7 @@ static int initialise(void)
// to something other than the default "C". Then, not only Latin1 but also the
// other characters give the correct results with iswalpha() etc.
#ifdef PLATFORM_RISCOS
setlocale(LC_CTYPE,"ISO8859-1");
setlocale(LC_CTYPE,"ISO8859-1");
#else
if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
{
@@ -416,16 +417,16 @@ static int initialise(void)


#ifdef NEED_GETOPT
struct option {
char *name;
int has_arg;
int *flag;
int val;
};
int optind;
static int optional_argument;
static const char *arg_opts = "abfgklpsvw"; // which options have arguments
static char *opt_string="";
struct option {
char *name;
int has_arg;
int *flag;
int val;
};
int optind;
static int optional_argument;
static const char *arg_opts = "abfgklpsvw"; // which options have arguments
static char *opt_string="";
#define no_argument 0
#define required_argument 1
#define optional_argument 2
@@ -434,7 +435,7 @@ static int initialise(void)
int main (int argc, char **argv)
{
static struct option long_options[] =
{
{
{"help", no_argument, 0, 'h'},
{"stdin", no_argument, 0, 0x100},
{"compile-debug", optional_argument, 0, 0x101},
@@ -451,7 +452,7 @@ int main (int argc, char **argv)
{"sep", optional_argument, 0, 0x10c},
{"tie", optional_argument, 0, 0x10d},
{0, 0, 0, 0}
};
};

static const char *err_load = "Failed to read ";

@@ -517,7 +518,7 @@ int main (int argc, char **argv)
break; // -- means don't interpret further - as commands

opt_string="";
for(ix=0; ;ix++)
for(ix=0;; ix++)
{
if(long_options[ix].name == 0)
break;
@@ -549,7 +550,7 @@ int main (int argc, char **argv)
while(true)
{
c = getopt_long (argc, argv, "a:b:f:g:hk:l:p:qs:v:w:xXmz", // NOTE: also change arg_opts to indicate which commands have a numeric value
long_options, &option_index);
long_options, &option_index);

/* Detect the end of the options. */
if (c == -1)
@@ -631,23 +632,23 @@ int main (int argc, char **argv)
option_endpause = 0;
break;

case 0x100: // --stdin
case 0x100: // --stdin
flag_stdin = 1;
break;

case 0x105: // --stdout
case 0x105: // --stdout
option_waveout = 1;
strcpy(wavefile,"stdout");
break;

case 0x101: // --compile-debug
case 0x102: // --compile
case 0x102: // --compile
if(optarg2 != NULL)
strncpy0(voicename,optarg2,sizeof(voicename));
flag_compile = c;
break;

case 0x103: // --punct
case 0x103: // --punct
option_punctuation = 1;
if(optarg2 != NULL)
{
@@ -693,19 +694,19 @@ int main (int argc, char **argv)
// deprecated and obsolete
switch(atoi(optarg2))
{
case 1:
phonemes_separator = '_';
break;
case 2:
phonemes_separator = 0x0361;
phoneme_options |= espeakPHONEMES_TIE;
break;
case 3:
phonemes_separator = 0x200d; // ZWJ
phoneme_options |= espeakPHONEMES_TIE;
break;
case 1:
phonemes_separator = '_';
break;
case 2:
phonemes_separator = 0x0361;
phoneme_options |= espeakPHONEMES_TIE;
break;
case 3:
phonemes_separator = 0x200d; // ZWJ
phoneme_options |= espeakPHONEMES_TIE;
break;
}
}
break;

@@ -713,15 +714,15 @@ int main (int argc, char **argv)
init_path(argv[0],data_path);
printf("speak text-to-speech: %s Data at: %s\n",version_string,path_home);
exit(0);
case 0x10c: // --sep
phoneme_options |= espeakPHONEMES_SHOW;
if(optarg2 == 0)
phonemes_separator = ' ';
else
utf8_in(&phonemes_separator, optarg2);
if(phonemes_separator == 'z')
phonemes_separator = 0x200c; // ZWNJ
if(phonemes_separator == 'z')
phonemes_separator = 0x200c; // ZWNJ
break;

case 0x10d: // --tie
@@ -730,8 +731,8 @@ int main (int argc, char **argv)
phonemes_separator = 0x0361; // default: combining-double-inverted-breve
else
utf8_in(&phonemes_separator, optarg2);
if(phonemes_separator == 'z')
phonemes_separator = 0x200d; // ZWJ
if(phonemes_separator == 'z')
phonemes_separator = 0x200d; // ZWJ
break;

default:
@@ -855,7 +856,7 @@ int main (int argc, char **argv)
SpeakNextClause(f_text,p_text,0);

ix = 1;
for(;;)
for(;; )
{
if(WavegenFile() != 0)
{

Loading…
Cancel
Save