|
|
@@ -450,7 +450,6 @@ static espeak_ng_STATUS ReadPhondataManifest(CompileContext *ctx, espeak_ng_ERRO |
|
|
|
// Read the phondata-manifest file |
|
|
|
FILE *f; |
|
|
|
int n_lines = 0; |
|
|
|
int ix; |
|
|
|
char *p; |
|
|
|
unsigned int value; |
|
|
|
char buf[sizeof(path_home)+40]; |
|
|
@@ -466,7 +465,7 @@ static espeak_ng_STATUS ReadPhondataManifest(CompileContext *ctx, espeak_ng_ERRO |
|
|
|
rewind(f); |
|
|
|
|
|
|
|
if (ctx->manifest != NULL) { |
|
|
|
for (ix = 0; ix < ctx->n_manifest; ix++) |
|
|
|
for (int ix = 0; ix < ctx->n_manifest; ix++) |
|
|
|
free(ctx->manifest[ix].name); |
|
|
|
} |
|
|
|
|
|
|
@@ -544,13 +543,11 @@ static void ReservePhCodes(CompileContext *ctx) |
|
|
|
{ |
|
|
|
// Reserve phoneme codes which have fixed numbers so that they can be |
|
|
|
// referred to from the program code. |
|
|
|
unsigned int word; |
|
|
|
const MNEM_TAB *p; |
|
|
|
|
|
|
|
p = reserved_phonemes; |
|
|
|
while (p->mnem != NULL) { |
|
|
|
word = StringToWord(p->mnem); |
|
|
|
ctx->phoneme_tab2[p->value].mnemonic = word; |
|
|
|
ctx->phoneme_tab2[p->value].mnemonic = StringToWord(p->mnem); |
|
|
|
ctx->phoneme_tab2[p->value].code = p->value; |
|
|
|
if (ctx->n_phcodes <= p->value) |
|
|
|
ctx->n_phcodes = p->value+1; |
|
|
@@ -637,12 +634,9 @@ static int CheckNextChar(CompileContext *ctx) |
|
|
|
|
|
|
|
static int NextItem(CompileContext *ctx, int type) |
|
|
|
{ |
|
|
|
int acc; |
|
|
|
unsigned char c = 0; |
|
|
|
unsigned char c2; |
|
|
|
int ix; |
|
|
|
int sign; |
|
|
|
char *p; |
|
|
|
const keywtab_t *pk; |
|
|
|
|
|
|
|
ctx->item_type = -1; |
|
|
@@ -701,9 +695,10 @@ static int NextItem(CompileContext *ctx, int type) |
|
|
|
return 0; |
|
|
|
|
|
|
|
if ((type == tNUMBER) || (type == tSIGNEDNUMBER)) { |
|
|
|
acc = 0; |
|
|
|
sign = 1; |
|
|
|
p = ctx->item_string; |
|
|
|
int acc = 0; |
|
|
|
int sign = 1; |
|
|
|
char *p; |
|
|
|
p = ctx->item_string; |
|
|
|
|
|
|
|
if ((*p == '-') && (type == tSIGNEDNUMBER)) { |
|
|
|
sign = -1; |
|
|
@@ -799,7 +794,6 @@ static int Range(int value, int divide, int min, int max) |
|
|
|
static int CompileVowelTransition(CompileContext *ctx, int which) |
|
|
|
{ |
|
|
|
// Compile a vowel transition |
|
|
|
int key; |
|
|
|
int len = 0; |
|
|
|
int rms = 0; |
|
|
|
int f1 = 0; |
|
|
@@ -830,7 +824,7 @@ static int CompileVowelTransition(CompileContext *ctx, int which) |
|
|
|
} |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
key = NextItem(ctx, tKEYWORD); |
|
|
|
int key = NextItem(ctx, tKEYWORD); |
|
|
|
if (ctx->item_type != tTRANSITION) { |
|
|
|
UngetItem(ctx); |
|
|
|
break; |
|
|
@@ -1213,8 +1207,6 @@ static int Hash8(const char *string) |
|
|
|
static int LoadEnvelope2(CompileContext *ctx, FILE *f) |
|
|
|
{ |
|
|
|
int ix, ix2; |
|
|
|
int n; |
|
|
|
int x, y; |
|
|
|
int displ; |
|
|
|
int n_points; |
|
|
|
char line_buf[128]; |
|
|
@@ -1230,7 +1222,7 @@ static int LoadEnvelope2(CompileContext *ctx, FILE *f) |
|
|
|
break; |
|
|
|
|
|
|
|
env_lin[n_points] = 0; |
|
|
|
n = sscanf(line_buf, "%f %f %d", &env_x[n_points], &env_y[n_points], &env_lin[n_points]); |
|
|
|
int n = sscanf(line_buf, "%f %f %d", &env_x[n_points], &env_y[n_points], &env_lin[n_points]); |
|
|
|
if (n >= 2) { |
|
|
|
env_x[n_points] *= (float)1.28; // convert range 0-100 to 0-128 |
|
|
|
n_points++; |
|
|
@@ -1244,12 +1236,14 @@ static int LoadEnvelope2(CompileContext *ctx, FILE *f) |
|
|
|
|
|
|
|
ix = 0; |
|
|
|
ix2 = 0; |
|
|
|
if (n_points > 0) for (x = 0; x < ENV_LEN; x++) { |
|
|
|
|
|
|
|
if (n_points > 0) for (int x = 0; x < ENV_LEN; x++) { |
|
|
|
if (n_points > 3 && x > env_x[ix+3]) |
|
|
|
ix++; |
|
|
|
if (n_points > 2 && x >= env_x[ix2+1]) |
|
|
|
ix2++; |
|
|
|
|
|
|
|
int y; |
|
|
|
if (env_lin[ix2] > 0) { |
|
|
|
y = (env_y[ix2] + (env_y[ix2+1] - env_y[ix2]) * ((float)x - env_x[ix2]) / (env_x[ix2+1] - env_x[ix2])) * 2.55; |
|
|
|
} else if (n_points > 3) |
|
|
@@ -1272,12 +1266,8 @@ static espeak_ng_STATUS LoadDataFile(CompileContext *ctx, const char *path, int |
|
|
|
// load spectrum sequence or sample data from a file. |
|
|
|
// return index into spect or sample data area. bit 23=1 if a sample |
|
|
|
|
|
|
|
FILE *f; |
|
|
|
int id; |
|
|
|
int hash; |
|
|
|
int type_code = ' '; |
|
|
|
REF_HASH_TAB *p, *p2; |
|
|
|
char buf[sizeof(path_home)+150]; |
|
|
|
|
|
|
|
if (strcmp(path, "NULL") == 0) |
|
|
|
return ENS_OK; |
|
|
@@ -1300,8 +1290,10 @@ static espeak_ng_STATUS LoadDataFile(CompileContext *ctx, const char *path, int |
|
|
|
} |
|
|
|
|
|
|
|
if (*addr == 0) { |
|
|
|
char buf[sizeof(path_home)+150]; |
|
|
|
sprintf(buf, "%s/%s", ctx->phsrc, path); |
|
|
|
|
|
|
|
FILE *f; |
|
|
|
if ((f = fopen(buf, "rb")) == NULL) { |
|
|
|
sprintf(buf, "%s/%s.wav", ctx->phsrc, path); |
|
|
|
if ((f = fopen(buf, "rb")) == NULL) { |
|
|
@@ -1310,10 +1302,11 @@ static espeak_ng_STATUS LoadDataFile(CompileContext *ctx, const char *path, int |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
id = Read4Bytes(f); |
|
|
|
int id = Read4Bytes(f); |
|
|
|
rewind(f); |
|
|
|
|
|
|
|
espeak_ng_STATUS status = ENS_OK; |
|
|
|
int type_code = ' '; |
|
|
|
if (id == 0x43455053) { |
|
|
|
status = LoadSpect(ctx, path, control, addr); |
|
|
|
type_code = 'S'; |
|
|
@@ -1445,27 +1438,25 @@ static void CompileSound(CompileContext *ctx, int keyword, int isvowel) |
|
|
|
*/ |
|
|
|
static int CompileIf(CompileContext *ctx, int elif) |
|
|
|
{ |
|
|
|
int key; |
|
|
|
bool finish = false; |
|
|
|
int word = 0; |
|
|
|
int word2; |
|
|
|
int data; |
|
|
|
int bitmap; |
|
|
|
int brackets; |
|
|
|
bool not_flag; |
|
|
|
unsigned short *prog_last_if = NULL; |
|
|
|
|
|
|
|
ctx->then_count = 2; |
|
|
|
ctx->after_if = true; |
|
|
|
|
|
|
|
while (!finish) { |
|
|
|
not_flag = false; |
|
|
|
word2 = 0; |
|
|
|
bool not_flag = false; |
|
|
|
int word2 = 0; |
|
|
|
if (ctx->prog_out >= ctx->prog_out_max) { |
|
|
|
error(ctx, "Phoneme program too large"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int key; |
|
|
|
if ((key = NextItem(ctx, tCONDITION)) < 0) |
|
|
|
error(ctx, "Expected a condition, not '%s'", ctx->item_string); |
|
|
|
|
|
|
@@ -1555,11 +1546,10 @@ static int CompileIf(CompileContext *ctx, int elif) |
|
|
|
static void FillThen(CompileContext *ctx, int add) |
|
|
|
{ |
|
|
|
unsigned short *p; |
|
|
|
int offset; |
|
|
|
|
|
|
|
p = ctx->if_stack[ctx->if_level].p_then; |
|
|
|
if (p != NULL) { |
|
|
|
offset = ctx->prog_out - p + add; |
|
|
|
int offset = ctx->prog_out - p + add; |
|
|
|
|
|
|
|
if ((ctx->then_count == 1) && (ctx->if_level == 1)) { |
|
|
|
// The THEN part only contains one statement, we can remove the THEN jump |
|
|
@@ -1583,7 +1573,6 @@ static void FillThen(CompileContext *ctx, int add) |
|
|
|
static int CompileElse(CompileContext *ctx) |
|
|
|
{ |
|
|
|
unsigned short *ref; |
|
|
|
unsigned short *p; |
|
|
|
|
|
|
|
if (ctx->if_level < 1) { |
|
|
|
error(ctx, "ELSE not expected"); |
|
|
@@ -1599,6 +1588,7 @@ static int CompileElse(CompileContext *ctx) |
|
|
|
ref = ctx->prog_out; |
|
|
|
*ctx->prog_out++ = 0; |
|
|
|
|
|
|
|
unsigned short *p; |
|
|
|
if ((p = ctx->if_stack[ctx->if_level].p_else) != NULL) |
|
|
|
*ref = ref - p; // backwards offset to the previous else |
|
|
|
ctx->if_stack[ctx->if_level].p_else = ref; |
|
|
@@ -1622,8 +1612,6 @@ static int CompileElif(CompileContext *ctx) |
|
|
|
static int CompileEndif(CompileContext *ctx) |
|
|
|
{ |
|
|
|
unsigned short *p; |
|
|
|
int chain; |
|
|
|
int offset; |
|
|
|
|
|
|
|
if (ctx->if_level < 1) { |
|
|
|
error(ctx, "ENDIF not expected"); |
|
|
@@ -1633,10 +1621,11 @@ static int CompileEndif(CompileContext *ctx) |
|
|
|
FillThen(ctx, 0); |
|
|
|
|
|
|
|
if ((p = ctx->if_stack[ctx->if_level].p_else) != NULL) { |
|
|
|
int chain; |
|
|
|
do { |
|
|
|
chain = *p; // a chain of previous else links |
|
|
|
|
|
|
|
offset = ctx->prog_out - p; |
|
|
|
int offset = ctx->prog_out - p; |
|
|
|
if (offset > MAX_JUMP) |
|
|
|
error(ctx, "IF block is too long"); |
|
|
|
*p = i_JUMP + offset; |
|
|
@@ -1787,7 +1776,6 @@ static void DecThenCount(CompileContext *ctx) |
|
|
|
static int CompilePhoneme(CompileContext *ctx, int compile_phoneme) |
|
|
|
{ |
|
|
|
int endphoneme = 0; |
|
|
|
int keyword; |
|
|
|
int value; |
|
|
|
int phcode = 0; |
|
|
|
int flags; |
|
|
@@ -1836,6 +1824,7 @@ static int CompilePhoneme(CompileContext *ctx, int compile_phoneme) |
|
|
|
ctx->phoneme_out->phflags = 0; |
|
|
|
|
|
|
|
while (!endphoneme && !feof(ctx->f_in)) { |
|
|
|
int keyword; |
|
|
|
if ((keyword = NextItem(ctx, tKEYWORD)) < 0) { |
|
|
|
if (keyword == -2) { |
|
|
|
error(ctx, "Missing 'endphoneme' before end-of-file"); // end of file |
|
|
@@ -2140,9 +2129,7 @@ static void WritePhonemeTables(CompileContext *ctx) |
|
|
|
{ |
|
|
|
int ix; |
|
|
|
int j; |
|
|
|
int n; |
|
|
|
int value; |
|
|
|
int count; |
|
|
|
PHONEME_TAB *p; |
|
|
|
|
|
|
|
value = ctx->n_phoneme_tabs; |
|
|
@@ -2153,12 +2140,12 @@ static void WritePhonemeTables(CompileContext *ctx) |
|
|
|
|
|
|
|
for (ix = 0; ix < ctx->n_phoneme_tabs; ix++) { |
|
|
|
p = ctx->phoneme_tab_list2[ix].phoneme_tab_ptr; |
|
|
|
n = ctx->n_phcodes_list[ix]; |
|
|
|
int n = ctx->n_phcodes_list[ix]; |
|
|
|
memset(&p[n], 0, sizeof(p[n])); |
|
|
|
p[n].mnemonic = 0; // terminate the phoneme table |
|
|
|
|
|
|
|
// count number of locally declared phonemes |
|
|
|
count = 0; |
|
|
|
int count = 0; |
|
|
|
for (j = 0; j < n; j++) { |
|
|
|
if (ix == 0) |
|
|
|
p[j].phflags |= phLOCAL; // write all phonemes in the base phoneme table |
|
|
@@ -2211,8 +2198,6 @@ static void EndPhonemeTable(CompileContext *ctx) |
|
|
|
|
|
|
|
static void StartPhonemeTable(CompileContext *ctx, const char *name) |
|
|
|
{ |
|
|
|
int ix; |
|
|
|
int j; |
|
|
|
PHONEME_TAB *p; |
|
|
|
|
|
|
|
if (ctx->n_phoneme_tabs >= N_PHONEME_TABS-1) { |
|
|
@@ -2235,6 +2220,7 @@ static void StartPhonemeTable(CompileContext *ctx, const char *name) |
|
|
|
|
|
|
|
if (ctx->n_phoneme_tabs > 0) { |
|
|
|
NextItem(ctx, tSTRING); // name of base phoneme table |
|
|
|
int ix; |
|
|
|
for (ix = 0; ix < ctx->n_phoneme_tabs; ix++) { |
|
|
|
if (strcmp(ctx->item_string, ctx->phoneme_tab_list2[ix].name) == 0) { |
|
|
|
ctx->phoneme_tab_list2[ctx->n_phoneme_tabs].includes = ix+1; |
|
|
@@ -2244,6 +2230,7 @@ static void StartPhonemeTable(CompileContext *ctx, const char *name) |
|
|
|
ctx->n_phcodes = ctx->n_phcodes_list[ix]; |
|
|
|
|
|
|
|
// clear "local phoneme" bit" |
|
|
|
int j; |
|
|
|
for (j = 0; j < ctx->n_phcodes; j++) |
|
|
|
ctx->phoneme_tab2[j].phflags &= ~phLOCAL; |
|
|
|
break; |
|
|
@@ -2259,7 +2246,6 @@ static void StartPhonemeTable(CompileContext *ctx, const char *name) |
|
|
|
|
|
|
|
static void CompilePhonemeFiles(CompileContext *ctx) |
|
|
|
{ |
|
|
|
int item; |
|
|
|
FILE *f; |
|
|
|
char buf[sizeof(path_home)+120]; |
|
|
|
|
|
|
@@ -2282,7 +2268,7 @@ static void CompilePhonemeFiles(CompileContext *ctx) |
|
|
|
ctx->linenum = ctx->stack[ctx->stack_ix].linenum; |
|
|
|
} |
|
|
|
|
|
|
|
item = NextItem(ctx, tKEYWORD); |
|
|
|
int item = NextItem(ctx, tKEYWORD); |
|
|
|
|
|
|
|
switch (item) |
|
|
|
{ |
|
|
@@ -2549,7 +2535,6 @@ espeak_ng_CompileIntonationPath(const char *source_path, |
|
|
|
int ix; |
|
|
|
char *p; |
|
|
|
char c; |
|
|
|
int keyword; |
|
|
|
int n_tune_names = 0; |
|
|
|
bool done_split = false; |
|
|
|
bool done_onset = false; |
|
|
@@ -2640,7 +2625,7 @@ espeak_ng_CompileIntonationPath(const char *source_path, |
|
|
|
} |
|
|
|
|
|
|
|
while (!feof(ctx->f_in)) { |
|
|
|
keyword = NextItem(ctx, tINTONATION); |
|
|
|
int keyword = NextItem(ctx, tINTONATION); |
|
|
|
|
|
|
|
switch (keyword) |
|
|
|
{ |