mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-04 22:38:33 +00:00
Revert commit 14a2fb39cf
This commit has been reported to cause distortions in phoneme pitches and speeds.
This commit is contained in:
+16
-8
@@ -113,6 +113,7 @@ char wavefile[200];
|
||||
|
||||
void DisplayVoices(FILE *f_out, char *language)
|
||||
{
|
||||
int ix;
|
||||
const char *p;
|
||||
int len;
|
||||
int count;
|
||||
@@ -139,7 +140,7 @@ void DisplayVoices(FILE *f_out, char *language)
|
||||
|
||||
fprintf(f_out, "Pty Language Age/Gender VoiceName File Other Languages\n");
|
||||
|
||||
for (int ix = 0; (v = voices[ix]) != NULL; ix++) {
|
||||
for (ix = 0; (v = voices[ix]) != NULL; ix++) {
|
||||
count = 0;
|
||||
p = v->languages;
|
||||
while (*p != 0) {
|
||||
@@ -173,7 +174,9 @@ void DisplayVoices(FILE *f_out, char *language)
|
||||
static void Write4Bytes(FILE *f, int value)
|
||||
{
|
||||
// Write 4 bytes to a file, least significant first
|
||||
for (int ix = 0; ix < 4; ix++) {
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
fputc(value & 0xff, f);
|
||||
value = value >> 8;
|
||||
}
|
||||
@@ -214,11 +217,13 @@ int OpenWavFile(char *path, int rate)
|
||||
|
||||
static void CloseWavFile()
|
||||
{
|
||||
unsigned int pos;
|
||||
|
||||
if ((f_wavfile == NULL) || (f_wavfile == stdout))
|
||||
return;
|
||||
|
||||
fflush(f_wavfile);
|
||||
unsigned int pos = ftell(f_wavfile);
|
||||
pos = ftell(f_wavfile);
|
||||
|
||||
fseek(f_wavfile, 4, SEEK_SET);
|
||||
Write4Bytes(f_wavfile, pos - 8);
|
||||
@@ -232,6 +237,8 @@ static void CloseWavFile()
|
||||
|
||||
static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
|
||||
{
|
||||
char fname[210];
|
||||
|
||||
if (quiet) return 0; // -q quiet mode
|
||||
|
||||
if (wav == NULL) {
|
||||
@@ -255,7 +262,6 @@ static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
|
||||
}
|
||||
|
||||
if (f_wavfile == NULL) {
|
||||
char fname[210];
|
||||
if (samples_split > 0) {
|
||||
sprintf(fname, "%s_%.2d%s", wavefile, wavefile_count+1, filetype);
|
||||
if (OpenWavFile(fname, samplerate) != 0)
|
||||
@@ -329,6 +335,7 @@ int main(int argc, char **argv)
|
||||
|
||||
int option_index = 0;
|
||||
int c;
|
||||
int ix;
|
||||
char *optarg2;
|
||||
int value;
|
||||
int flag_stdin = 0;
|
||||
@@ -362,6 +369,7 @@ int main(int argc, char **argv)
|
||||
optind = 1;
|
||||
opt_string = "";
|
||||
while (optind < argc) {
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
if ((c = *opt_string) == 0) {
|
||||
@@ -381,10 +389,10 @@ int main(int argc, char **argv)
|
||||
break; // -- means don't interpret further - as commands
|
||||
|
||||
opt_string = "";
|
||||
for (int ix = 0;; ix++) {
|
||||
for (ix = 0;; ix++) {
|
||||
if (long_options[ix].name == 0)
|
||||
break;
|
||||
size_t len = strlen(long_options[ix].name);
|
||||
len = strlen(long_options[ix].name);
|
||||
if (memcmp(long_options[ix].name, p, len) == 0) {
|
||||
c = long_options[ix].val;
|
||||
optarg2 = NULL;
|
||||
@@ -486,7 +494,7 @@ int main(int argc, char **argv)
|
||||
case 0x103: // --punct
|
||||
option_punctuation = 1;
|
||||
if (optarg2 != NULL) {
|
||||
int ix = 0;
|
||||
ix = 0;
|
||||
while ((ix < N_PUNCTLIST) && ((option_punctlist[ix] = optarg2[ix]) != 0)) ix++;
|
||||
option_punctlist[N_PUNCTLIST-1] = 0;
|
||||
option_punctuation = 2;
|
||||
@@ -665,7 +673,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
} else {
|
||||
// bulk input on stdin
|
||||
int ix = 0;
|
||||
ix = 0;
|
||||
while (!feof(stdin)) {
|
||||
p_text[ix++] = fgetc(stdin);
|
||||
if (ix >= (max-1)) {
|
||||
|
||||
+146
-79
@@ -386,6 +386,7 @@ 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];
|
||||
@@ -401,7 +402,7 @@ static void ReadPhondataManifest()
|
||||
rewind(f);
|
||||
|
||||
if (manifest != NULL) {
|
||||
for (int ix = 0; ix < n_manifest; ix++)
|
||||
for (ix = 0; ix < n_manifest; ix++)
|
||||
free(manifest[ix].name);
|
||||
}
|
||||
|
||||
@@ -442,7 +443,13 @@ static const char *KeyToMnem(keywtab_t *ktab, int type, int value)
|
||||
static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)
|
||||
{
|
||||
USHORT *pc;
|
||||
int instn;
|
||||
int instn_category;
|
||||
int address, address2;
|
||||
int data1;
|
||||
int type2;
|
||||
int ix;
|
||||
int any;
|
||||
const char *name;
|
||||
char buf[120];
|
||||
|
||||
@@ -486,10 +493,10 @@ static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)
|
||||
|
||||
pc = prog_buf;
|
||||
while (pc < prog_out) {
|
||||
int instn = *pc++;
|
||||
int instn_category = (instn >> 12) & 0xf;
|
||||
int data1 = instn & 0xff;
|
||||
int type2 = (instn >> 8) & 0xf;
|
||||
instn = *pc++;
|
||||
instn_category = (instn >> 12) & 0xf;
|
||||
data1 = instn & 0xff;
|
||||
type2 = (instn >> 8) & 0xf;
|
||||
fprintf(f_out, " %.3x: %.4x %s", (unsigned int)(pc-prog_buf), instn, instn_category_string[instn_category]);
|
||||
|
||||
switch (instn_category)
|
||||
@@ -503,7 +510,6 @@ static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)
|
||||
data1 = 0;
|
||||
fprintf(f_out, "%s", instn0_string[data1]);
|
||||
} else if (type2 == i_IPA_NAME) {
|
||||
int ix;
|
||||
for (ix = 0; ix < data1; ix += 2) {
|
||||
instn = *pc++;
|
||||
buf[ix] = instn >> 8;
|
||||
@@ -565,8 +571,8 @@ static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)
|
||||
} else if (type2 == 8) {
|
||||
// list of numbers
|
||||
fprintf(f_out, " StressLevel(");
|
||||
int any = 0;
|
||||
for (int ix = 0; ix < 8; ix++) {
|
||||
any = 0;
|
||||
for (ix = 0; ix < 8; ix++) {
|
||||
if (data1 & (1 << ix)) {
|
||||
if (any)
|
||||
fputc(',', f_out);
|
||||
@@ -703,10 +709,12 @@ char item_string[N_ITEM_STRING];
|
||||
|
||||
static int ref_sorter(char **a, char **b)
|
||||
{
|
||||
int ix;
|
||||
|
||||
REF_HASH_TAB *p1 = (REF_HASH_TAB *)(*a);
|
||||
REF_HASH_TAB *p2 = (REF_HASH_TAB *)(*b);
|
||||
|
||||
int ix = strcoll(p1->string, p2->string);
|
||||
ix = strcoll(p1->string, p2->string);
|
||||
if (ix != 0)
|
||||
return ix;
|
||||
|
||||
@@ -720,9 +728,14 @@ static int ref_sorter(char **a, char **b)
|
||||
static void CompileReport(void)
|
||||
{
|
||||
int ix;
|
||||
int hash;
|
||||
int n;
|
||||
REF_HASH_TAB *p;
|
||||
REF_HASH_TAB **list;
|
||||
const char *data_path;
|
||||
int prev_table;
|
||||
int procedure_num;
|
||||
int prev_mnemonic;
|
||||
|
||||
if (f_report == NULL)
|
||||
return;
|
||||
@@ -740,19 +753,19 @@ static void CompileReport(void)
|
||||
|
||||
fprintf(f_report, "Data file Used by\n");
|
||||
ix = 0;
|
||||
for (int hash = 0; (hash < 256) && (ix < count_references); hash++) {
|
||||
for (hash = 0; (hash < 256) && (ix < count_references); hash++) {
|
||||
p = ref_hash_tab[hash];
|
||||
while (p != NULL) {
|
||||
list[ix++] = p;
|
||||
p = (REF_HASH_TAB *)(p->link);
|
||||
}
|
||||
}
|
||||
int n = ix;
|
||||
n = ix;
|
||||
qsort((void *)list, n, sizeof(REF_HASH_TAB *), (int (*)(const void *, const void *))ref_sorter);
|
||||
|
||||
data_path = "";
|
||||
int prev_mnemonic = 0;
|
||||
int prev_table = 0;
|
||||
prev_mnemonic = 0;
|
||||
prev_table = 0;
|
||||
for (ix = 0; ix < n; ix++) {
|
||||
int j = 0;
|
||||
|
||||
@@ -771,7 +784,7 @@ static void CompileReport(void)
|
||||
prev_mnemonic = list[ix]->ph_mnemonic;
|
||||
if ((prev_mnemonic >> 24) == 'P') {
|
||||
// a procedure, not a phoneme
|
||||
int procedure_num = atoi(WordToString(prev_mnemonic));
|
||||
procedure_num = atoi(WordToString(prev_mnemonic));
|
||||
fprintf(f_report, " %s %s", phoneme_tab_list2[prev_table = list[ix]->ph_table].name, proc_names[procedure_num]);
|
||||
} else
|
||||
fprintf(f_report, " [%s] %s", WordToString(prev_mnemonic), phoneme_tab_list2[prev_table = list[ix]->ph_table].name);
|
||||
@@ -818,14 +831,15 @@ 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;
|
||||
unsigned char c;
|
||||
unsigned int word;
|
||||
|
||||
if (string == NULL)
|
||||
return 0;
|
||||
|
||||
unsigned int word = 0;
|
||||
for (int ix = 0; ix < 4; ix++) {
|
||||
word = 0;
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
if (string[ix] == 0) break;
|
||||
c = string[ix];
|
||||
word |= (c << (ix*8));
|
||||
@@ -895,16 +909,21 @@ 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;
|
||||
unsigned int word;
|
||||
|
||||
if (strcmp(string, "NULL") == 0)
|
||||
return 1;
|
||||
|
||||
int ix = strlen(string);
|
||||
ix = strlen(string);
|
||||
if ((ix == 0) || (ix > 4))
|
||||
error("Bad phoneme name '%s'", string);
|
||||
unsigned int word = StringToWord(string);
|
||||
word = StringToWord(string);
|
||||
|
||||
// don't use phoneme number 0, reserved for string terminator
|
||||
int start = 1;
|
||||
start = 1;
|
||||
|
||||
if (control == 2) {
|
||||
// don't look for control and stress phonemes (allows these characters to be
|
||||
@@ -912,7 +931,7 @@ static int LookupPhoneme(const char *string, int control)
|
||||
start = 8;
|
||||
}
|
||||
|
||||
int use = 0;
|
||||
use = 0;
|
||||
for (ix = start; ix < n_phcodes; ix++) {
|
||||
if (phoneme_tab2[ix].mnemonic == word)
|
||||
return ix;
|
||||
@@ -938,7 +957,8 @@ static int LookupPhoneme(const char *string, int control)
|
||||
|
||||
static unsigned int get_char()
|
||||
{
|
||||
unsigned int c = fgetc(f_in);
|
||||
unsigned int c;
|
||||
c = fgetc(f_in);
|
||||
if (c == '\n')
|
||||
linenum++;
|
||||
return c;
|
||||
@@ -965,6 +985,8 @@ static int NextItem(int type)
|
||||
int acc;
|
||||
unsigned char c = 0;
|
||||
unsigned char c2;
|
||||
int ix;
|
||||
int sign;
|
||||
char *p;
|
||||
keywtab_t *pk;
|
||||
|
||||
@@ -995,7 +1017,7 @@ static int NextItem(int type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ix = 0;
|
||||
ix = 0;
|
||||
while (!feof(f_in) && !isspace(c) && (c != '(') && (c != ')') && (c != ',')) {
|
||||
if (c == '\\')
|
||||
c = get_char();
|
||||
@@ -1026,7 +1048,7 @@ static int NextItem(int type)
|
||||
|
||||
if ((type == tNUMBER) || (type == tSIGNEDNUMBER)) {
|
||||
acc = 0;
|
||||
int sign = 1;
|
||||
sign = 1;
|
||||
p = item_string;
|
||||
|
||||
if ((*p == '-') && (type == tSIGNEDNUMBER)) {
|
||||
@@ -1067,9 +1089,10 @@ static int NextItem(int type)
|
||||
static int NextItemMax(int max)
|
||||
{
|
||||
// Get a number, but restrict value to max
|
||||
int value;
|
||||
char msg[80];
|
||||
|
||||
int value = NextItem(tNUMBER);
|
||||
value = NextItem(tNUMBER);
|
||||
if (value > max) {
|
||||
sprintf(msg, "Value %d is greater than maximum %d", value, max);
|
||||
error(msg, NULL);
|
||||
@@ -1084,12 +1107,14 @@ static int NextItemBrackets(int type, int control)
|
||||
// control: bit 0 0= need (
|
||||
// bit 1 1= allow comma
|
||||
|
||||
int value;
|
||||
|
||||
if ((control & 1) == 0) {
|
||||
if (!NextItem(tOPENBRACKET))
|
||||
error("Expected '('", NULL);
|
||||
}
|
||||
|
||||
int value = NextItem(type);
|
||||
value = NextItem(type);
|
||||
if ((control & 2) && (item_terminator == ','))
|
||||
return value;
|
||||
|
||||
@@ -1122,7 +1147,7 @@ static int Range(int value, int divide, int min, int max)
|
||||
int CompileVowelTransition(int which)
|
||||
{
|
||||
// Compile a vowel transition
|
||||
|
||||
int key;
|
||||
int len = 0;
|
||||
int rms = 0;
|
||||
int f1 = 0;
|
||||
@@ -1133,7 +1158,10 @@ int CompileVowelTransition(int which)
|
||||
int f3_amp = 0;
|
||||
int flags = 0;
|
||||
int vcolour = 0;
|
||||
int x;
|
||||
int instn = i_VOWELIN;
|
||||
int word1;
|
||||
int word2;
|
||||
|
||||
if (which == 1) {
|
||||
len = 50 / 2; // defaults for transition into vowel
|
||||
@@ -1150,7 +1178,7 @@ int CompileVowelTransition(int which)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int key = NextItem(tKEYWORD);
|
||||
key = NextItem(tKEYWORD);
|
||||
if (item_type != tTRANSITION) {
|
||||
UngetItem();
|
||||
break;
|
||||
@@ -1174,7 +1202,7 @@ int CompileVowelTransition(int which)
|
||||
f2_min = Range(NextItem(tSIGNEDNUMBER), 50, -15, 15) & 0x1f;
|
||||
f2_max = Range(NextItem(tSIGNEDNUMBER), 50, -15, 15) & 0x1f;
|
||||
if (f2_min > f2_max) {
|
||||
int x = f2_min;
|
||||
x = f2_min;
|
||||
f2_min = f2_max;
|
||||
f2_max = x;
|
||||
}
|
||||
@@ -1211,8 +1239,8 @@ int CompileVowelTransition(int which)
|
||||
break;
|
||||
}
|
||||
}
|
||||
int word1 = len + (rms << 6) + (flags << 12);
|
||||
int word2 = f2 + (f2_min << 6) + (f2_max << 11) + (f3_adj << 16) + (f3_amp << 21) + (f1 << 26) + (vcolour << 29);
|
||||
word1 = len + (rms << 6) + (flags << 12);
|
||||
word2 = f2 + (f2_min << 6) + (f2_max << 11) + (f3_adj << 16) + (f3_amp << 21) + (f1 << 26) + (vcolour << 29);
|
||||
prog_out[0] = instn + ((word1 >> 16) & 0xff);
|
||||
prog_out[1] = word1;
|
||||
prog_out[2] = word2 >> 16;
|
||||
@@ -1225,8 +1253,14 @@ int CompileVowelTransition(int which)
|
||||
int LoadSpect(const char *path, int control)
|
||||
{
|
||||
SpectSeq *spectseq;
|
||||
int peak;
|
||||
int displ;
|
||||
int frame;
|
||||
int n_frames;
|
||||
int ix;
|
||||
int x, x2;
|
||||
int rms;
|
||||
float total;
|
||||
float pkheight;
|
||||
int marker1_set = 0;
|
||||
int frame_vowelbreak = 0;
|
||||
@@ -1255,21 +1289,21 @@ int LoadSpect(const char *path, int control)
|
||||
}
|
||||
|
||||
// do we need additional klatt data ?
|
||||
for (int frame = 0; frame < spectseq->numframes; frame++) {
|
||||
for (frame = 0; frame < spectseq->numframes; frame++) {
|
||||
for (ix = 5; ix < N_KLATTP2; ix++) {
|
||||
if (spectseq->frames[frame]->klatt_param[ix] != 0)
|
||||
klatt_flag = FRFLAG_KLATT;
|
||||
}
|
||||
}
|
||||
|
||||
int displ = ftell(f_phdata);
|
||||
displ = ftell(f_phdata);
|
||||
|
||||
seq_out.n_frames = 0;
|
||||
seq_out.sqflags = 0;
|
||||
seq_out.length_total = 0;
|
||||
|
||||
float total = 0.0f;
|
||||
for (int frame = 0; frame < spectseq->numframes; frame++) {
|
||||
total = 0;
|
||||
for (frame = 0; frame < spectseq->numframes; frame++) {
|
||||
if (spectseq->frames[frame]->keyframe) {
|
||||
if (seq_out.n_frames == 1)
|
||||
frame_vowelbreak = frame;
|
||||
@@ -1291,8 +1325,8 @@ int LoadSpect(const char *path, int control)
|
||||
spectseq->frames[frame_vowelbreak]->markers |= FRFLAG_VOWEL_CENTRE;
|
||||
}
|
||||
|
||||
int n_frames = 0;
|
||||
for (int frame = 0; frame < spectseq->numframes; frame++) {
|
||||
n_frames = 0;
|
||||
for (frame = 0; frame < spectseq->numframes; frame++) {
|
||||
fr = spectseq->frames[frame];
|
||||
|
||||
if (fr->keyframe) {
|
||||
@@ -1307,7 +1341,7 @@ int LoadSpect(const char *path, int control)
|
||||
|
||||
fr_out->frflags = fr->markers | klatt_flag;
|
||||
|
||||
int rms = (int)GetFrameRms(fr, spectseq->amplitude);
|
||||
rms = (int)GetFrameRms(fr, spectseq->amplitude);
|
||||
if (rms > 255) rms = 255;
|
||||
fr_out->rms = rms;
|
||||
|
||||
@@ -1316,7 +1350,7 @@ int LoadSpect(const char *path, int control)
|
||||
|
||||
// write: peak data
|
||||
count_frames++;
|
||||
for (int peak = 0; peak < 8; peak++) {
|
||||
for (peak = 0; peak < 8; peak++) {
|
||||
if (peak < 7)
|
||||
fr_out->ffreq[peak] = fr->peaks[peak].pkfreq;
|
||||
|
||||
@@ -1355,7 +1389,7 @@ int LoadSpect(const char *path, int control)
|
||||
for (ix = 0; ix < 5; ix++)
|
||||
fr_out->klattp2[ix] = fr->klatt_param[ix+5];
|
||||
|
||||
for (int peak = 0; peak < 7; peak++) {
|
||||
for (peak = 0; peak < 7; peak++) {
|
||||
fr_out->klatt_ap[ix] = fr->peaks[peak].klt_ap;
|
||||
|
||||
x = fr->peaks[peak].klt_bp / 2;
|
||||
@@ -1395,13 +1429,18 @@ int LoadSpect(const char *path, int control)
|
||||
|
||||
static int LoadWavefile(FILE *f, const char *fname)
|
||||
{
|
||||
int displ;
|
||||
unsigned char c1;
|
||||
unsigned char c3;
|
||||
int c2;
|
||||
int sample;
|
||||
int sample2;
|
||||
float x;
|
||||
int max = 0;
|
||||
int length;
|
||||
int sr1, sr2;
|
||||
int failed;
|
||||
int len;
|
||||
int resample_wav = 0;
|
||||
const char *fname2;
|
||||
char fname_temp[100];
|
||||
@@ -1409,8 +1448,8 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
int scale_factor = 0;
|
||||
|
||||
fseek(f, 24, SEEK_SET);
|
||||
int sr1 = Read4Bytes(f);
|
||||
int sr2 = Read4Bytes(f);
|
||||
sr1 = Read4Bytes(f);
|
||||
sr2 = Read4Bytes(f);
|
||||
fseek(f, 40, SEEK_SET);
|
||||
|
||||
if ((sr1 != samplerate_native) || (sr2 != sr1*2)) {
|
||||
@@ -1428,7 +1467,7 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
#endif
|
||||
|
||||
fname2 = fname;
|
||||
size_t len = strlen(fname);
|
||||
len = strlen(fname);
|
||||
if (strcmp(&fname[len-4], ".wav") == 0) {
|
||||
strcpy(msg, fname);
|
||||
msg[len-4] = 0;
|
||||
@@ -1465,10 +1504,10 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
fseek(f, 40, SEEK_SET); // skip past the WAV header, up to before "data length"
|
||||
}
|
||||
|
||||
int displ = ftell(f_phdata);
|
||||
displ = ftell(f_phdata);
|
||||
|
||||
// data contains: 4 bytes of length (n_samples * 2), followed by 2-byte samples (lsb byte first)
|
||||
int length = Read4Bytes(f);
|
||||
length = Read4Bytes(f);
|
||||
|
||||
while (!feof(f)) {
|
||||
c1 = fgetc(f);
|
||||
@@ -1510,7 +1549,7 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
fputc(sample & 0xff, f_phdata);
|
||||
fputc(sample >> 8, f_phdata);
|
||||
} else {
|
||||
float x = ((float)sample / scale_factor) + 0.5;
|
||||
x = ((float)sample / scale_factor) + 0.5;
|
||||
sample2 = (int)x;
|
||||
if (sample2 > 127)
|
||||
sample2 = 127;
|
||||
@@ -1536,9 +1575,10 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
|
||||
static int LoadEnvelope(FILE *f, const char *fname)
|
||||
{
|
||||
int displ;
|
||||
char buf[128];
|
||||
|
||||
int displ = ftell(f_phdata);
|
||||
displ = ftell(f_phdata);
|
||||
|
||||
fseek(f, 12, SEEK_SET);
|
||||
if (fread(buf, 128, 1, f) == 0)
|
||||
@@ -1573,16 +1613,20 @@ static int Hash8(const char *string)
|
||||
|
||||
static int LoadEnvelope2(FILE *f, const char *fname)
|
||||
{
|
||||
int ix, ix2;
|
||||
int n;
|
||||
int x, y;
|
||||
int displ;
|
||||
int n_points;
|
||||
double yy;
|
||||
char line_buf[128];
|
||||
float env_x[20];
|
||||
float env_y[20];
|
||||
int env_lin[20];
|
||||
unsigned char env[ENV_LEN];
|
||||
|
||||
int n_points = 0;
|
||||
n_points = 0;
|
||||
fgets(line_buf, sizeof(line_buf), f); // skip first line
|
||||
|
||||
while (!feof(f)) {
|
||||
if (fgets(line_buf, sizeof(line_buf), f) == NULL)
|
||||
break;
|
||||
@@ -1597,17 +1641,16 @@ static int LoadEnvelope2(FILE *f, const char *fname)
|
||||
env_x[n_points] = env_x[n_points-1];
|
||||
env_y[n_points] = env_y[n_points-1];
|
||||
|
||||
int ix = -1;
|
||||
int ix2 = 0;
|
||||
int y = 0;
|
||||
for (int x = 0; x < ENV_LEN; x++) {
|
||||
ix = -1;
|
||||
ix2 = 0;
|
||||
for (x = 0; x < ENV_LEN; x++) {
|
||||
if (x > env_x[ix+4])
|
||||
ix++;
|
||||
if (x >= env_x[ix2+1])
|
||||
ix2++;
|
||||
|
||||
if (env_lin[ix2] > 0) {
|
||||
double yy = env_y[ix2] + (env_y[ix2+1] - env_y[ix2]) * ((float)x - env_x[ix2]) / (env_x[ix2+1] - env_x[ix2]);
|
||||
yy = env_y[ix2] + (env_y[ix2+1] - env_y[ix2]) * ((float)x - env_x[ix2]) / (env_x[ix2+1] - env_x[ix2]);
|
||||
y = (int)(yy * 2.55);
|
||||
} else if (n_points > 3)
|
||||
y = (int)(polint(&env_x[ix], &env_y[ix], 4, x) * 2.55); // convert to range 0-255
|
||||
@@ -1624,7 +1667,7 @@ static int LoadEnvelope2(FILE *f, const char *fname)
|
||||
n_envelopes++;
|
||||
}
|
||||
|
||||
int displ = ftell(f_phdata);
|
||||
displ = ftell(f_phdata);
|
||||
fwrite(env, 1, 128, f_phdata);
|
||||
|
||||
return displ;
|
||||
@@ -1636,6 +1679,8 @@ static int LoadDataFile(const char *path, int control)
|
||||
// return index into spect or sample data area. bit 23=1 if a sample
|
||||
|
||||
FILE *f;
|
||||
int id;
|
||||
int hash;
|
||||
int addr = 0;
|
||||
int type_code = ' ';
|
||||
REF_HASH_TAB *p, *p2;
|
||||
@@ -1648,7 +1693,7 @@ static int LoadDataFile(const char *path, int control)
|
||||
|
||||
count_references++;
|
||||
|
||||
int hash = Hash8(path);
|
||||
hash = Hash8(path);
|
||||
p = ref_hash_tab[hash];
|
||||
while (p != NULL) {
|
||||
if (strcmp(path, p->string) == 0) {
|
||||
@@ -1670,7 +1715,7 @@ static int LoadDataFile(const char *path, int control)
|
||||
}
|
||||
}
|
||||
|
||||
int id = Read4Bytes(f);
|
||||
id = Read4Bytes(f);
|
||||
rewind(f);
|
||||
|
||||
if (id == 0x43455053) {
|
||||
@@ -1712,11 +1757,13 @@ static int LoadDataFile(const char *path, int control)
|
||||
|
||||
static int CompileToneSpec(void)
|
||||
{
|
||||
int pitch1 = 0;
|
||||
int pitch2 = 0;
|
||||
int pitch_env = 0;
|
||||
int amp_env = 0;
|
||||
|
||||
int pitch1 = NextItemBrackets(tNUMBER, 2);
|
||||
int pitch2 = NextItemBrackets(tNUMBER, 3);
|
||||
pitch1 = NextItemBrackets(tNUMBER, 2);
|
||||
pitch2 = NextItemBrackets(tNUMBER, 3);
|
||||
|
||||
if (item_terminator == ',') {
|
||||
NextItemBrackets(tSTRING, 3);
|
||||
@@ -1752,6 +1799,7 @@ static int CompileToneSpec(void)
|
||||
|
||||
int CompileSound(int keyword, int isvowel)
|
||||
{
|
||||
int addr;
|
||||
int value = 0;
|
||||
char path[N_ITEM_STRING];
|
||||
static int sound_instns[] = { i_FMT, i_WAV, i_VWLSTART, i_VWLENDING, i_WAVADD };
|
||||
@@ -1777,7 +1825,7 @@ int CompileSound(int keyword, int isvowel)
|
||||
}
|
||||
}
|
||||
}
|
||||
int addr = LoadDataFile(path, isvowel);
|
||||
addr = LoadDataFile(path, isvowel);
|
||||
addr = addr / 4; // addr is words not bytes
|
||||
|
||||
*prog_out++ = sound_instns[keyword-kFMT] + ((value & 0xff) << 4) + ((addr >> 16) & 0xf);
|
||||
@@ -1803,6 +1851,8 @@ int CompileIf(int elif)
|
||||
int word = 0;
|
||||
int word2;
|
||||
int data;
|
||||
int bitmap;
|
||||
int brackets;
|
||||
int not_flag;
|
||||
USHORT *prog_last_if = NULL;
|
||||
|
||||
@@ -1844,8 +1894,8 @@ int CompileIf(int elif)
|
||||
}
|
||||
} else if (item_type == tTEST) {
|
||||
if (key == kTHISSTRESS) {
|
||||
int bitmap = 0;
|
||||
int brackets = 2;
|
||||
bitmap = 0;
|
||||
brackets = 2;
|
||||
do {
|
||||
data = NextItemBrackets(tNUMBER, brackets);
|
||||
if (data > 7)
|
||||
@@ -1906,10 +1956,11 @@ int CompileIf(int elif)
|
||||
void FillThen(int add)
|
||||
{
|
||||
USHORT *p;
|
||||
int offset;
|
||||
|
||||
p = if_stack[if_level].p_then;
|
||||
if (p != NULL) {
|
||||
int offset = prog_out - p + add;
|
||||
offset = prog_out - p + add;
|
||||
|
||||
if ((then_count == 1) && (if_level == 1)) {
|
||||
// The THEN part only contains one statement, we can remove the THEN jump
|
||||
@@ -2019,7 +2070,9 @@ static int CompileSwitch(int type)
|
||||
|
||||
static PHONEME_TAB_LIST *FindPhonemeTable(const char *string)
|
||||
{
|
||||
for (int ix = 0; ix < n_phoneme_tabs; ix++) {
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < n_phoneme_tabs; ix++) {
|
||||
if (strcmp(phoneme_tab_list2[ix].name, string) == 0)
|
||||
return &phoneme_tab_list2[ix];
|
||||
}
|
||||
@@ -2031,6 +2084,7 @@ static PHONEME_TAB *FindPhoneme(const char *string)
|
||||
{
|
||||
PHONEME_TAB_LIST *phtab = NULL;
|
||||
int ix;
|
||||
unsigned int mnem;
|
||||
char *phname;
|
||||
char buf[200];
|
||||
|
||||
@@ -2047,7 +2101,7 @@ static PHONEME_TAB *FindPhoneme(const char *string)
|
||||
if (phtab == NULL)
|
||||
return NULL; // phoneme table not found
|
||||
|
||||
unsigned int mnem = StringToWord(phname);
|
||||
mnem = StringToWord(phname);
|
||||
for (ix = 1; ix < 256; ix++) {
|
||||
if (mnem == phtab->phoneme_tab_ptr[ix].mnemonic)
|
||||
return &phtab->phoneme_tab_ptr[ix];
|
||||
@@ -2059,6 +2113,8 @@ static PHONEME_TAB *FindPhoneme(const char *string)
|
||||
|
||||
static void ImportPhoneme(void)
|
||||
{
|
||||
unsigned int ph_mnem;
|
||||
unsigned int ph_code;
|
||||
PHONEME_TAB *ph;
|
||||
|
||||
NextItem(tSTRING);
|
||||
@@ -2066,8 +2122,8 @@ static void ImportPhoneme(void)
|
||||
if ((ph = FindPhoneme(item_string)) == NULL)
|
||||
return;
|
||||
|
||||
unsigned int ph_mnem = phoneme_out->mnemonic;
|
||||
unsigned int ph_code = phoneme_out->code;
|
||||
ph_mnem = phoneme_out->mnemonic;
|
||||
ph_code = phoneme_out->code;
|
||||
memcpy(phoneme_out, ph, sizeof(PHONEME_TAB));
|
||||
phoneme_out->mnemonic = ph_mnem;
|
||||
phoneme_out->code = ph_code;
|
||||
@@ -2120,7 +2176,9 @@ static void DecThenCount()
|
||||
|
||||
static void InstnPlusPhoneme(int instn)
|
||||
{
|
||||
int phcode = NextItemBrackets(tPHONEMEMNEM, 0);
|
||||
int phcode;
|
||||
|
||||
phcode = NextItemBrackets(tPHONEMEMNEM, 0);
|
||||
*prog_out++ = instn + phcode;
|
||||
}
|
||||
|
||||
@@ -2130,6 +2188,10 @@ int CompilePhoneme(int compile_phoneme)
|
||||
int keyword;
|
||||
int value;
|
||||
int phcode = 0;
|
||||
int flags;
|
||||
int ix;
|
||||
int start;
|
||||
int count;
|
||||
int c;
|
||||
char *p;
|
||||
int vowel_length_factor = 100; // for testing
|
||||
@@ -2251,9 +2313,9 @@ int CompilePhoneme(int compile_phoneme)
|
||||
strcpy(item_string, " ");
|
||||
|
||||
// copy the string, recognize characters in the form U+9999
|
||||
int flags = 0;
|
||||
int count = 0;
|
||||
int ix = 1;
|
||||
flags = 0;
|
||||
count = 0;
|
||||
ix = 1;
|
||||
|
||||
for (p = item_string; *p != 0;) {
|
||||
p += utf8_in(&c, p);
|
||||
@@ -2286,7 +2348,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
ipa_buf[0] = flags;
|
||||
ipa_buf[ix] = 0;
|
||||
|
||||
int start = 1;
|
||||
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
|
||||
@@ -2465,24 +2527,27 @@ int CompilePhoneme(int compile_phoneme)
|
||||
|
||||
static void WritePhonemeTables()
|
||||
{
|
||||
int ix;
|
||||
int j;
|
||||
int n;
|
||||
int value;
|
||||
int count;
|
||||
PHONEME_TAB *p;
|
||||
|
||||
int value = n_phoneme_tabs;
|
||||
value = n_phoneme_tabs;
|
||||
fputc(value, f_phtab);
|
||||
fputc(0, f_phtab);
|
||||
fputc(0, f_phtab);
|
||||
fputc(0, f_phtab);
|
||||
|
||||
for (int ix = 0; ix < n_phoneme_tabs; ix++) {
|
||||
for (ix = 0; ix < n_phoneme_tabs; ix++) {
|
||||
p = phoneme_tab_list2[ix].phoneme_tab_ptr;
|
||||
n = n_phcodes_list[ix];
|
||||
p[n].mnemonic = 0; // terminate the phoneme table
|
||||
|
||||
// count number of locally declared phonemes
|
||||
count = 0;
|
||||
for (int j = 0; j < n; j++) {
|
||||
for (j = 0; j < n; j++) {
|
||||
if (ix == 0)
|
||||
p[j].phflags |= phLOCAL; // write all phonemes in the base phoneme table
|
||||
|
||||
@@ -2499,7 +2564,7 @@ static void WritePhonemeTables()
|
||||
|
||||
fwrite(phoneme_tab_list2[ix].name, 1, N_PHONEME_TAB_NAME, f_phtab);
|
||||
|
||||
for (int j = 0; j < n; j++) {
|
||||
for (j = 0; j < n; j++) {
|
||||
if (p[j].phflags & phLOCAL) {
|
||||
// this bit is set temporarily to incidate a local phoneme, declared in
|
||||
// in the current phoneme file
|
||||
@@ -2551,6 +2616,7 @@ static void EndPhonemeTable()
|
||||
static void StartPhonemeTable(const char *name)
|
||||
{
|
||||
int ix;
|
||||
int j;
|
||||
PHONEME_TAB *p;
|
||||
|
||||
fprintf(f_errors, "______________________________\nPhoneme Table: '%s'\n", name);
|
||||
@@ -2584,7 +2650,7 @@ static void StartPhonemeTable(const char *name)
|
||||
n_phcodes = n_phcodes_list[ix];
|
||||
|
||||
// clear "local phoneme" bit"
|
||||
for (int j = 0; j < n_phcodes; j++)
|
||||
for (j = 0; j < n_phcodes; j++)
|
||||
phoneme_tab2[j].phflags &= ~phLOCAL;
|
||||
break;
|
||||
}
|
||||
@@ -2601,6 +2667,7 @@ static void CompileEquivalents()
|
||||
{
|
||||
// a list of phonemes in another language and the equivalent phoneme strings in this language
|
||||
|
||||
int ix;
|
||||
int n_names;
|
||||
int n_bytes;
|
||||
int foreign_phoneme;
|
||||
@@ -2638,7 +2705,7 @@ static void CompileEquivalents()
|
||||
if ((p = strstr(line_buf, "//")) != NULL)
|
||||
*p = 0;
|
||||
|
||||
for (int ix = 0; ix < 6; ix++)
|
||||
for (ix = 0; ix < 6; ix++)
|
||||
names[ix][0] = 0;
|
||||
n_names = sscanf(line_buf, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]);
|
||||
if (n_names < 1)
|
||||
@@ -2668,7 +2735,7 @@ static void CompileEquivalents()
|
||||
}
|
||||
}
|
||||
|
||||
for (int ix = 1; ix < n_names; ix++)
|
||||
for (ix = 1; ix < n_names; ix++)
|
||||
phcode[ix] = LookupPhoneme(names[ix], 1);
|
||||
|
||||
// only write a translation if it has an effect
|
||||
|
||||
@@ -197,6 +197,7 @@ const char *LookupMnemName(MNEM_TAB *table, const int value)
|
||||
void print_dictionary_flags(unsigned int *flags, char *buf, int buf_len)
|
||||
{
|
||||
int stress;
|
||||
int ix;
|
||||
const char *name;
|
||||
int len;
|
||||
int total = 0;
|
||||
@@ -208,7 +209,7 @@ void print_dictionary_flags(unsigned int *flags, char *buf, int buf_len)
|
||||
buf += total;
|
||||
}
|
||||
|
||||
for (int ix = 8; ix < 64; ix++) {
|
||||
for (ix = 8; ix < 64; ix++) {
|
||||
if (((ix < 30) && (flags[0] & (1 << ix))) || ((ix >= 0x20) && (flags[1] & (1 << (ix-0x20))))) {
|
||||
name = LookupMnemName(mnem_flags, ix);
|
||||
len = strlen(name) + 1;
|
||||
@@ -229,6 +230,8 @@ 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;
|
||||
@@ -251,10 +254,9 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
|
||||
|
||||
static char symbols_lg[] = { 'A', 'B', 'C', 'H', 'F', 'G', 'Y' };
|
||||
|
||||
int match_type = 0;
|
||||
match_type = 0;
|
||||
buf_pre[0] = 0;
|
||||
|
||||
int ix;
|
||||
for (ix = 0; ix < group_length; ix++)
|
||||
buf[ix] = group_chars[ix];
|
||||
buf[ix] = 0;
|
||||
@@ -386,26 +388,35 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
char *word;
|
||||
char *phonetic;
|
||||
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;
|
||||
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;
|
||||
int all_upper_case;
|
||||
|
||||
char *mnemptr;
|
||||
unsigned char flag_codes[100];
|
||||
char encoded_ph[200];
|
||||
char bad_phoneme_str[4];
|
||||
int bad_phoneme;
|
||||
static char nullstring[] = { 0 };
|
||||
|
||||
int text_not_phonemes = 0; // this word specifies replacement text, not phonemes
|
||||
text_not_phonemes = 0;
|
||||
phonetic = word = nullstring;
|
||||
|
||||
p = linebuf;
|
||||
|
||||
int step = 0;
|
||||
step = 0;
|
||||
|
||||
c = 0;
|
||||
while (c != '\n') {
|
||||
@@ -413,7 +424,7 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
|
||||
if ((c == '?') && (step == 0)) {
|
||||
// conditional rule, allow only if the numbered condition is set for the voice
|
||||
int flag_offset = 100;
|
||||
flag_offset = 100;
|
||||
|
||||
p++;
|
||||
if (*p == '!') {
|
||||
@@ -441,7 +452,7 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
while (!isspace2(c = *p)) p++;
|
||||
*p = 0;
|
||||
|
||||
int flagnum = LookupMnem(mnem_flags, mnemptr);
|
||||
flagnum = LookupMnem(mnem_flags, mnemptr);
|
||||
if (flagnum > 0) {
|
||||
if (flagnum == 200)
|
||||
text_mode = 1;
|
||||
@@ -552,14 +563,12 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
// this is replacement text, so don't encode as phonemes. Restrict the length of the replacement word
|
||||
strncpy0(encoded_ph, phonetic, N_WORD_BYTES-4);
|
||||
} else {
|
||||
int bad_phoneme;
|
||||
EncodePhonemes(phonetic, encoded_ph, &bad_phoneme);
|
||||
if (strchr(encoded_ph, phonSWITCH) != 0)
|
||||
flag_codes[n_flag_codes++] = BITNUM_FLAG_ONLY_S; // don't match on suffixes (except 's') when switching languages
|
||||
|
||||
// check for errors in the phonemes codes
|
||||
if (bad_phoneme != 0) {
|
||||
char bad_phoneme_str[4];
|
||||
// unrecognised phoneme, report error
|
||||
bad_phoneme_str[utf8_out(bad_phoneme, bad_phoneme_str)] = 0;
|
||||
fprintf(f_log, "%5d: Bad phoneme [%s] (U+%x) in: %s %s\n", linenum, bad_phoneme_str, bad_phoneme, word, phonetic);
|
||||
@@ -578,7 +587,7 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
// convert to lower case, and note if the word is all-capitals
|
||||
int c2;
|
||||
|
||||
int all_upper_case = 1;
|
||||
all_upper_case = 1;
|
||||
p = word;
|
||||
for (p = word;;) {
|
||||
// this assumes that the lower case char is the same length as the upper case char
|
||||
@@ -596,13 +605,13 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
flag_codes[n_flag_codes++] = BITNUM_FLAG_ALLCAPS;
|
||||
}
|
||||
|
||||
int len_word = strlen(word);
|
||||
len_word = strlen(word);
|
||||
|
||||
if (translator->transpose_min > 0)
|
||||
len_word = TransposeAlphabet(translator, word);
|
||||
|
||||
*hash = HashDictionary(word);
|
||||
int len_phonetic = strlen(encoded_ph);
|
||||
len_phonetic = strlen(encoded_ph);
|
||||
|
||||
dict_line[1] = len_word; // bit 6 indicates whether the word has been compressed
|
||||
len_word &= 0x3f;
|
||||
@@ -643,10 +652,11 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
static void compile_dictlist_start(void)
|
||||
{
|
||||
// initialise dictionary list
|
||||
int ix;
|
||||
char *p;
|
||||
char *p2;
|
||||
|
||||
for (int ix = 0; ix < N_HASH_DICT; ix++) {
|
||||
for (ix = 0; ix < N_HASH_DICT; ix++) {
|
||||
p = hash_chains[ix];
|
||||
while (p != NULL) {
|
||||
memcpy(&p2, p, sizeof(char *));
|
||||
@@ -661,10 +671,11 @@ static void compile_dictlist_start(void)
|
||||
static void compile_dictlist_end(FILE *f_out)
|
||||
{
|
||||
// Write out the compiled dictionary list
|
||||
int hash;
|
||||
int length;
|
||||
char *p;
|
||||
|
||||
for (int hash = 0; hash < N_HASH_DICT; hash++) {
|
||||
for (hash = 0; hash < N_HASH_DICT; hash++) {
|
||||
p = hash_chains[hash];
|
||||
hash_counts[hash] = (int)ftell(f_out);
|
||||
|
||||
@@ -684,6 +695,7 @@ static int compile_dictlist_file(const char *path, const char *filename)
|
||||
char *p;
|
||||
int count = 0;
|
||||
FILE *f_in;
|
||||
char buf[200];
|
||||
char fname[sizeof(path_home)+45];
|
||||
char dict_line[128];
|
||||
|
||||
@@ -702,7 +714,6 @@ static int compile_dictlist_file(const char *path, const char *filename)
|
||||
|
||||
linenum = 0;
|
||||
|
||||
char buf[200];
|
||||
while (fgets(buf, sizeof(buf), f_in) != NULL) {
|
||||
linenum++;
|
||||
|
||||
@@ -764,6 +775,7 @@ 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;
|
||||
@@ -780,8 +792,7 @@ static void copy_rule_string(char *string, int *state_out)
|
||||
rule_phonemes[len++] = ' ';
|
||||
output = &rule_phonemes[len];
|
||||
}
|
||||
|
||||
int sxflags = 0x808000; // to ensure non-zero bytes
|
||||
sxflags = 0x808000; // to ensure non-zero bytes
|
||||
|
||||
for (p = string, ix = 0;;) {
|
||||
literal = 0;
|
||||
@@ -997,12 +1008,18 @@ static char *compile_rule(char *input)
|
||||
{
|
||||
int ix;
|
||||
unsigned char c;
|
||||
int wc;
|
||||
char *p;
|
||||
char *prule;
|
||||
int len;
|
||||
int len_name;
|
||||
int start;
|
||||
int state = 2;
|
||||
int finish = 0;
|
||||
char buf[80];
|
||||
char output[150];
|
||||
int bad_phoneme;
|
||||
char bad_phoneme_str[4];
|
||||
|
||||
buf[0] = 0;
|
||||
rule_cond[0] = 0;
|
||||
@@ -1071,8 +1088,6 @@ static char *compile_rule(char *input)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bad_phoneme;
|
||||
char bad_phoneme_str[4];
|
||||
EncodePhonemes(rule_phonemes, buf, &bad_phoneme);
|
||||
if (bad_phoneme != 0) {
|
||||
bad_phoneme_str[utf8_out(bad_phoneme, bad_phoneme_str)] = 0;
|
||||
@@ -1080,11 +1095,10 @@ static char *compile_rule(char *input)
|
||||
error_count++;
|
||||
}
|
||||
strcpy(output, buf);
|
||||
size_t len = strlen(buf)+1;
|
||||
len = strlen(buf)+1;
|
||||
|
||||
size_t len_name = strlen(group_name);
|
||||
len_name = strlen(group_name);
|
||||
if ((len_name > 0) && (memcmp(rule_match, group_name, len_name) != 0)) {
|
||||
int wc;
|
||||
utf8_in(&wc, rule_match);
|
||||
if ((group_name[0] == '9') && IsDigit(wc)) {
|
||||
// numeric group, rule_match starts with a digit, so OK
|
||||
@@ -1122,7 +1136,7 @@ static char *compile_rule(char *input)
|
||||
}
|
||||
}
|
||||
if (rule_pre[0] != 0) {
|
||||
int start = 0;
|
||||
start = 0;
|
||||
if (rule_pre[0] == RULE_SPACE) {
|
||||
// omit '_' at the beginning of the pre-string and imply it by using RULE_PRE_ATSTART
|
||||
c = RULE_PRE_ATSTART;
|
||||
@@ -1161,8 +1175,8 @@ int __cdecl string_sorter(char **a, char **b)
|
||||
static int __cdecl rgroup_sorter(RGROUP *a, RGROUP *b)
|
||||
{
|
||||
// Sort long names before short names
|
||||
int ix = strlen(b->name) - strlen(a->name);
|
||||
|
||||
int ix;
|
||||
ix = strlen(b->name) - strlen(a->name);
|
||||
if (ix != 0) return ix;
|
||||
ix = strcmp(a->name, b->name);
|
||||
if (ix != 0) return ix;
|
||||
@@ -1171,8 +1185,10 @@ static int __cdecl rgroup_sorter(RGROUP *a, RGROUP *b)
|
||||
|
||||
static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name)
|
||||
{
|
||||
int ix;
|
||||
int len1;
|
||||
int len2;
|
||||
int len_name;
|
||||
char *p;
|
||||
char *p2, *p3;
|
||||
const char *common;
|
||||
@@ -1180,7 +1196,7 @@ static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name
|
||||
short nextchar_count[256];
|
||||
memset(nextchar_count, 0, sizeof(nextchar_count));
|
||||
|
||||
int len_name = strlen(name);
|
||||
len_name = strlen(name);
|
||||
|
||||
// sort the rules in this group by their phoneme string
|
||||
common = "";
|
||||
@@ -1189,7 +1205,7 @@ static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name
|
||||
if (strcmp(name, "9") == 0)
|
||||
len_name = 0; // don't remove characters from numeric match strings
|
||||
|
||||
for (int ix = 0; ix < n_rules; ix++) {
|
||||
for (ix = 0; ix < n_rules; ix++) {
|
||||
p = rules[ix];
|
||||
len1 = strlen(p) + 1; // phoneme string
|
||||
p3 = &p[len1];
|
||||
@@ -1218,6 +1234,9 @@ static int compile_lettergroup(char *input, FILE *f_out)
|
||||
{
|
||||
char *p;
|
||||
char *p_start;
|
||||
int group;
|
||||
int ix;
|
||||
int n_items;
|
||||
int length;
|
||||
int max_length = 0;
|
||||
|
||||
@@ -1232,7 +1251,7 @@ static int compile_lettergroup(char *input, FILE *f_out)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int group = atoi(&p[0]);
|
||||
group = atoi(&p[0]);
|
||||
if (group >= N_LETTER_GROUPS) {
|
||||
fprintf(f_log, "%5d: lettergroup out of range (01-%.2d)\n", linenum, N_LETTER_GROUPS-1);
|
||||
error_count++;
|
||||
@@ -1250,7 +1269,7 @@ static int compile_lettergroup(char *input, FILE *f_out)
|
||||
}
|
||||
letterGroupsDefined[group] = 1;
|
||||
|
||||
int n_items = 0;
|
||||
n_items = 0;
|
||||
while (n_items < N_LETTERGP_ITEMS) {
|
||||
while (isspace2(*p)) p++;
|
||||
if (*p == 0)
|
||||
@@ -1270,7 +1289,7 @@ static int compile_lettergroup(char *input, FILE *f_out)
|
||||
|
||||
// write out the items, longest first
|
||||
while (max_length > 1) {
|
||||
for (int ix = 0; ix < n_items; ix++) {
|
||||
for (ix = 0; ix < n_items; ix++) {
|
||||
if (item_length[ix] == max_length)
|
||||
fwrite(items[ix], 1, max_length, f_out);
|
||||
}
|
||||
@@ -1498,6 +1517,8 @@ int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, cha
|
||||
|
||||
FILE *f_in;
|
||||
FILE *f_out;
|
||||
int offset_rules = 0;
|
||||
int value;
|
||||
char fname_in[sizeof(path_home)+45];
|
||||
char fname_out[sizeof(path_home)+15];
|
||||
char fname_temp[sizeof(path_home)+15];
|
||||
@@ -1537,8 +1558,7 @@ int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, cha
|
||||
}
|
||||
sprintf(fname_temp, "%s%ctemp", path_home, PATHSEP);
|
||||
|
||||
int value = N_HASH_DICT;
|
||||
int offset_rules = 0;
|
||||
value = N_HASH_DICT;
|
||||
Write4Bytes(f_out, value);
|
||||
Write4Bytes(f_out, offset_rules);
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ static const char *basename(const char *filename)
|
||||
static unsigned int StringToWord(const char *string)
|
||||
{
|
||||
// Pack 4 characters into a word
|
||||
int ix;
|
||||
unsigned char c;
|
||||
unsigned int word;
|
||||
|
||||
@@ -51,7 +52,7 @@ static unsigned int StringToWord(const char *string)
|
||||
return 0;
|
||||
|
||||
word = 0;
|
||||
for (int ix = 0; ix < 4; ix++) {
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
if (string[ix] == 0) break;
|
||||
c = string[ix];
|
||||
word |= (c << (ix*8));
|
||||
|
||||
@@ -92,9 +92,10 @@ int Reverse4Bytes(int word)
|
||||
{
|
||||
// reverse the order of bytes from little-endian to big-endian
|
||||
#ifdef ARCH_BIG
|
||||
int ix;
|
||||
int word2 = 0;
|
||||
|
||||
for (int ix = 0; ix <= 24; ix += 8) {
|
||||
for (ix = 0; ix <= 24; ix += 8) {
|
||||
word2 = word2 << 8;
|
||||
word2 |= (word >> ix) & 0xff;
|
||||
}
|
||||
@@ -200,9 +201,12 @@ static void InitGroups(Translator *tr)
|
||||
|
||||
int LoadDictionary(Translator *tr, const char *name, int no_error)
|
||||
{
|
||||
int hash;
|
||||
char *p;
|
||||
int *pw;
|
||||
int length;
|
||||
FILE *f;
|
||||
unsigned int size;
|
||||
char fname[sizeof(path_home)+20];
|
||||
|
||||
strcpy(dictionary_name, name); // currently loaded dictionary name
|
||||
@@ -212,7 +216,7 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
|
||||
// bytes 0-3: offset to rules data
|
||||
// bytes 4-7: number of hash table entries
|
||||
sprintf(fname, "%s%c%s_dict", path_home, PATHSEP, name);
|
||||
unsigned int size = GetFileLength(fname);
|
||||
size = GetFileLength(fname);
|
||||
|
||||
if (tr->data_dictlist != NULL) {
|
||||
Free(tr->data_dictlist);
|
||||
@@ -233,7 +237,7 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
|
||||
fclose(f);
|
||||
|
||||
pw = (int *)(tr->data_dictlist);
|
||||
int length = Reverse4Bytes(pw[1]);
|
||||
length = Reverse4Bytes(pw[1]);
|
||||
|
||||
if (size <= (N_HASH_DICT + sizeof(int)*2)) {
|
||||
fprintf(stderr, "Empty _dict file: '%s\n", fname);
|
||||
@@ -253,7 +257,7 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
|
||||
// set up hash table for data_dictlist
|
||||
p = &(tr->data_dictlist[8]);
|
||||
|
||||
for (int hash = 0; hash < N_HASH_DICT; hash++) {
|
||||
for (hash = 0; hash < N_HASH_DICT; hash++) {
|
||||
tr->dict_hashtab[hash] = p;
|
||||
while ((length = *p) != 0)
|
||||
p += length;
|
||||
@@ -292,6 +296,7 @@ int HashDictionary(const char *string)
|
||||
*/
|
||||
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
|
||||
@@ -328,7 +333,7 @@ const char *EncodePhonemes(const char *p, char *outptr, int *bad_phoneme)
|
||||
max = -1;
|
||||
max_ph = 0;
|
||||
|
||||
for (int ix = 1; ix < n_phoneme_tab; ix++) {
|
||||
for (ix = 1; ix < n_phoneme_tab; ix++) {
|
||||
if (phoneme_tab[ix] == NULL)
|
||||
continue;
|
||||
if (phoneme_tab[ix]->type == phINVALID)
|
||||
@@ -437,6 +442,9 @@ static unsigned int phon_out_size = 0;
|
||||
char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa, int *flags)
|
||||
{
|
||||
int c;
|
||||
int mnem;
|
||||
int len;
|
||||
int first;
|
||||
int ix = 0;
|
||||
char *p;
|
||||
PHONEME_DATA phdata;
|
||||
@@ -476,7 +484,7 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int
|
||||
p++;
|
||||
}
|
||||
|
||||
int len = strlen(p);
|
||||
len = strlen(p);
|
||||
if (len > 0) {
|
||||
strcpy(phon_out, p);
|
||||
phon_out += len;
|
||||
@@ -485,8 +493,8 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int
|
||||
}
|
||||
}
|
||||
|
||||
int first = 1;
|
||||
for (int mnem = ph->mnemonic; (c = mnem & 0xff) != 0; mnem = mnem >> 8) {
|
||||
first = 1;
|
||||
for (mnem = ph->mnemonic; (c = mnem & 0xff) != 0; mnem = mnem >> 8) {
|
||||
if ((c == '/') && (option_phoneme_variants == 0))
|
||||
break; // discard phoneme variant indicator
|
||||
|
||||
@@ -528,6 +536,7 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)
|
||||
|
||||
*/
|
||||
|
||||
int ix;
|
||||
unsigned int len;
|
||||
int phon_out_ix = 0;
|
||||
int stress;
|
||||
@@ -562,7 +571,7 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)
|
||||
use_tie = 0;
|
||||
}
|
||||
|
||||
for (int ix = 1; ix < (n_phoneme_list-2); ix++) {
|
||||
for (ix = 1; ix < (n_phoneme_list-2); ix++) {
|
||||
buf = phon_buf;
|
||||
|
||||
plist = &phoneme_list[ix];
|
||||
@@ -710,12 +719,14 @@ int IsVowel(Translator *tr, int letter)
|
||||
|
||||
static int Unpronouncable2(Translator *tr, char *word)
|
||||
{
|
||||
int c;
|
||||
int end_flags;
|
||||
char ph_buf[N_WORD_PHONEMES];
|
||||
|
||||
ph_buf[0] = 0;
|
||||
int c = word[-1];
|
||||
c = word[-1];
|
||||
word[-1] = ' '; // ensure there is a space before the "word"
|
||||
int end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL);
|
||||
end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL);
|
||||
word[-1] = c;
|
||||
if ((end_flags == 0) || (end_flags & SUFX_UNPRON))
|
||||
return 1;
|
||||
@@ -733,6 +744,8 @@ int Unpronouncable(Translator *tr, char *word, int posn)
|
||||
int c;
|
||||
int c1 = 0;
|
||||
int vowel_posn = 9;
|
||||
int index;
|
||||
int count;
|
||||
ALPHABET *alphabet;
|
||||
|
||||
utf8_in(&c, word);
|
||||
@@ -752,8 +765,8 @@ int Unpronouncable(Translator *tr, char *word, int posn)
|
||||
if (((c = *word) == ' ') || (c == 0) || (c == '\''))
|
||||
return 0;
|
||||
|
||||
int index = 0;
|
||||
int count = 0;
|
||||
index = 0;
|
||||
count = 0;
|
||||
for (;;) {
|
||||
index += utf8_in(&c, &word[index]);
|
||||
if ((c == 0) || (c == ' '))
|
||||
@@ -913,13 +926,14 @@ 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
|
||||
unsigned char phonetic[N_WORD_PHONEMES];
|
||||
signed char vowel_stress[N_WORD_PHONEMES/2];
|
||||
|
||||
strcpy((char *)phonetic, word);
|
||||
int max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 0);
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 0);
|
||||
|
||||
if (new_stress >= 4) {
|
||||
// promote to primary stress
|
||||
@@ -987,6 +1001,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
int mnem;
|
||||
int opt_length;
|
||||
int done;
|
||||
int stressflags;
|
||||
int dflags = 0;
|
||||
int first_primary;
|
||||
int long_vowel;
|
||||
@@ -1005,7 +1020,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
3 secondary stress
|
||||
4 main stress */
|
||||
|
||||
int stressflags = tr->langopts.stress_flags;
|
||||
stressflags = tr->langopts.stress_flags;
|
||||
|
||||
if (dictionary_flags != NULL)
|
||||
dflags = dictionary_flags[0];
|
||||
@@ -2343,12 +2358,14 @@ void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags)
|
||||
{
|
||||
// apply after the translation is complete
|
||||
|
||||
int ix;
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
int len = strlen(phonemes);
|
||||
len = strlen(phonemes);
|
||||
|
||||
if (tr->langopts.param[LOPT_ALT] & 2) {
|
||||
for (int ix = 0; ix < (len-1); ix++) {
|
||||
for (ix = 0; ix < (len-1); ix++) {
|
||||
if (phonemes[ix] == phonSTRESS_P) {
|
||||
p = &phonemes[ix+1];
|
||||
if ((dict_flags & FLAG_ALT2_TRANS) != 0) {
|
||||
@@ -2376,23 +2393,28 @@ int TransposeAlphabet(Translator *tr, char *text)
|
||||
int c;
|
||||
int c2;
|
||||
int ix;
|
||||
int offset;
|
||||
int min;
|
||||
int max;
|
||||
const char *map;
|
||||
char *p = text;
|
||||
char *p2;
|
||||
int all_alpha = 1;
|
||||
int bits;
|
||||
int acc;
|
||||
int pairs_start;
|
||||
const short *pairs_list;
|
||||
int bufix;
|
||||
char buf[N_WORD_BYTES+1];
|
||||
|
||||
int offset = tr->transpose_min - 1;
|
||||
int min = tr->transpose_min;
|
||||
int max = tr->transpose_max;
|
||||
offset = tr->transpose_min - 1;
|
||||
min = tr->transpose_min;
|
||||
max = tr->transpose_max;
|
||||
map = tr->transpose_map;
|
||||
|
||||
int pairs_start = max - min + 2;
|
||||
pairs_start = max - min + 2;
|
||||
|
||||
int bufix = 0;
|
||||
bufix = 0;
|
||||
do {
|
||||
p += utf8_in(&c, p);
|
||||
if (c != 0) {
|
||||
@@ -2468,6 +2490,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
|
||||
{
|
||||
char *p;
|
||||
char *next;
|
||||
int hash;
|
||||
int phoneme_len;
|
||||
int wlen;
|
||||
unsigned char flag;
|
||||
@@ -2482,13 +2505,14 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
|
||||
const char *word_end;
|
||||
const char *word1;
|
||||
int wflags = 0;
|
||||
int lookup_symbol;
|
||||
char word_buf[N_WORD_BYTES+1];
|
||||
char dict_flags_buf[80];
|
||||
|
||||
if (wtab != NULL)
|
||||
wflags = wtab->flags;
|
||||
|
||||
int lookup_symbol = flags[1] & FLAG_LOOKUP_SYMBOL;
|
||||
lookup_symbol = flags[1] & FLAG_LOOKUP_SYMBOL;
|
||||
word1 = word;
|
||||
if (tr->transpose_min > 0) {
|
||||
strncpy0(word_buf, word, N_WORD_BYTES);
|
||||
@@ -2497,7 +2521,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
|
||||
} else
|
||||
wlen = strlen(word);
|
||||
|
||||
int hash = HashDictionary(word);
|
||||
hash = HashDictionary(word);
|
||||
p = tr->dict_hashtab[hash];
|
||||
|
||||
if (p == NULL) {
|
||||
@@ -2740,6 +2764,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
|
||||
*/
|
||||
int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *flags, int end_flags, WORD_TAB *wtab)
|
||||
{
|
||||
int length;
|
||||
const char *found;
|
||||
const char *word1;
|
||||
const char *word2;
|
||||
@@ -2749,7 +2774,7 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f
|
||||
char word[N_WORD_BYTES];
|
||||
static char word_replacement[N_WORD_BYTES];
|
||||
|
||||
int length = 0;
|
||||
length = 0;
|
||||
word2 = word1 = *wordptr;
|
||||
|
||||
while ((word2[nbytes = utf8_nbytes(word2)] == ' ') && (word2[nbytes+1] == '.')) {
|
||||
@@ -2870,6 +2895,7 @@ int Lookup(Translator *tr, const char *word, char *ph_out)
|
||||
|
||||
int flags0;
|
||||
unsigned int flags[2];
|
||||
int say_as;
|
||||
char *word1 = (char *)word;
|
||||
char text[80];
|
||||
|
||||
@@ -2879,7 +2905,7 @@ int Lookup(Translator *tr, const char *word, char *ph_out)
|
||||
flags0 = flags[0];
|
||||
|
||||
if (flags[0] & FLAG_TEXTMODE) {
|
||||
int say_as = option_sayas;
|
||||
say_as = option_sayas;
|
||||
option_sayas = 0; // don't speak replacement word as letter names
|
||||
text[0] = 0;
|
||||
strncpy0(&text[1], word1, sizeof(text));
|
||||
@@ -2913,7 +2939,10 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
that were done when the suffix was added to the original word.
|
||||
*/
|
||||
|
||||
int i;
|
||||
char *word_end;
|
||||
int len_ending;
|
||||
int end_flags;
|
||||
const char *p;
|
||||
int len;
|
||||
char ending[50];
|
||||
@@ -2932,7 +2961,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
if (*word_end == REPLACED_E)
|
||||
*word_end = 'e';
|
||||
}
|
||||
int i = word_end - word;
|
||||
i = word_end - word;
|
||||
|
||||
if (word_copy != NULL) {
|
||||
memcpy(word_copy, word, i);
|
||||
@@ -2940,7 +2969,6 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
}
|
||||
|
||||
// look for multibyte characters to increase the number of bytes to remove
|
||||
int len_ending;
|
||||
for (len_ending = i = (end_type & 0x3f); i > 0; i--) { // num.of characters of the suffix
|
||||
word_end--;
|
||||
while ((*word_end & 0xc0) == 0x80) {
|
||||
@@ -2957,7 +2985,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
ending[i] = 0;
|
||||
word_end--; // now pointing at last character of stem
|
||||
|
||||
int end_flags = (end_type & 0xfff0) | FLAG_SUFX;
|
||||
end_flags = (end_type & 0xfff0) | FLAG_SUFX;
|
||||
|
||||
/* add an 'e' to the stem if appropriate,
|
||||
if stem ends in vowel+consonant
|
||||
|
||||
@@ -49,13 +49,15 @@
|
||||
double ConvertFromIeeeExtended(unsigned char *bytes /* LCN */)
|
||||
{
|
||||
double f;
|
||||
int expon;
|
||||
unsigned long hiMant, loMant;
|
||||
|
||||
int expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
||||
int hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
||||
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[5] & 0xFF));
|
||||
int loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[9] & 0xFF));
|
||||
|
||||
@@ -320,6 +320,7 @@ 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
|
||||
@@ -330,7 +331,7 @@ static void count_pitch_vowels(int start, int end, int clause_end)
|
||||
number_tail = 0; // number between tonic syllable and next primary
|
||||
last_primary = -1;
|
||||
|
||||
for (int ix = start; ix < end; ix++) {
|
||||
for (ix = start; ix < end; ix++) {
|
||||
stress = syllable_tab[ix].stress; // marked stress level
|
||||
|
||||
if (stress >= max_stress) {
|
||||
@@ -387,18 +388,19 @@ 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;
|
||||
|
||||
if (base < 0) base = 0;
|
||||
|
||||
int pitch2 = base;
|
||||
pitch2 = base;
|
||||
|
||||
if (drop < 0) {
|
||||
flags = SYL_RISE;
|
||||
drop = -drop;
|
||||
}
|
||||
|
||||
int pitch1 = pitch2 + drop;
|
||||
pitch1 = pitch2 + drop;
|
||||
if (pitch1 < 0)
|
||||
pitch1 = 0;
|
||||
|
||||
@@ -412,7 +414,8 @@ static void set_pitch(SYLLABLE *syl, int base, int drop)
|
||||
|
||||
static int CountUnstressed(int start, int end, int limit)
|
||||
{
|
||||
int ix;
|
||||
int ix;
|
||||
|
||||
for (ix = start; ix <= end; ix++) {
|
||||
if (syllable_tab[ix].stress >= limit)
|
||||
break;
|
||||
@@ -429,7 +432,10 @@ static int SetHeadIntonation(TUNE *tune, int syl_ix, int end_ix, int control)
|
||||
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;
|
||||
@@ -438,10 +444,10 @@ static int SetHeadIntonation(TUNE *tune, int syl_ix, int end_ix, int control)
|
||||
int head_final = end_ix;
|
||||
int secondary = 2;
|
||||
|
||||
int pitch_range = (tune->head_end - tune->head_start) << 8;
|
||||
int pitch_range_abs = abs(pitch_range);
|
||||
pitch_range = (tune->head_end - tune->head_start) << 8;
|
||||
pitch_range_abs = abs(pitch_range);
|
||||
drops = drops_0; // this should be controled by tune->head_drops
|
||||
int initial = 1;
|
||||
initial = 1;
|
||||
|
||||
stage = 0;
|
||||
if (tune->onset == 255)
|
||||
@@ -545,6 +551,8 @@ static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *t
|
||||
int initial;
|
||||
int overflow = 0;
|
||||
int n_overflow;
|
||||
int pitch_range;
|
||||
int pitch_range_abs;
|
||||
int *drops;
|
||||
signed char *overflow_tab;
|
||||
SYLLABLE *syl;
|
||||
@@ -552,8 +560,8 @@ static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *t
|
||||
static signed char continue_tab[5] = { -26, 32, 20, 8, 0 };
|
||||
|
||||
drops = th->body_drops;
|
||||
int pitch_range = (th->body_end - th->body_start) << 8;
|
||||
int pitch_range_abs = abs(pitch_range);
|
||||
pitch_range = (th->body_end - th->body_start) << 8;
|
||||
pitch_range_abs = abs(pitch_range);
|
||||
|
||||
if (continuing) {
|
||||
initial = 0;
|
||||
@@ -630,12 +638,16 @@ 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;
|
||||
SYLLABLE *syl;
|
||||
|
||||
int increment = (end_pitch - start_pitch) << 8;
|
||||
int n_increments = end_ix - start_ix;
|
||||
increment = (end_pitch - start_pitch) << 8;
|
||||
n_increments = end_ix - start_ix;
|
||||
|
||||
if (n_increments <= 0)
|
||||
return;
|
||||
@@ -643,9 +655,9 @@ static void SetPitchGradient(int start_ix, int end_ix, int start_pitch, int end_
|
||||
if (n_increments > 1)
|
||||
increment = increment / n_increments;
|
||||
|
||||
int pitch = start_pitch << 8;
|
||||
pitch = start_pitch << 8;
|
||||
|
||||
for (int ix = start_ix; ix < end_ix; ix++) {
|
||||
for (ix = start_ix; ix < end_ix; ix++) {
|
||||
syl = &syllable_tab[ix];
|
||||
stress = syl->stress;
|
||||
|
||||
@@ -669,10 +681,12 @@ 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;
|
||||
TUNE *tune;
|
||||
int drop;
|
||||
|
||||
tune = &tunes[tune_number];
|
||||
int ix = start;
|
||||
ix = start;
|
||||
|
||||
// vowels before the first primary stress
|
||||
|
||||
@@ -690,7 +704,6 @@ static int calc_pitches2(int start, int end, int tune_number)
|
||||
|
||||
// tonic syllable
|
||||
|
||||
int drop;
|
||||
if (number_tail == 0) {
|
||||
tone_pitch_env = tune->nucleus0_env;
|
||||
drop = tune->nucleus0_max - tune->nucleus0_min;
|
||||
@@ -715,8 +728,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;
|
||||
TONE_HEAD *th;
|
||||
TONE_NUCLEUS *tn;
|
||||
int drop;
|
||||
int continuing = 0;
|
||||
|
||||
if (control == 0)
|
||||
@@ -727,7 +742,7 @@ static int calc_pitches(int control, int start, int end, int tune_number)
|
||||
|
||||
th = &tone_head_table[tune_number];
|
||||
tn = &tone_nucleus_table[tune_number];
|
||||
int ix = start;
|
||||
ix = start;
|
||||
|
||||
// vowels before the first primary stress
|
||||
|
||||
@@ -748,7 +763,6 @@ static int calc_pitches(int control, int start, int end, int tune_number)
|
||||
if (tn->flags & T_EMPH)
|
||||
syllable_tab[ix].flags |= SYL_EMPHASIS;
|
||||
|
||||
int drop;
|
||||
if (number_tail == 0) {
|
||||
tone_pitch_env = tn->pitch_env0;
|
||||
drop = tn->tonic_max0 - tn->tonic_min0;
|
||||
@@ -775,6 +789,7 @@ 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;
|
||||
|
||||
@@ -793,7 +808,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
|
||||
// count number of stressed syllables
|
||||
p = &phoneme_list[0];
|
||||
for (int ix = 0; ix < n_phoneme_list; ix++, p++) {
|
||||
for (ix = 0; ix < n_phoneme_list; ix++, p++) {
|
||||
if ((p->type == phVOWEL) && (p->stresslevel >= 4)) {
|
||||
if (count_stressed == 0)
|
||||
final_stressed = ix;
|
||||
@@ -822,7 +837,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
prev_tph = prevw_tph = phoneme_tab[phonPAUSE];
|
||||
|
||||
// perform tone sandhi
|
||||
for (int ix = 0; ix < n_phoneme_list; ix++, p++) {
|
||||
for (ix = 0; ix < n_phoneme_list; ix++, p++) {
|
||||
if ((p->type == phPAUSE) && (p->ph->std_length > 50)) {
|
||||
pause = 1; // there is a pause since the previous vowel
|
||||
prevw_tph = phoneme_tab[phonPAUSE]; // forget previous tone
|
||||
@@ -887,7 +902,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
|
||||
// convert tone numbers to pitch
|
||||
p = &phoneme_list[0];
|
||||
for (int ix = 0; ix < n_phoneme_list; ix++, p++) {
|
||||
for (ix = 0; ix < n_phoneme_list; ix++, p++) {
|
||||
if (p->synthflags & SFLAG_SYLLABLE) {
|
||||
tone_ph = p->tone_ph;
|
||||
|
||||
@@ -921,21 +936,24 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
int ix;
|
||||
int x;
|
||||
int st_ix;
|
||||
int n_st;
|
||||
int option;
|
||||
int group_tone;
|
||||
int group_tone_comma;
|
||||
int ph_start = 0;
|
||||
int st_start;
|
||||
int st_clause_end;
|
||||
int count;
|
||||
int n_primary;
|
||||
int count_primary;
|
||||
PHONEME_TAB *ph;
|
||||
int ph_end = n_phoneme_list;
|
||||
|
||||
SYLLABLE syllable_tab2[N_PHONEME_LIST];
|
||||
|
||||
syllable_tab = syllable_tab2; // don't use permanent storage. it's only needed during the call of CalcPitches()
|
||||
int n_st = 0;
|
||||
int n_primary = 0;
|
||||
|
||||
n_st = 0;
|
||||
n_primary = 0;
|
||||
for (ix = 0; ix < (n_phoneme_list-1); ix++) {
|
||||
p = &phoneme_list[ix];
|
||||
if (p->synthflags & SFLAG_SYLLABLE) {
|
||||
@@ -976,8 +994,8 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
else
|
||||
no_tonic = 0;
|
||||
|
||||
int st_start = 0;
|
||||
int count_primary = 0;
|
||||
st_start = 0;
|
||||
count_primary = 0;
|
||||
for (st_ix = 0; st_ix < n_st; st_ix++) {
|
||||
syl = &syllable_tab[st_ix];
|
||||
|
||||
|
||||
+45
-21
@@ -127,7 +127,9 @@ static short natural_samples[100] = {
|
||||
|
||||
static double resonator(resonator_ptr r, double input)
|
||||
{
|
||||
double x = (double)((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
|
||||
double x;
|
||||
|
||||
x = (double)((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
|
||||
r->p2 = (double)r->p1;
|
||||
r->p1 = (double)x;
|
||||
|
||||
@@ -136,7 +138,9 @@ static double resonator(resonator_ptr r, double input)
|
||||
|
||||
static double resonator2(resonator_ptr r, double input)
|
||||
{
|
||||
double x = (double)((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
|
||||
double x;
|
||||
|
||||
x = (double)((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
|
||||
r->p2 = (double)r->p1;
|
||||
r->p1 = (double)x;
|
||||
|
||||
@@ -173,12 +177,15 @@ static double antiresonator2(resonator_ptr r, double input)
|
||||
static void flutter(klatt_frame_ptr frame)
|
||||
{
|
||||
static int time_count;
|
||||
double fla = (double)kt_globals.f0_flutter / 50;
|
||||
double flb = (double)kt_globals.original_f0 / 100;
|
||||
double flc = sin(PI*12.7*time_count); // because we are calling flutter() more frequently, every 2.9mS
|
||||
double fld = sin(PI*7.1*time_count);
|
||||
double fle = sin(PI*4.7*time_count);
|
||||
double delta_f0 = fla * flb * (flc + fld + fle) * 10;
|
||||
double delta_f0;
|
||||
double fla, flb, flc, fld, fle;
|
||||
|
||||
fla = (double)kt_globals.f0_flutter / 50;
|
||||
flb = (double)kt_globals.original_f0 / 100;
|
||||
flc = sin(PI*12.7*time_count); // because we are calling flutter() more frequently, every 2.9mS
|
||||
fld = sin(PI*7.1*time_count);
|
||||
fle = sin(PI*4.7*time_count);
|
||||
delta_f0 = fla * flb * (flc + fld + fle) * 10;
|
||||
frame->F0hz10 = frame->F0hz10 + (long)delta_f0;
|
||||
time_count++;
|
||||
}
|
||||
@@ -192,7 +199,13 @@ static void flutter(klatt_frame_ptr frame)
|
||||
|
||||
static double sampled_source(int source_num)
|
||||
{
|
||||
int itemp;
|
||||
double ftemp;
|
||||
double result;
|
||||
double diff_value;
|
||||
int current_value;
|
||||
int next_value;
|
||||
double temp_diff;
|
||||
short *samples;
|
||||
|
||||
if (source_num == 0) {
|
||||
@@ -204,17 +217,17 @@ static double sampled_source(int source_num)
|
||||
}
|
||||
|
||||
if (kt_globals.T0 != 0) {
|
||||
double ftemp = (double)kt_globals.nper;
|
||||
ftemp = (double)kt_globals.nper;
|
||||
ftemp = ftemp / kt_globals.T0;
|
||||
ftemp = ftemp * kt_globals.num_samples;
|
||||
int itemp = (int)ftemp;
|
||||
itemp = (int)ftemp;
|
||||
|
||||
double temp_diff = ftemp - (double)itemp;
|
||||
temp_diff = ftemp - (double)itemp;
|
||||
|
||||
int current_value = samples[itemp];
|
||||
int next_value = samples[itemp+1];
|
||||
current_value = samples[itemp];
|
||||
next_value = samples[itemp+1];
|
||||
|
||||
double diff_value = (double)next_value - (double)current_value;
|
||||
diff_value = (double)next_value - (double)current_value;
|
||||
diff_value = diff_value * temp_diff;
|
||||
|
||||
result = samples[itemp] + diff_value;
|
||||
@@ -546,12 +559,13 @@ static double impulsive_source()
|
||||
|
||||
static double natural_source()
|
||||
{
|
||||
double lgtemp;
|
||||
static double vwave;
|
||||
|
||||
if (kt_globals.nper < kt_globals.nopen) {
|
||||
kt_globals.pulse_shape_a -= kt_globals.pulse_shape_b;
|
||||
vwave += kt_globals.pulse_shape_a;
|
||||
double lgtemp = vwave * 0.028;
|
||||
lgtemp = vwave * 0.028;
|
||||
|
||||
return lgtemp;
|
||||
}
|
||||
@@ -707,9 +721,12 @@ static void pitch_synch_par_reset(klatt_frame_ptr frame)
|
||||
|
||||
static void setabc(long int f, long int bw, resonator_ptr rp)
|
||||
{
|
||||
double r;
|
||||
double arg;
|
||||
|
||||
// Let r = exp(-pi bw t)
|
||||
double arg = kt_globals.minus_pi_t * bw;
|
||||
double r = exp(arg);
|
||||
arg = kt_globals.minus_pi_t * bw;
|
||||
r = exp(arg);
|
||||
|
||||
// Let c = -r**2
|
||||
rp->c = -(r * r);
|
||||
@@ -731,12 +748,15 @@ static void setabc(long int f, long int bw, resonator_ptr rp)
|
||||
|
||||
static void setzeroabc(long int f, long int bw, resonator_ptr rp)
|
||||
{
|
||||
double r;
|
||||
double arg;
|
||||
|
||||
f = -f;
|
||||
|
||||
// First compute ordinary resonator coefficients
|
||||
// Let r = exp(-pi bw t)
|
||||
double arg = kt_globals.minus_pi_t * bw;
|
||||
double r = exp(arg);
|
||||
arg = kt_globals.minus_pi_t * bw;
|
||||
r = exp(arg);
|
||||
|
||||
// Let c = -r**2
|
||||
rp->c = -(r * r);
|
||||
@@ -771,9 +791,10 @@ static void setzeroabc(long int f, long int bw, resonator_ptr rp)
|
||||
|
||||
static double gen_noise(double noise)
|
||||
{
|
||||
long temp;
|
||||
static double nlast;
|
||||
|
||||
long temp = (long)getrandom(-8191, 8191);
|
||||
temp = (long)getrandom(-8191, 8191);
|
||||
kt_globals.nrand = (long)temp;
|
||||
|
||||
noise = kt_globals.nrand + (0.75 * nlast);
|
||||
@@ -1042,11 +1063,14 @@ int Wavegen_Klatt2(int length, int modulation, int resume, frame_t *fr1, frame_t
|
||||
|
||||
void KlattInit()
|
||||
{
|
||||
|
||||
static short formant_hz[10] = { 280, 688, 1064, 2806, 3260, 3700, 6500, 7000, 8000, 280 };
|
||||
static short bandwidth[10] = { 89, 160, 70, 160, 200, 200, 500, 500, 500, 89 };
|
||||
static short parallel_amp[10] = { 0, 59, 59, 59, 59, 59, 59, 0, 0, 0 };
|
||||
static short parallel_bw[10] = { 59, 59, 89, 149, 200, 200, 500, 0, 0, 0 };
|
||||
|
||||
int ix;
|
||||
|
||||
sample_count = 0;
|
||||
|
||||
kt_globals.synthesis_model = CASCADE_PARALLEL;
|
||||
@@ -1064,7 +1088,7 @@ void KlattInit()
|
||||
KlattReset(2);
|
||||
|
||||
// set default values for frame parameters
|
||||
for (int ix = 0; ix <= 9; ix++) {
|
||||
for (ix = 0; ix <= 9; ix++) {
|
||||
kt_frame.Fhz[ix] = formant_hz[ix];
|
||||
kt_frame.Bhz[ix] = bandwidth[ix];
|
||||
kt_frame.Ap[ix] = parallel_amp[ix];
|
||||
|
||||
+17
-11
@@ -123,7 +123,7 @@ static void close_pipes(int p1[2], int p2[2], int p3[2])
|
||||
|
||||
static int start_mbrola(const char *voice_path)
|
||||
{
|
||||
int p_stdin[2], p_stdout[2], p_stderr[2];
|
||||
int error, p_stdin[2], p_stdout[2], p_stderr[2];
|
||||
ssize_t written;
|
||||
char charbuf[20];
|
||||
|
||||
@@ -132,7 +132,7 @@ static int start_mbrola(const char *voice_path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int error = create_pipes(p_stdin, p_stdout, p_stderr);
|
||||
error = create_pipes(p_stdin, p_stdout, p_stderr);
|
||||
if (error)
|
||||
return -1;
|
||||
|
||||
@@ -146,6 +146,8 @@ static int start_mbrola(const char *voice_path)
|
||||
}
|
||||
|
||||
if (mbr_pid == 0) {
|
||||
int i;
|
||||
|
||||
if (dup2(p_stdin[0], 0) == -1 ||
|
||||
dup2(p_stdout[1], 1) == -1 ||
|
||||
dup2(p_stderr[1], 2) == -1) {
|
||||
@@ -155,7 +157,8 @@ static int start_mbrola(const char *voice_path)
|
||||
(void)written; // suppress 'variable not used' warning
|
||||
_exit(1);
|
||||
}
|
||||
for (int i = p_stderr[1]; i > 2; i--)
|
||||
|
||||
for (i = p_stderr[1]; i > 2; i--)
|
||||
close(i);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
@@ -239,7 +242,7 @@ static void free_pending_data(void)
|
||||
static int mbrola_died(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
int status, len;
|
||||
const char *msg;
|
||||
char msgbuf[80];
|
||||
|
||||
@@ -266,7 +269,7 @@ static int mbrola_died(void)
|
||||
|
||||
log("mbrowrap error: %s", msg);
|
||||
|
||||
size_t len = strlen(mbr_errorbuf);
|
||||
len = strlen(mbr_errorbuf);
|
||||
if (!len)
|
||||
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "%s", msg);
|
||||
else
|
||||
@@ -323,11 +326,12 @@ static int mbrola_has_errors(void)
|
||||
static int send_to_mbrola(const char *cmd)
|
||||
{
|
||||
ssize_t result;
|
||||
int len;
|
||||
|
||||
if (!mbr_pid)
|
||||
return -1;
|
||||
|
||||
int len = strlen(cmd);
|
||||
len = strlen(cmd);
|
||||
result = write(mbr_cmd_fd, cmd, len);
|
||||
|
||||
if (result == -1) {
|
||||
@@ -477,13 +481,14 @@ static ssize_t receive_from_mbrola(void *buffer, size_t bufsize)
|
||||
|
||||
int init_MBR(const char *voice_path)
|
||||
{
|
||||
int error, result;
|
||||
unsigned char wavhdr[45];
|
||||
|
||||
int error = start_mbrola(voice_path);
|
||||
error = start_mbrola(voice_path);
|
||||
if (error)
|
||||
return -1;
|
||||
|
||||
int result = send_to_mbrola("#\n");
|
||||
result = send_to_mbrola("#\n");
|
||||
if (result != 2) {
|
||||
stop_mbrola();
|
||||
return -1;
|
||||
@@ -528,7 +533,7 @@ void close_MBR(void)
|
||||
|
||||
int reset_MBR()
|
||||
{
|
||||
int success = 1;
|
||||
int result, success = 1;
|
||||
char dummybuf[4096];
|
||||
|
||||
if (mbr_state == MBR_IDLE)
|
||||
@@ -538,7 +543,7 @@ int reset_MBR()
|
||||
if (kill(mbr_pid, SIGUSR1) == -1)
|
||||
success = 0;
|
||||
free_pending_data();
|
||||
int result = write(mbr_cmd_fd, "\n#\n", 3);
|
||||
result = write(mbr_cmd_fd, "\n#\n", 3);
|
||||
if (result != 3)
|
||||
success = 0;
|
||||
do {
|
||||
@@ -592,9 +597,10 @@ void setVolumeRatio_MBR(float value)
|
||||
|
||||
int lastErrorStr_MBR(char *buffer, int bufsize)
|
||||
{
|
||||
int result;
|
||||
if (mbr_pid)
|
||||
mbrola_has_errors();
|
||||
int result = snprintf(buffer, bufsize, "%s", mbr_errorbuf);
|
||||
result = snprintf(buffer, bufsize, "%s", mbr_errorbuf);
|
||||
return result >= bufsize ? (bufsize - 1) : result;
|
||||
}
|
||||
|
||||
|
||||
+45
-22
@@ -390,11 +390,12 @@ static const unsigned short letter_accents_250[] = {
|
||||
|
||||
static int LookupLetter2(Translator *tr, unsigned int letter, char *ph_buf)
|
||||
{
|
||||
int len;
|
||||
char single_letter[10];
|
||||
|
||||
single_letter[0] = 0;
|
||||
single_letter[1] = '_';
|
||||
int len = utf8_out(letter, &single_letter[2]);
|
||||
len = utf8_out(letter, &single_letter[2]);
|
||||
single_letter[len+2] = ' ';
|
||||
single_letter[len+3] = 0;
|
||||
|
||||
@@ -477,12 +478,13 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b
|
||||
{
|
||||
// control, bit 0: not the first letter of a word
|
||||
|
||||
int len;
|
||||
static char single_letter[10] = { 0, 0 };
|
||||
unsigned int dict_flags[2];
|
||||
char ph_buf3[40];
|
||||
|
||||
ph_buf1[0] = 0;
|
||||
int len = utf8_out(letter, &single_letter[2]);
|
||||
len = utf8_out(letter, &single_letter[2]);
|
||||
single_letter[len+2] = ' ';
|
||||
|
||||
if (next_byte == -1) {
|
||||
@@ -649,8 +651,10 @@ static const char *hex_letters[] = {
|
||||
int IsSuperscript(int letter)
|
||||
{
|
||||
// is this a subscript or superscript letter ?
|
||||
int ix;
|
||||
int c;
|
||||
for (int ix = 0; (c = derived_letters[ix]) != 0; ix += 2) {
|
||||
|
||||
for (ix = 0; (c = derived_letters[ix]) != 0; ix += 2) {
|
||||
if (c > letter)
|
||||
break;
|
||||
if (c == letter)
|
||||
@@ -667,6 +671,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
// bit 1: say 'capital'
|
||||
// bit 2: say character code for unknown letters
|
||||
|
||||
int n_bytes;
|
||||
int letter;
|
||||
int len;
|
||||
int ix;
|
||||
@@ -675,8 +680,11 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
char *pbuf;
|
||||
const char *modifier;
|
||||
ALPHABET *alphabet;
|
||||
int al_offset;
|
||||
int al_flags;
|
||||
int language;
|
||||
int number;
|
||||
int phontab_1;
|
||||
int speak_letter_number;
|
||||
char capital[30];
|
||||
char ph_buf[80];
|
||||
@@ -688,9 +696,9 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
ph_buf[0] = 0;
|
||||
ph_alphabet[0] = 0;
|
||||
capital[0] = 0;
|
||||
int phontab_1 = translator->phoneme_tab_ix;
|
||||
phontab_1 = translator->phoneme_tab_ix;
|
||||
|
||||
int n_bytes = utf8_in(&letter, word);
|
||||
n_bytes = utf8_in(&letter, word);
|
||||
|
||||
if ((letter & 0xfff00) == 0x0e000)
|
||||
letter &= 0xff; // uncode private usage area
|
||||
@@ -738,8 +746,8 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
LookupLetter(tr, number, 0, ph_buf, control & 1);
|
||||
}
|
||||
|
||||
int al_offset = 0;
|
||||
int al_flags = 0;
|
||||
al_offset = 0;
|
||||
al_flags = 0;
|
||||
if ((alphabet = AlphabetFromChar(letter)) != NULL) {
|
||||
al_offset = alphabet->offset;
|
||||
al_flags = alphabet->flags;
|
||||
@@ -903,6 +911,7 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
|
||||
unsigned int c;
|
||||
int n_stress = 0;
|
||||
int prev = 0;
|
||||
int count;
|
||||
unsigned char buf[N_WORD_PHONEMES];
|
||||
|
||||
for (ix = 0; (c = phonemes[ix]) != 0; ix++) {
|
||||
@@ -912,7 +921,7 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
|
||||
}
|
||||
buf[ix] = 0;
|
||||
|
||||
int count = 0;
|
||||
count = 0;
|
||||
prev = 0;
|
||||
for (ix = 0; (c = buf[ix]) != 0; ix++) {
|
||||
if ((c == phonSTRESS_P) && (n_chars > 1) && (prev != phonSWITCH)) {
|
||||
@@ -1019,7 +1028,10 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
|
||||
int c;
|
||||
char *p;
|
||||
const char *p2;
|
||||
int acc;
|
||||
int prev;
|
||||
int value;
|
||||
int subtract;
|
||||
int repeat = 0;
|
||||
int n_digits = 0;
|
||||
char *word_start;
|
||||
@@ -1031,9 +1043,9 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
|
||||
static const char *roman_numbers = "ixcmvld";
|
||||
static int roman_values[] = { 1, 10, 100, 1000, 5, 50, 500 };
|
||||
|
||||
int acc = 0;
|
||||
int prev = 0;
|
||||
int subtract = 0x7fff;
|
||||
acc = 0;
|
||||
prev = 0;
|
||||
subtract = 0x7fff;
|
||||
ph_out[0] = 0;
|
||||
flags[0] = 0;
|
||||
flags[1] = 0;
|
||||
@@ -1271,7 +1283,11 @@ static int LookupNum2(Translator *tr, int value, int thousandplex, const int con
|
||||
// bit 8 followed by decimal fraction
|
||||
// bit 9: use #f form for both tens and units (lang=ml)
|
||||
|
||||
int found;
|
||||
int ix;
|
||||
int units;
|
||||
int tens;
|
||||
int is_ordinal;
|
||||
int used_and = 0;
|
||||
int found_ordinal = 0;
|
||||
int next_phtype;
|
||||
@@ -1282,10 +1298,10 @@ static int LookupNum2(Translator *tr, int value, int thousandplex, const int con
|
||||
char ph_digits[50];
|
||||
char ph_and[12];
|
||||
|
||||
int units = value % 10;
|
||||
int tens = value / 10;
|
||||
units = value % 10;
|
||||
tens = value / 10;
|
||||
|
||||
int found = 0;
|
||||
found = 0;
|
||||
ph_ordinal[0] = 0;
|
||||
ph_tens[0] = 0;
|
||||
ph_digits[0] = 0;
|
||||
@@ -1294,7 +1310,7 @@ static int LookupNum2(Translator *tr, int value, int thousandplex, const int con
|
||||
if (control & 0x20)
|
||||
ord_type = 'q';
|
||||
|
||||
int is_ordinal = control & 1;
|
||||
is_ordinal = control & 1;
|
||||
|
||||
if ((control & 2) && (n_digit_lookup == 2)) {
|
||||
// pronunciation of the final 2 digits has already been found
|
||||
@@ -1508,8 +1524,15 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
// bit 8 followed by decimal fraction
|
||||
|
||||
int found;
|
||||
int hundreds;
|
||||
int tensunits;
|
||||
int x;
|
||||
int ix;
|
||||
int exact;
|
||||
int ordinal;
|
||||
int tplex;
|
||||
int say_zero_hundred = 0;
|
||||
int say_one_hundred;
|
||||
char string[12]; // for looking up entries in **_list
|
||||
char buf1[100];
|
||||
char buf2[100];
|
||||
@@ -1520,9 +1543,9 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
char ph_hundred_and[12];
|
||||
char ph_thousand_and[12];
|
||||
|
||||
int ordinal = control & 0x22;
|
||||
int hundreds = value / 100;
|
||||
int tensunits = value % 100;
|
||||
ordinal = control & 0x22;
|
||||
hundreds = value / 100;
|
||||
tensunits = value % 100;
|
||||
buf1[0] = 0;
|
||||
|
||||
ph_thousands[0] = 0;
|
||||
@@ -1551,11 +1574,11 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
} else if (hundreds >= 10) {
|
||||
ph_digits[0] = 0;
|
||||
|
||||
int exact = 0;
|
||||
exact = 0;
|
||||
if ((value % 1000) == 0)
|
||||
exact = 1;
|
||||
|
||||
int tplex = thousandplex+1;
|
||||
tplex = thousandplex+1;
|
||||
if (tr->langopts.numbers2 & NUM2_MYRIADS)
|
||||
tplex = 0;
|
||||
|
||||
@@ -1623,7 +1646,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
if (found)
|
||||
ph_100[0] = 0;
|
||||
else {
|
||||
int say_one_hundred = 1;
|
||||
say_one_hundred = 1;
|
||||
if (hundreds == 1) {
|
||||
if ((tr->langopts.numbers & NUM_OMIT_1_HUNDRED) != 0)
|
||||
say_one_hundred = 0;
|
||||
@@ -1681,7 +1704,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
}
|
||||
} else {
|
||||
if (ph_ordinal2[0] != 0) {
|
||||
int ix = strlen(buf1);
|
||||
ix = strlen(buf1);
|
||||
if ((ix > 0) && (buf1[ix-1] == phonPAUSE_SHORT))
|
||||
buf1[ix-1] = 0; // remove pause before addding ordinal suffix
|
||||
strcpy(buf2, ph_ordinal2);
|
||||
|
||||
@@ -43,7 +43,7 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out)
|
||||
{
|
||||
// Copy the phonemes list and perform any substitutions that are required for the
|
||||
// current voice
|
||||
|
||||
int ix;
|
||||
int k;
|
||||
int replace_flags;
|
||||
int n_plist_out = 0;
|
||||
@@ -51,7 +51,7 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out)
|
||||
PHONEME_LIST2 *plist2;
|
||||
PHONEME_TAB *next = NULL;
|
||||
|
||||
for (int ix = 0; (ix < n_ph_list2) && (n_plist_out < N_PHONEME_LIST); ix++) {
|
||||
for (ix = 0; (ix < n_ph_list2) && (n_plist_out < N_PHONEME_LIST); ix++) {
|
||||
plist2 = &ph_list2[ix];
|
||||
|
||||
// don't do any substitution if the language has been temporarily changed
|
||||
@@ -108,13 +108,19 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
PHONEME_TAB *next, *next2;
|
||||
int unstress_count = 0;
|
||||
int word_stress = 0;
|
||||
int current_phoneme_tab;
|
||||
int max_stress;
|
||||
int voicing;
|
||||
int regression;
|
||||
int end_sourceix;
|
||||
int alternative;
|
||||
int delete_count;
|
||||
int word_start;
|
||||
int inserted;
|
||||
int deleted;
|
||||
PHONEME_DATA phdata;
|
||||
|
||||
int n_ph_list3;
|
||||
PHONEME_LIST *plist3;
|
||||
PHONEME_LIST *plist3_inserted = NULL;
|
||||
PHONEME_LIST ph_list3[N_PHONEME_LIST];
|
||||
@@ -125,10 +131,10 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
memset(&worddata, 0, sizeof(worddata));
|
||||
plist2 = ph_list2;
|
||||
phlist = phoneme_list;
|
||||
int end_sourceix = plist2[n_ph_list2-1].sourceix;
|
||||
end_sourceix = plist2[n_ph_list2-1].sourceix;
|
||||
|
||||
// is the last word of the clause unstressed ?
|
||||
int max_stress = 0;
|
||||
max_stress = 0;
|
||||
for (j = n_ph_list2-3; j >= 0; j--) {
|
||||
// start with the last phoneme (before the terminating pauses) and move backwards
|
||||
if ((plist2[j].stresslevel & 0x7f) > max_stress)
|
||||
@@ -151,8 +157,8 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
}
|
||||
|
||||
// look for switch of phoneme tables
|
||||
int delete_count = 0;
|
||||
int current_phoneme_tab = tr->phoneme_tab_ix;
|
||||
delete_count = 0;
|
||||
current_phoneme_tab = tr->phoneme_tab_ix;
|
||||
for (j = 0; j < n_ph_list2; j++) {
|
||||
if (current_phoneme_tab != tr->phoneme_tab_ix)
|
||||
plist2[j].synthflags |= SFLAG_SWITCHED_LANG;
|
||||
@@ -244,7 +250,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
}
|
||||
}
|
||||
|
||||
int n_ph_list3 = SubstitutePhonemes(tr, ph_list3) - 2;
|
||||
n_ph_list3 = SubstitutePhonemes(tr, ph_list3) - 2;
|
||||
|
||||
for (j = 0; (j < n_ph_list3) && (ix < N_PHONEME_LIST-3);) {
|
||||
if (ph_list3[j].sourceix) {
|
||||
@@ -272,7 +278,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
// transfer all the phonemes of the clause into phoneme_list
|
||||
ph = phoneme_tab[phonPAUSE];
|
||||
ph_list3[0].ph = ph;
|
||||
int word_start = 1;
|
||||
word_start = 1;
|
||||
|
||||
for (j = 0; insert_ph || ((j < n_ph_list3) && (ix < N_PHONEME_LIST-3)); j++) {
|
||||
plist3 = &ph_list3[j];
|
||||
|
||||
@@ -321,6 +321,7 @@ int iswalnum(int c)
|
||||
int towlower(int c)
|
||||
{
|
||||
int x;
|
||||
int ix;
|
||||
|
||||
if (c < 0x80)
|
||||
return tolower(c);
|
||||
@@ -330,7 +331,7 @@ int towlower(int c)
|
||||
|
||||
if (x == 0xfd) {
|
||||
// special cases, lookup translation table
|
||||
for (int ix = 0; wchar_tolower[ix] != 0; ix += 2) {
|
||||
for (ix = 0; wchar_tolower[ix] != 0; ix += 2) {
|
||||
if (wchar_tolower[ix] == c)
|
||||
return wchar_tolower[ix+1];
|
||||
}
|
||||
@@ -340,12 +341,13 @@ int towlower(int c)
|
||||
|
||||
int towupper(int c)
|
||||
{
|
||||
int ix;
|
||||
// check whether a previous character code is the upper-case equivalent of this character
|
||||
if (towlower(c-32) == c)
|
||||
return c-32; // yes, use it
|
||||
if (towlower(c-1) == c)
|
||||
return c-1;
|
||||
for (int ix = 0; wchar_toupper[ix] != 0; ix += 2) {
|
||||
for (ix = 0; wchar_toupper[ix] != 0; ix += 2) {
|
||||
if (wchar_toupper[ix] == c)
|
||||
return wchar_toupper[ix+1];
|
||||
}
|
||||
@@ -463,6 +465,7 @@ int iswupper2(int c)
|
||||
int towlower2(unsigned int c)
|
||||
{
|
||||
int x;
|
||||
int ix;
|
||||
|
||||
// check for non-standard upper to lower case conversions
|
||||
if (c == 'I') {
|
||||
@@ -481,7 +484,7 @@ int towlower2(unsigned int c)
|
||||
|
||||
if (x == 0xfd) {
|
||||
// special cases, lookup translation table
|
||||
for (int ix = 0; wchar_tolower[ix] != 0; ix += 2) {
|
||||
for (ix = 0; wchar_tolower[ix] != 0; ix += 2) {
|
||||
if (wchar_tolower[ix] == (int)c)
|
||||
return wchar_tolower[ix+1];
|
||||
}
|
||||
@@ -491,6 +494,7 @@ int towlower2(unsigned int c)
|
||||
|
||||
int towupper2(unsigned int c)
|
||||
{
|
||||
int ix;
|
||||
if (c > MAX_WALPHA)
|
||||
return towupper(c);
|
||||
|
||||
@@ -499,7 +503,7 @@ int towupper2(unsigned int c)
|
||||
return c-32; // yes, use it
|
||||
if (towlower2(c-1) == (int)c)
|
||||
return c-1;
|
||||
for (int ix = 0; wchar_toupper[ix] != 0; ix += 2) {
|
||||
for (ix = 0; wchar_toupper[ix] != 0; ix += 2) {
|
||||
if (wchar_toupper[ix] == (int)c)
|
||||
return wchar_toupper[ix+1];
|
||||
}
|
||||
@@ -539,13 +543,14 @@ int Eof(void)
|
||||
static int GetC_get(void)
|
||||
{
|
||||
unsigned int c;
|
||||
unsigned int c2;
|
||||
|
||||
if (f_input != NULL) {
|
||||
c = fgetc(f_input);
|
||||
if (feof(f_input)) c = ' ';
|
||||
|
||||
if (option_multibyte == espeakCHARS_16BIT) {
|
||||
unsigned int c2 = fgetc(f_input);
|
||||
c2 = fgetc(f_input);
|
||||
if (feof(f_input)) c2 = 0;
|
||||
c = c + (c2 << 8);
|
||||
}
|
||||
@@ -583,10 +588,12 @@ static int GetC(void)
|
||||
// Returns a unicode wide character
|
||||
// Performs UTF8 checking and conversion
|
||||
|
||||
int c;
|
||||
int c1;
|
||||
int c2;
|
||||
int cbuf[4];
|
||||
int ix;
|
||||
int n_bytes;
|
||||
static int ungot2 = 0;
|
||||
static const unsigned char mask[4] = { 0xff, 0x1f, 0x0f, 0x07 };
|
||||
|
||||
@@ -608,7 +615,7 @@ static int GetC(void)
|
||||
|
||||
if ((option_multibyte < 2) && (c1 & 0x80)) {
|
||||
// multi-byte utf8 encoding, convert to unicode
|
||||
int n_bytes = 0;
|
||||
n_bytes = 0;
|
||||
|
||||
if (((c1 & 0xe0) == 0xc0) && ((c1 & 0x1e) != 0))
|
||||
n_bytes = 1;
|
||||
@@ -618,7 +625,7 @@ static int GetC(void)
|
||||
n_bytes = 3;
|
||||
|
||||
if ((ix = n_bytes) > 0) {
|
||||
int c = c1 & mask[ix];
|
||||
c = c1 & mask[ix];
|
||||
while (ix > 0) {
|
||||
if ((c2 = cbuf[ix] = GetC_get()) == 0) {
|
||||
if (option_multibyte == espeakCHARS_AUTO)
|
||||
@@ -662,12 +669,12 @@ static void UngetC(int c)
|
||||
const char *WordToString2(unsigned int word)
|
||||
{
|
||||
// Convert a language mnemonic word into a string
|
||||
|
||||
int ix;
|
||||
static char buf[5];
|
||||
char *p;
|
||||
|
||||
p = buf;
|
||||
for (int ix = 3; ix >= 0; ix--) {
|
||||
for (ix = 3; ix >= 0; ix--) {
|
||||
if ((*p = word >> (ix*8)) != 0)
|
||||
p++;
|
||||
}
|
||||
@@ -697,6 +704,7 @@ static const char *LookupCharName(Translator *tr, int c, int only)
|
||||
// Find the phoneme string (in ascii) to speak the name of character c
|
||||
// Used for punctuation characters and symbols
|
||||
|
||||
int ix;
|
||||
unsigned int flags[2];
|
||||
char single_letter[24];
|
||||
char phonemes[60];
|
||||
@@ -710,7 +718,7 @@ static const char *LookupCharName(Translator *tr, int c, int only)
|
||||
flags[1] = 0;
|
||||
single_letter[0] = 0;
|
||||
single_letter[1] = '_';
|
||||
int ix = utf8_out(c, &single_letter[2]);
|
||||
ix = utf8_out(c, &single_letter[2]);
|
||||
single_letter[2+ix] = 0;
|
||||
|
||||
if (only) {
|
||||
@@ -780,6 +788,7 @@ static int LoadSoundFile(const char *fname, int index)
|
||||
FILE *f;
|
||||
char *p;
|
||||
int *ip;
|
||||
int length;
|
||||
char fname_temp[100];
|
||||
char fname2[sizeof(path_home)+13+40];
|
||||
|
||||
@@ -800,12 +809,13 @@ static int LoadSoundFile(const char *fname, int index)
|
||||
f = NULL;
|
||||
#ifdef PLATFORM_POSIX
|
||||
if ((f = fopen(fname, "rb")) != NULL) {
|
||||
int ix;
|
||||
int fd_temp;
|
||||
int header[3];
|
||||
char command[sizeof(fname2)+sizeof(fname2)+40];
|
||||
|
||||
fseek(f, 20, SEEK_SET);
|
||||
for (int ix = 0; ix < 3; ix++)
|
||||
for (ix = 0; ix < 3; ix++)
|
||||
header[ix] = Read4Bytes(f);
|
||||
|
||||
// if the sound file is not mono, 16 bit signed, at the correct sample rate, then convert it
|
||||
@@ -832,7 +842,7 @@ static int LoadSoundFile(const char *fname, int index)
|
||||
}
|
||||
}
|
||||
|
||||
int length = GetFileLength(fname);
|
||||
length = GetFileLength(fname);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
if ((p = (char *)realloc(soundicon_tab[index].data, length)) == NULL) {
|
||||
fclose(f);
|
||||
@@ -851,7 +861,9 @@ static int LoadSoundFile(const char *fname, int index)
|
||||
static int LookupSoundicon(int c)
|
||||
{
|
||||
// Find the sound icon number for a punctuation chatacter
|
||||
for (int ix = N_SOUNDICON_SLOTS; ix < n_soundicon_tab; ix++) {
|
||||
int ix;
|
||||
|
||||
for (ix = N_SOUNDICON_SLOTS; ix < n_soundicon_tab; ix++) {
|
||||
if (soundicon_tab[ix].name == c) {
|
||||
if (soundicon_tab[ix].length == 0) {
|
||||
if (LoadSoundFile(NULL, ix) != 0)
|
||||
@@ -868,7 +880,7 @@ static int LoadSoundFile2(const char *fname)
|
||||
// Load a sound file into one of the reserved slots in the sound icon table
|
||||
// (if it'snot already loaded)
|
||||
|
||||
int ix;
|
||||
int ix;
|
||||
static int slot = -1;
|
||||
|
||||
for (ix = 0; ix < n_soundicon_tab; ix++) {
|
||||
@@ -900,11 +912,14 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
int soundicon;
|
||||
int attributes;
|
||||
int short_pause;
|
||||
int c2;
|
||||
int len;
|
||||
int bufix1;
|
||||
char buf[200];
|
||||
char buf2[80];
|
||||
char ph_buf[30];
|
||||
|
||||
int c2 = *c2_ptr;
|
||||
c2 = *c2_ptr;
|
||||
buf[0] = 0;
|
||||
|
||||
if ((soundicon = LookupSoundicon(c1)) >= 0) {
|
||||
@@ -964,8 +979,8 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
}
|
||||
}
|
||||
|
||||
int bufix1 = *bufix;
|
||||
int len = strlen(buf);
|
||||
bufix1 = *bufix;
|
||||
len = strlen(buf);
|
||||
strcpy(&output[*bufix], buf);
|
||||
*bufix += len;
|
||||
|
||||
@@ -1057,6 +1072,7 @@ static const char *VoiceFromStack()
|
||||
// Use the voice properties from the SSML stack to choose a voice, and switch
|
||||
// to that voice if it's not the current voice
|
||||
|
||||
int ix;
|
||||
const char *p;
|
||||
SSML_STACK *sp;
|
||||
const char *v_id;
|
||||
@@ -1074,7 +1090,7 @@ static const char *VoiceFromStack()
|
||||
voice_select.variant = ssml_stack[0].voice_variant_number;
|
||||
voice_select.identifier = NULL;
|
||||
|
||||
for (int ix = 0; ix < n_ssml_stack; ix++) {
|
||||
for (ix = 0; ix < n_ssml_stack; ix++) {
|
||||
sp = &ssml_stack[ix];
|
||||
voice_name_specified = 0;
|
||||
|
||||
@@ -1131,6 +1147,7 @@ static void ProcessParamStack(char *outbuf, int *outix)
|
||||
{
|
||||
// Set the speech parameters from the parameter stack
|
||||
int param;
|
||||
int ix;
|
||||
int value;
|
||||
char buf[20];
|
||||
int new_parameters[N_SPEECH_PARAM];
|
||||
@@ -1139,7 +1156,7 @@ static void ProcessParamStack(char *outbuf, int *outix)
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++)
|
||||
new_parameters[param] = -1;
|
||||
|
||||
for (int ix = 0; ix < n_param_stack; ix++) {
|
||||
for (ix = 0; ix < n_param_stack; ix++) {
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++) {
|
||||
if (param_stack[ix].parameter[param] >= 0)
|
||||
new_parameters[param] = param_stack[ix].parameter[param];
|
||||
@@ -1176,6 +1193,7 @@ static void ProcessParamStack(char *outbuf, int *outix)
|
||||
|
||||
static PARAM_STACK *PushParamStack(int tag_type)
|
||||
{
|
||||
int ix;
|
||||
PARAM_STACK *sp;
|
||||
|
||||
sp = ¶m_stack[n_param_stack];
|
||||
@@ -1183,7 +1201,7 @@ static PARAM_STACK *PushParamStack(int tag_type)
|
||||
n_param_stack++;
|
||||
|
||||
sp->type = tag_type;
|
||||
for (int ix = 0; ix < N_SPEECH_PARAM; ix++)
|
||||
for (ix = 0; ix < N_SPEECH_PARAM; ix++)
|
||||
sp->parameter[ix] = -1;
|
||||
return sp;
|
||||
}
|
||||
@@ -1191,12 +1209,13 @@ static PARAM_STACK *PushParamStack(int tag_type)
|
||||
static void PopParamStack(int tag_type, char *outbuf, int *outix)
|
||||
{
|
||||
// unwind the stack up to and including the previous tag of this type
|
||||
int ix;
|
||||
int top = 0;
|
||||
|
||||
if (tag_type >= SSML_CLOSE)
|
||||
tag_type -= SSML_CLOSE;
|
||||
|
||||
for (int ix = 0; ix < n_param_stack; ix++) {
|
||||
for (ix = 0; ix < n_param_stack; ix++) {
|
||||
if (param_stack[ix].type == tag_type)
|
||||
top = ix;
|
||||
}
|
||||
@@ -1238,7 +1257,8 @@ 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;
|
||||
|
||||
@@ -1301,6 +1321,7 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
{
|
||||
int sign = 0;
|
||||
wchar_t *tail;
|
||||
double value;
|
||||
|
||||
while (iswspace(*pw)) pw++;
|
||||
if (*pw == '+') {
|
||||
@@ -1311,7 +1332,7 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
pw++;
|
||||
sign = -1;
|
||||
}
|
||||
double value = (double)wcstod(pw, &tail);
|
||||
value = (double)wcstod(pw, &tail);
|
||||
if (tail == pw) {
|
||||
// failed to find a number, return 100%
|
||||
*value_out = 100;
|
||||
@@ -1326,8 +1347,9 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
}
|
||||
|
||||
if ((tail[0] == 's') && (tail[1] == 't')) {
|
||||
double x;
|
||||
// convert from semitones to a frequency percentage
|
||||
double x = pow((double)2.0, (double)((value*sign)/12)) * 100;
|
||||
x = pow((double)2.0, (double)((value*sign)/12)) * 100;
|
||||
*value_out = (int)x;
|
||||
return 2; // percentage
|
||||
}
|
||||
@@ -1469,6 +1491,7 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type)
|
||||
static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
|
||||
{
|
||||
int value;
|
||||
int sign;
|
||||
|
||||
static const MNEM_TAB mnem_volume[] = {
|
||||
{ "default", 100 },
|
||||
@@ -1519,7 +1542,7 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
|
||||
// mnemonic specifies a value as a percentage of the base pitch/range/rate/volume
|
||||
sp->parameter[param_type] = (param_stack[0].parameter[param_type] * value)/100;
|
||||
} else {
|
||||
int sign = attr_prosody_value(param_type, attr1, &value);
|
||||
sign = attr_prosody_value(param_type, attr1, &value);
|
||||
|
||||
if (sign == 0)
|
||||
sp->parameter[param_type] = value; // absolute value in Hz
|
||||
@@ -1544,13 +1567,14 @@ static int ReplaceKeyName(char *outbuf, int index, int *outix)
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int ix;
|
||||
int letter;
|
||||
char *p;
|
||||
|
||||
p = &outbuf[index];
|
||||
|
||||
if ((letter = LookupMnem(keynames, p)) != 0) {
|
||||
int ix = utf8_out(letter, p);
|
||||
ix = utf8_out(letter, p);
|
||||
*outix = index + ix;
|
||||
return letter;
|
||||
}
|
||||
@@ -2532,6 +2556,8 @@ void InitNamedata(void)
|
||||
|
||||
void InitText2(void)
|
||||
{
|
||||
int param;
|
||||
|
||||
ungot_char = 0;
|
||||
ungot_char2 = 0;
|
||||
|
||||
@@ -2539,7 +2565,7 @@ void InitText2(void)
|
||||
n_param_stack = 1;
|
||||
ssml_stack[0].tag_type = 0;
|
||||
|
||||
for (int param = 0; param < N_SPEECH_PARAM; param++)
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++)
|
||||
speech_parameters[param] = param_stack[0].parameter[param]; // set all speech parameters to defaults
|
||||
|
||||
option_punctuation = speech_parameters[espeakPUNCTUATION];
|
||||
|
||||
@@ -140,7 +140,11 @@ static int speed3 = 118;
|
||||
void SetSpeed(int control)
|
||||
{
|
||||
int x;
|
||||
int s1;
|
||||
int wpm;
|
||||
int wpm2;
|
||||
int wpm_value;
|
||||
double sonic;
|
||||
|
||||
speed.loud_consonants = 0;
|
||||
speed.min_sample_len = 450;
|
||||
@@ -148,11 +152,11 @@ void SetSpeed(int control)
|
||||
speed.lenmod2_factor = 100;
|
||||
speed.min_pause = 5;
|
||||
|
||||
int wpm = embedded_value[EMBED_S];
|
||||
wpm = embedded_value[EMBED_S];
|
||||
if (control == 2)
|
||||
wpm = embedded_value[EMBED_S2];
|
||||
|
||||
int wpm_value = wpm;
|
||||
wpm_value = wpm;
|
||||
|
||||
if (voice->speed_percent > 0)
|
||||
wpm = (wpm * voice->speed_percent)/100;
|
||||
@@ -172,7 +176,7 @@ void SetSpeed(int control)
|
||||
speed3 = (x * voice->speedf3)/256;
|
||||
}
|
||||
if (control & 2) {
|
||||
double sonic = ((double)wpm2)/wpm;
|
||||
sonic = ((double)wpm2)/wpm;
|
||||
DoSonicSpeed((int)(sonic * 1024));
|
||||
speed.pause_factor = 85;
|
||||
speed.clause_pause_factor = 80;
|
||||
@@ -225,7 +229,7 @@ void SetSpeed(int control)
|
||||
speed.lenmod2_factor = 110 - (wpm - 250)/2;
|
||||
}
|
||||
|
||||
int s1 = (x * voice->speedf1)/256;
|
||||
s1 = (x * voice->speedf1)/256;
|
||||
|
||||
if (wpm >= 170)
|
||||
speed.wav_factor = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds
|
||||
@@ -269,13 +273,17 @@ void SetSpeed(int control)
|
||||
void SetSpeed(int control)
|
||||
{
|
||||
// This is the earlier version of SetSpeed() before sonic speed-up was added
|
||||
int x;
|
||||
int s1;
|
||||
int wpm;
|
||||
int wpm2;
|
||||
|
||||
speed.loud_consonants = 0;
|
||||
speed.min_sample_len = 450;
|
||||
speed.lenmod_factor = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change
|
||||
speed.lenmod2_factor = 100;
|
||||
|
||||
int wpm = embedded_value[EMBED_S];
|
||||
wpm = embedded_value[EMBED_S];
|
||||
if (control == 2)
|
||||
wpm = embedded_value[EMBED_S2];
|
||||
|
||||
@@ -287,10 +295,10 @@ void SetSpeed(int control)
|
||||
if (wpm > 360)
|
||||
speed.loud_consonants = (wpm - 360) / 8;
|
||||
|
||||
int wpm2 = wpm;
|
||||
wpm2 = wpm;
|
||||
if (wpm > 359) wpm2 = 359;
|
||||
if (wpm < 80) wpm2 = 80;
|
||||
int x = speed_lookup[wpm2-80];
|
||||
x = speed_lookup[wpm2-80];
|
||||
|
||||
if (wpm >= 380)
|
||||
x = 7;
|
||||
@@ -321,7 +329,7 @@ void SetSpeed(int control)
|
||||
speed.lenmod2_factor = 110 - (wpm - 250)/2;
|
||||
}
|
||||
|
||||
int s1 = (x * voice->speedf1)/256;
|
||||
s1 = (x * voice->speedf1)/256;
|
||||
|
||||
if (wpm >= 170)
|
||||
speed.wav_factor = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds
|
||||
@@ -365,10 +373,11 @@ void SetParameter(int parameter, int value, int relative)
|
||||
// relative 0=absolute 1=relative
|
||||
|
||||
int new_value = value;
|
||||
int default_value;
|
||||
|
||||
if (relative) {
|
||||
if (parameter < 5) {
|
||||
int default_value = param_defaults[parameter];
|
||||
default_value = param_defaults[parameter];
|
||||
new_value = default_value + (default_value * value)/100;
|
||||
}
|
||||
}
|
||||
@@ -430,6 +439,7 @@ static void DoEmbedded2(int *embix)
|
||||
|
||||
void CalcLengths(Translator *tr)
|
||||
{
|
||||
int ix;
|
||||
int ix2;
|
||||
PHONEME_LIST *prev;
|
||||
PHONEME_LIST *next;
|
||||
@@ -458,7 +468,7 @@ void CalcLengths(Translator *tr)
|
||||
unsigned char *pitch_env = NULL;
|
||||
PHONEME_DATA phdata_tone;
|
||||
|
||||
for (int ix = 1; ix < n_phoneme_list; ix++) {
|
||||
for (ix = 1; ix < n_phoneme_list; ix++) {
|
||||
prev = &phoneme_list[ix-1];
|
||||
p = &phoneme_list[ix];
|
||||
stress = p->stresslevel & 0x7;
|
||||
|
||||
@@ -264,6 +264,8 @@ static void init_path(const char *path)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
HKEY RegKey;
|
||||
unsigned long size;
|
||||
unsigned long var_type;
|
||||
char *env;
|
||||
unsigned char buf[sizeof(path_home)-13];
|
||||
|
||||
@@ -280,8 +282,8 @@ static void init_path(const char *path)
|
||||
|
||||
buf[0] = 0;
|
||||
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey);
|
||||
unsigned long size = sizeof(buf);
|
||||
unsigned long var_type = REG_SZ;
|
||||
size = sizeof(buf);
|
||||
var_type = REG_SZ;
|
||||
RegQueryValueExA(RegKey, "path", 0, &var_type, buf, &size);
|
||||
|
||||
sprintf(path_home, "%s\\espeak-data", buf);
|
||||
@@ -308,6 +310,7 @@ static void init_path(const char *path)
|
||||
|
||||
static int initialise(int control)
|
||||
{
|
||||
int param;
|
||||
int result;
|
||||
int srate = 22050; // default sample rate 22050 Hz
|
||||
|
||||
@@ -329,7 +332,7 @@ static int initialise(int control)
|
||||
SynthesizeInit();
|
||||
InitNamedata();
|
||||
|
||||
for (int param = 0; param < N_SPEECH_PARAM; param++)
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++)
|
||||
param_stack[0].parameter[param] = param_defaults[param];
|
||||
|
||||
return 0;
|
||||
@@ -444,6 +447,7 @@ void MarkerEvent(int type, unsigned int char_position, int value, int value2, un
|
||||
{
|
||||
// type: 1=word, 2=sentence, 3=named mark, 4=play audio, 5=end, 7=phoneme
|
||||
espeak_EVENT *ep;
|
||||
double time;
|
||||
|
||||
if ((event_list == NULL) || (event_list_ix >= (n_event_list-2)))
|
||||
return;
|
||||
@@ -455,7 +459,7 @@ void MarkerEvent(int type, unsigned int char_position, int value, int value2, un
|
||||
ep->text_position = char_position & 0xffffff;
|
||||
ep->length = char_position >> 24;
|
||||
|
||||
double time = ((double)(count_samples + mbrola_delay + (out_ptr - out_start)/2)*1000.0)/samplerate;
|
||||
time = ((double)(count_samples + mbrola_delay + (out_ptr - out_start)/2)*1000.0)/samplerate;
|
||||
ep->audio_position = (int)time;
|
||||
ep->sample = (count_samples + mbrola_delay + (out_ptr - out_start)/2);
|
||||
|
||||
@@ -536,8 +540,9 @@ void sync_espeak_Key(const char *key)
|
||||
{
|
||||
// symbolic name, symbolicname_character - is there a system resource of symbolic names per language?
|
||||
int letter;
|
||||
int ix;
|
||||
|
||||
int ix = utf8_in(&letter, key);
|
||||
ix = utf8_in(&letter, key);
|
||||
if (key[ix] == 0) {
|
||||
// a single character
|
||||
sync_espeak_Char(letter);
|
||||
@@ -595,6 +600,8 @@ 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)
|
||||
{
|
||||
int param;
|
||||
|
||||
// It seems that the wctype functions don't work until the locale has been set
|
||||
// to something other than the default "C". Then, not only Latin1 but also the
|
||||
// other characters give the correct results with iswalpha() etc.
|
||||
@@ -634,7 +641,7 @@ ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length
|
||||
|
||||
VoiceReset(0);
|
||||
|
||||
for (int param = 0; param < N_SPEECH_PARAM; param++)
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++)
|
||||
param_stack[0].parameter[param] = saved_parameters[param] = param_defaults[param];
|
||||
|
||||
SetParameter(espeakRATE, 175, 0);
|
||||
|
||||
@@ -65,11 +65,11 @@ float polint(float xa[], float ya[], int n, float x)
|
||||
{
|
||||
// General polinomial interpolation routine, xa[1...n] ya[1...n]
|
||||
int i, m, ns = 1;
|
||||
float den, dift, ho, hp, w;
|
||||
float den, dif, dift, ho, hp, w;
|
||||
float y; // result
|
||||
float c[9], d[9];
|
||||
|
||||
float dif = fabs(x-xa[1]);
|
||||
dif = fabs(x-xa[1]);
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
if ((dift = fabs(x-xa[i])) < dif) {
|
||||
@@ -98,6 +98,7 @@ float polint(float xa[], float ya[], int n, float x)
|
||||
|
||||
static SpectFrame *SpectFrameCreate()
|
||||
{
|
||||
int ix;
|
||||
SpectFrame *frame;
|
||||
|
||||
frame = malloc(sizeof(SpectFrame));
|
||||
@@ -111,7 +112,7 @@ static SpectFrame *SpectFrameCreate()
|
||||
frame->amp_adjust = 100;
|
||||
frame->length_adjust = 0;
|
||||
|
||||
for (int ix = 0; ix < N_PEAKS; ix++) {
|
||||
for (ix = 0; ix < N_PEAKS; ix++) {
|
||||
frame->formants[ix].freq = 0;
|
||||
frame->peaks[ix].pkfreq = default_freq[ix];
|
||||
frame->peaks[ix].pkheight = 0;
|
||||
@@ -199,6 +200,7 @@ double GetFrameRms(SpectFrame *frame, int seq_amplitude)
|
||||
{
|
||||
int h;
|
||||
float total = 0;
|
||||
int maxh;
|
||||
int height;
|
||||
int htab[400];
|
||||
wavegen_peaks_t wpeaks[9];
|
||||
@@ -212,7 +214,7 @@ double GetFrameRms(SpectFrame *frame, int seq_amplitude)
|
||||
wpeaks[h].right = frame->peaks[h].pkright << 16;
|
||||
}
|
||||
|
||||
int maxh = PeaksToHarmspect(wpeaks, 90<<16, htab, 0);
|
||||
maxh = PeaksToHarmspect(wpeaks, 90<<16, htab, 0);
|
||||
for (h = 1; h < maxh; h++)
|
||||
total += ((htab[h] * htab[h]) >> 10);
|
||||
frame->rms = sqrt(total) / 7.25;
|
||||
@@ -243,8 +245,9 @@ SpectSeq *SpectSeqCreate()
|
||||
|
||||
void SpectSeqDestroy(SpectSeq *spect)
|
||||
{
|
||||
int ix;
|
||||
if (spect->frames != NULL) {
|
||||
for (int ix = 0; ix < spect->numframes; ix++) {
|
||||
for (ix = 0; ix < spect->numframes; ix++) {
|
||||
if (spect->frames[ix] != NULL)
|
||||
SpectFrameDestroy(spect->frames[ix]);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,8 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
{
|
||||
// Load a phoneme name translation table from espeak-data/mbrola
|
||||
|
||||
int size;
|
||||
int ix;
|
||||
int *pw;
|
||||
FILE *f_in;
|
||||
char path[sizeof(path_home)+15];
|
||||
@@ -152,7 +154,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
|
||||
// read eSpeak's mbrola phoneme translation data, eg. en1_phtrans
|
||||
sprintf(path, "%s/mbrola_ph/%s", path_home, phtrans);
|
||||
int size = GetFileLength(path);
|
||||
size = GetFileLength(path);
|
||||
if ((f_in = fopen(path, "rb")) == NULL) {
|
||||
close_MBR();
|
||||
return EE_NOT_FOUND;
|
||||
@@ -166,7 +168,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
|
||||
mbrola_control = Read4Bytes(f_in);
|
||||
pw = (int *)mbrola_tab;
|
||||
for (int ix = 4; ix < size; ix += 4)
|
||||
for (ix = 4; ix < size; ix += 4)
|
||||
*pw++ = Read4Bytes(f_in);
|
||||
size = fread(mbrola_tab, 1, size, f_in);
|
||||
fclose(f_in);
|
||||
@@ -262,9 +264,11 @@ static int GetMbrName(PHONEME_LIST *plist, PHONEME_TAB *ph, PHONEME_TAB *ph_prev
|
||||
static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
|
||||
{
|
||||
// final=1: only give the final pitch value.
|
||||
int x;
|
||||
int ix;
|
||||
int pitch_base;
|
||||
int pitch_range;
|
||||
int p2;
|
||||
int p1, p2, p_end;
|
||||
unsigned char *pitch_env;
|
||||
int max = -1;
|
||||
int min = 999;
|
||||
@@ -273,6 +277,7 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
|
||||
int env100 = 80; // apply the pitch change only over this proportion of the mbrola phoneme(s)
|
||||
int y2;
|
||||
int y[4];
|
||||
int env_split;
|
||||
char buf[50];
|
||||
static char output[50];
|
||||
|
||||
@@ -281,12 +286,12 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
|
||||
|
||||
SetPitch2(voice, pitch1, pitch2, &pitch_base, &pitch_range);
|
||||
|
||||
int env_split = (split * 128)/100;
|
||||
env_split = (split * 128)/100;
|
||||
if (env_split < 0)
|
||||
env_split = 0-env_split;
|
||||
|
||||
// find max and min in the pitch envelope
|
||||
for (int x = 0; x < 128; x++) {
|
||||
for (x = 0; x < 128; x++) {
|
||||
if (pitch_env[x] > max) {
|
||||
max = pitch_env[x];
|
||||
y_max = x;
|
||||
@@ -307,8 +312,8 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
|
||||
y[3] = y[2] + (127 - y[2])/2;
|
||||
|
||||
// set initial pitch
|
||||
int p1 = ((pitch_env[0]*pitch_range)>>8) + pitch_base; // Hz << 12
|
||||
int p_end = ((pitch_env[127]*pitch_range)>>8) + pitch_base;
|
||||
p1 = ((pitch_env[0]*pitch_range)>>8) + pitch_base; // Hz << 12
|
||||
p_end = ((pitch_env[127]*pitch_range)>>8) + pitch_base;
|
||||
|
||||
if (split >= 0) {
|
||||
sprintf(buf, " 0 %d", p1/4096);
|
||||
@@ -317,7 +322,7 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
|
||||
|
||||
// don't use intermediate pitch points for linear rise and fall
|
||||
if (env > 1) {
|
||||
for (int ix = 1; ix < 4; ix++) {
|
||||
for (ix = 1; ix < 4; ix++) {
|
||||
p2 = ((pitch_env[y[ix]]*pitch_range)>>8) + pitch_base;
|
||||
|
||||
if (split > 0)
|
||||
@@ -574,20 +579,22 @@ int MbrolaFill(int length, int resume, int amplitude)
|
||||
// Read audio data from Mbrola (length is in millisecs)
|
||||
|
||||
static int n_samples;
|
||||
int req_samples, result;
|
||||
int ix;
|
||||
short value16;
|
||||
int value;
|
||||
|
||||
if (!resume)
|
||||
n_samples = samplerate * length / 1000;
|
||||
|
||||
int req_samples = (out_end - out_ptr)/2;
|
||||
req_samples = (out_end - out_ptr)/2;
|
||||
if (req_samples > n_samples)
|
||||
req_samples = n_samples;
|
||||
int result = read_MBR((short *)out_ptr, req_samples);
|
||||
result = read_MBR((short *)out_ptr, req_samples);
|
||||
if (result <= 0)
|
||||
return 0;
|
||||
|
||||
for (int ix = 0; ix < result; ix++) {
|
||||
for (ix = 0; ix < result; ix++) {
|
||||
value16 = out_ptr[0] + (out_ptr[1] << 8);
|
||||
value = value16 * amplitude;
|
||||
value = value / 40; // adjust this constant to give a suitable amplitude for mbrola voices
|
||||
|
||||
@@ -75,10 +75,11 @@ static char *ReadPhFile(void *ptr, const char *fname, int *size)
|
||||
{
|
||||
FILE *f_in;
|
||||
char *p;
|
||||
unsigned int length;
|
||||
char buf[sizeof(path_home)+40];
|
||||
|
||||
sprintf(buf, "%s%c%s", path_home, PATHSEP, fname);
|
||||
unsigned int length = GetFileLength(buf);
|
||||
length = GetFileLength(buf);
|
||||
|
||||
if ((f_in = fopen(buf, "rb")) == NULL) {
|
||||
fprintf(stderr, "Can't read data file: '%s'\n", buf);
|
||||
@@ -108,8 +109,10 @@ int LoadPhData(int *srate)
|
||||
{
|
||||
int ix;
|
||||
int n_phonemes;
|
||||
int version;
|
||||
int result = 1;
|
||||
int length;
|
||||
int rate;
|
||||
unsigned char *p;
|
||||
int *pw;
|
||||
|
||||
@@ -125,9 +128,8 @@ int LoadPhData(int *srate)
|
||||
n_tunes = length / sizeof(TUNE);
|
||||
|
||||
// read the version number and sample rate from the first 8 bytes of phondata
|
||||
int version = 0; // bytes 0-3, version number
|
||||
int rate = 0; // bytes 4-7, sample rate
|
||||
|
||||
version = 0; // bytes 0-3, version number
|
||||
rate = 0; // bytes 4-7, sample rate
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
version += (wavefile_data[ix] << (ix*8));
|
||||
rate += (wavefile_data[ix+4] << (ix*8));
|
||||
@@ -176,7 +178,9 @@ void FreePhData(void)
|
||||
|
||||
int PhonemeCode(unsigned int mnem)
|
||||
{
|
||||
for (int ix = 0; ix < n_phoneme_tab; ix++) {
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < n_phoneme_tab; ix++) {
|
||||
if (phoneme_tab[ix] == NULL)
|
||||
continue;
|
||||
if (phoneme_tab[ix]->mnemonic == mnem)
|
||||
@@ -187,11 +191,13 @@ int PhonemeCode(unsigned int mnem)
|
||||
|
||||
int LookupPhonemeString(const char *string)
|
||||
{
|
||||
int ix;
|
||||
unsigned char c;
|
||||
unsigned int mnem;
|
||||
|
||||
// Pack up to 4 characters into a word
|
||||
unsigned int mnem = 0;
|
||||
for (int ix = 0; ix < 4; ix++) {
|
||||
mnem = 0;
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
if (string[ix] == 0) break;
|
||||
c = string[ix];
|
||||
mnem |= (c << (ix*8));
|
||||
@@ -203,7 +209,9 @@ 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;
|
||||
frameref_t *frames;
|
||||
int length1;
|
||||
int length_std;
|
||||
@@ -215,13 +223,13 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
|
||||
seq = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt_addr]);
|
||||
seqk = (SPECT_SEQK *)seq;
|
||||
int nf = seq->n_frames;
|
||||
nf = seq->n_frames;
|
||||
|
||||
if (nf >= N_SEQ_FRAMES)
|
||||
nf = N_SEQ_FRAMES - 1;
|
||||
|
||||
seq_len_adjust = fmt_params->fmt2_lenadj + fmt_params->fmt_length;
|
||||
int seq_break = 0;
|
||||
seq_break = 0;
|
||||
|
||||
for (ix = 0; ix < nf; ix++) {
|
||||
if (seq->frame[0].frflags & FRFLAG_KLATT)
|
||||
@@ -333,6 +341,7 @@ unsigned char *GetEnvelope(int index)
|
||||
|
||||
static void SetUpPhonemeTable(int number, int recursing)
|
||||
{
|
||||
int ix;
|
||||
int includes;
|
||||
int ph_code;
|
||||
PHONEME_TAB *phtab;
|
||||
@@ -347,7 +356,7 @@ static void SetUpPhonemeTable(int number, int recursing)
|
||||
|
||||
// now add the phonemes from this table
|
||||
phtab = phoneme_tab_list[number].phoneme_tab_ptr;
|
||||
for (int ix = 0; ix < phoneme_tab_list[number].n_phonemes; ix++) {
|
||||
for (ix = 0; ix < phoneme_tab_list[number].n_phonemes; ix++) {
|
||||
ph_code = phtab[ix].code;
|
||||
phoneme_tab[ph_code] = &phtab[ix];
|
||||
if (ph_code > n_phoneme_tab)
|
||||
@@ -455,6 +464,7 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition,
|
||||
// condition:
|
||||
// 0 if diminished, 1 if unstressed, 2 if not stressed, 3 if stressed, 4 if max stress
|
||||
|
||||
int stress_level;
|
||||
PHONEME_LIST *pl;
|
||||
static int condition_level[4] = { 1, 2, 4, 15 };
|
||||
|
||||
@@ -468,7 +478,7 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition,
|
||||
return false; // no stress elevel for this consonant
|
||||
}
|
||||
|
||||
int stress_level = pl->stresslevel & 0xf;
|
||||
stress_level = pl->stresslevel & 0xf;
|
||||
|
||||
if (tr != NULL) {
|
||||
if ((control & 1) && (plist->synthflags & SFLAG_DICTIONARY) && ((tr->langopts.param[LOPT_REDUCE] & 1) == 0)) {
|
||||
@@ -515,6 +525,9 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
{
|
||||
int which;
|
||||
int ix;
|
||||
unsigned int data;
|
||||
int instn;
|
||||
int instn2;
|
||||
int count;
|
||||
int check_endtype = 0;
|
||||
PHONEME_TAB *ph;
|
||||
@@ -528,9 +541,9 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
|
||||
// bits 8-10 = 7, other conditions
|
||||
|
||||
int instn = (*p_prog) & 0xfff;
|
||||
unsigned int data = instn & 0xff;
|
||||
int instn2 = instn >> 8;
|
||||
instn = (*p_prog) & 0xfff;
|
||||
data = instn & 0xff;
|
||||
instn2 = instn >> 8;
|
||||
|
||||
if (instn2 < 14) {
|
||||
plist_this = plist;
|
||||
@@ -736,6 +749,7 @@ static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT
|
||||
{
|
||||
USHORT *prog;
|
||||
int voweltype;
|
||||
signed char x;
|
||||
|
||||
if (instn_type == 2) {
|
||||
phdata->pd_control |= pd_FORNEXTPH;
|
||||
@@ -747,7 +761,7 @@ static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT
|
||||
if ((voweltype >= 0) && (voweltype < 6)) {
|
||||
prog = *p_prog + voweltype*2;
|
||||
phdata->sound_addr[instn_type] = (((prog[1] & 0xf) << 16) + prog[2]) * 4;
|
||||
signed char x = (prog[1] >> 4) & 0xff;
|
||||
x = (prog[1] >> 4) & 0xff;
|
||||
phdata->sound_param[instn_type] = x; // sign extend
|
||||
}
|
||||
|
||||
@@ -756,13 +770,15 @@ static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT
|
||||
|
||||
int NumInstnWords(USHORT *prog)
|
||||
{
|
||||
int instn;
|
||||
int instn2;
|
||||
int instn_type;
|
||||
int n;
|
||||
int type2;
|
||||
static const char n_words[16] = { 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 4, 0, 0, 0, 0, 0 };
|
||||
|
||||
int instn2;
|
||||
int type2;
|
||||
int instn = *prog;
|
||||
int instn_type = instn >> 12;
|
||||
instn = *prog;
|
||||
instn_type = instn >> 12;
|
||||
if ((n = n_words[instn_type]) > 0)
|
||||
return n;
|
||||
|
||||
@@ -812,6 +828,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
bool truth;
|
||||
bool truth2;
|
||||
int data;
|
||||
int end_flag;
|
||||
int ix;
|
||||
signed char param_sc;
|
||||
|
||||
@@ -833,7 +850,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
if (ph->program == 0)
|
||||
return;
|
||||
|
||||
int end_flag = 0;
|
||||
end_flag = 0;
|
||||
|
||||
for (prog = &phoneme_index[ph->program]; end_flag != 1; prog++) {
|
||||
instn = *prog;
|
||||
@@ -1042,10 +1059,11 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata)
|
||||
{
|
||||
// Examine the program of a single isolated phoneme
|
||||
int ix;
|
||||
PHONEME_LIST plist[4];
|
||||
memset(plist, 0, sizeof(plist));
|
||||
|
||||
for (int ix = 0; ix < 4; ix++) {
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
plist[ix].phcode = phonPAUSE;
|
||||
plist[ix].ph = phoneme_tab[phonPAUSE];
|
||||
}
|
||||
|
||||
@@ -77,9 +77,10 @@ static PHONEME_LIST next_pause;
|
||||
const char *WordToString(unsigned int word)
|
||||
{
|
||||
// Convert a phoneme mnemonic word into a string
|
||||
int ix;
|
||||
static char buf[5];
|
||||
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
for (ix = 0; ix < 4; ix++)
|
||||
buf[ix] = word >> (ix*8);
|
||||
buf[4] = 0;
|
||||
return buf;
|
||||
@@ -189,6 +190,7 @@ static void DoPause(int length, int control)
|
||||
// control = 1, less shortening at fast speeds
|
||||
|
||||
unsigned int len;
|
||||
int srate2;
|
||||
|
||||
if (length == 0)
|
||||
len = 0;
|
||||
@@ -198,7 +200,7 @@ static void DoPause(int length, int control)
|
||||
if (len < 90000)
|
||||
len = (len * samplerate) / 1000; // convert from mS to number of samples
|
||||
else {
|
||||
int srate2 = samplerate / 25; // avoid overflow
|
||||
srate2 = samplerate / 25; // avoid overflow
|
||||
len = (len * srate2) / 40;
|
||||
}
|
||||
}
|
||||
@@ -220,20 +222,25 @@ extern int seq_len_adjust; // temporary fix to advance the start point for playi
|
||||
|
||||
static int DoSample2(int index, int which, int std_length, int control, int length_mod, int amp)
|
||||
{
|
||||
int length;
|
||||
int wav_length;
|
||||
int wav_scale;
|
||||
int min_length;
|
||||
int x;
|
||||
int len4;
|
||||
intptr_t *q;
|
||||
unsigned char *p;
|
||||
|
||||
index = index & 0x7fffff;
|
||||
p = &wavefile_data[index];
|
||||
int wav_scale = p[2];
|
||||
int wav_length = (p[1] * 256);
|
||||
wav_scale = p[2];
|
||||
wav_length = (p[1] * 256);
|
||||
wav_length += p[0]; // length in bytes
|
||||
|
||||
if (wav_length == 0)
|
||||
return 0;
|
||||
|
||||
int min_length = speed.min_sample_len;
|
||||
min_length = speed.min_sample_len;
|
||||
|
||||
if (wav_scale == 0)
|
||||
min_length *= 2; // 16 bit samples
|
||||
@@ -254,7 +261,7 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
|
||||
if (length_mod > 0)
|
||||
std_length = (std_length * length_mod)/256;
|
||||
|
||||
int length = (std_length * speed.wav_factor)/256;
|
||||
length = (std_length * speed.wav_factor)/256;
|
||||
|
||||
if (control & pd_DONTLENGTHEN) {
|
||||
// this option is used for Stops, with short noise bursts.
|
||||
@@ -278,7 +285,7 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
|
||||
if (amp < 0)
|
||||
return length;
|
||||
|
||||
int len4 = wav_length / 4;
|
||||
len4 = wav_length / 4;
|
||||
|
||||
index += 4;
|
||||
|
||||
@@ -389,6 +396,10 @@ static void set_frame_rms(frame_t *fr, int new_rms)
|
||||
// Each frame includes its RMS amplitude value, so to set a new
|
||||
// RMS just adjust the formant amplitudes by the appropriate ratio
|
||||
|
||||
int x;
|
||||
int h;
|
||||
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,
|
||||
@@ -412,13 +423,12 @@ static void set_frame_rms(frame_t *fr, int new_rms)
|
||||
}
|
||||
|
||||
if (fr->rms == 0) return; // check for divide by zero
|
||||
int x = (new_rms * 64)/fr->rms;
|
||||
x = (new_rms * 64)/fr->rms;
|
||||
if (x >= 200) x = 199;
|
||||
|
||||
x = sqrt_tab[x]; // sqrt(new_rms/fr->rms)*0x200;
|
||||
|
||||
int h;
|
||||
for (int ix = 0; ix < 8; ix++) {
|
||||
for (ix = 0; ix < 8; ix++) {
|
||||
h = fr->fheight[ix] * x;
|
||||
fr->fheight[ix] = h/0x200;
|
||||
}
|
||||
@@ -427,12 +437,13 @@ 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;
|
||||
|
||||
if (voice->klattv[0])
|
||||
return;
|
||||
|
||||
int x;
|
||||
for (int ix = 2; ix < 8; ix++) {
|
||||
for (ix = 2; ix < 8; ix++) {
|
||||
x = fr->fheight[ix] * level;
|
||||
fr->fheight[ix] = x/100;
|
||||
}
|
||||
@@ -471,9 +482,11 @@ static frame_t *DuplicateLastFrame(frameref_t *seq, int n_frames, int length)
|
||||
|
||||
static void AdjustFormants(frame_t *fr, int target, int min, int max, int f1_adj, int f3_adj, int hf_reduce, int flags)
|
||||
{
|
||||
int x;
|
||||
|
||||
target = (target * voice->formant_factor)/256;
|
||||
|
||||
int x = (target - fr->ffreq[2]) / 2;
|
||||
x = (target - fr->ffreq[2]) / 2;
|
||||
if (x > max) x = max;
|
||||
if (x < min) x = min;
|
||||
fr->ffreq[2] += x;
|
||||
@@ -523,6 +536,21 @@ static int VowelCloseness(frame_t *fr)
|
||||
|
||||
int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which)
|
||||
{
|
||||
int ix;
|
||||
int formant;
|
||||
int next_rms;
|
||||
|
||||
int len;
|
||||
int rms;
|
||||
int f1;
|
||||
int f2;
|
||||
int f2_min;
|
||||
int f2_max;
|
||||
int f3_adj;
|
||||
int f3_amp;
|
||||
int flags;
|
||||
int vcolour;
|
||||
|
||||
#define N_VCOLOUR 2
|
||||
// percentage change for each formant in 256ths
|
||||
static short vcolouring[N_VCOLOUR][5] = {
|
||||
@@ -535,17 +563,17 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig
|
||||
if (*n_frames < 2)
|
||||
return 0;
|
||||
|
||||
int len = (data1 & 0x3f) * 2;
|
||||
int rms = (data1 >> 6) & 0x3f;
|
||||
int flags = (data1 >> 12);
|
||||
len = (data1 & 0x3f) * 2;
|
||||
rms = (data1 >> 6) & 0x3f;
|
||||
flags = (data1 >> 12);
|
||||
|
||||
int f2 = (data2 & 0x3f) * 50;
|
||||
int f2_min = (((data2 >> 6) & 0x1f) - 15) * 50;
|
||||
int f2_max = (((data2 >> 11) & 0x1f) - 15) * 50;
|
||||
int f3_adj = (((data2 >> 16) & 0x1f) - 15) * 50;
|
||||
int f3_amp = ((data2 >> 21) & 0x1f) * 8;
|
||||
int f1 = ((data2 >> 26) & 0x7);
|
||||
int vcolour = (data2 >> 29);
|
||||
f2 = (data2 & 0x3f) * 50;
|
||||
f2_min = (((data2 >> 6) & 0x1f) - 15) * 50;
|
||||
f2_max = (((data2 >> 11) & 0x1f) - 15) * 50;
|
||||
f3_adj = (((data2 >> 16) & 0x1f) - 15) * 50;
|
||||
f3_amp = ((data2 >> 21) & 0x1f) * 8;
|
||||
f1 = ((data2 >> 26) & 0x7);
|
||||
vcolour = (data2 >> 29);
|
||||
|
||||
if ((other_ph != NULL) && (other_ph->mnemonic == '?'))
|
||||
flags |= 8;
|
||||
@@ -560,7 +588,7 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig
|
||||
seq[0].frflags |= FRFLAG_LEN_MOD2; // reduce length modification
|
||||
fr->frflags |= FRFLAG_LEN_MOD2;
|
||||
|
||||
int next_rms = seq[1].frame->rms;
|
||||
next_rms = seq[1].frame->rms;
|
||||
|
||||
if (voice->klattv[0])
|
||||
fr->klattp[KLATT_AV] = seq[1].frame->klattp[KLATT_AV] - 4;
|
||||
@@ -604,11 +632,11 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig
|
||||
set_frame_rms(fr, rms);
|
||||
|
||||
if ((vcolour > 0) && (vcolour <= N_VCOLOUR)) {
|
||||
for (int ix = 0; ix < *n_frames; ix++) {
|
||||
for (ix = 0; ix < *n_frames; ix++) {
|
||||
fr = CopyFrame(seq[ix].frame, 0);
|
||||
seq[ix].frame = fr;
|
||||
|
||||
for (int formant = 1; formant <= 5; formant++) {
|
||||
for (formant = 1; formant <= 5; formant++) {
|
||||
int x;
|
||||
x = fr->ffreq[formant] * vcolouring[vcolour-1][formant-1];
|
||||
fr->ffreq[formant] = x / 256;
|
||||
@@ -642,6 +670,7 @@ static void SmoothSpect(void)
|
||||
frame_t *frame2;
|
||||
frame_t *frame1;
|
||||
frame_t *frame_centre;
|
||||
int ix;
|
||||
int len;
|
||||
int pk;
|
||||
int modified;
|
||||
@@ -660,7 +689,7 @@ static void SmoothSpect(void)
|
||||
frame_centre = (frame_t *)q[2];
|
||||
|
||||
// backwards
|
||||
int ix = syllable_centre -1;
|
||||
ix = syllable_centre -1;
|
||||
frame = frame2 = frame_centre;
|
||||
for (;;) {
|
||||
if (ix < 0) ix = N_WCMDQ-1;
|
||||
@@ -826,6 +855,9 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L
|
||||
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;
|
||||
@@ -834,10 +866,10 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L
|
||||
if (fmt_params->fmt_addr == 0)
|
||||
return 0;
|
||||
|
||||
int length_mod = plist->length;
|
||||
length_mod = plist->length;
|
||||
if (length_mod == 0) length_mod = 256;
|
||||
|
||||
int length_min = (samplerate/70); // greater than one cycle at low pitch (Hz)
|
||||
length_min = (samplerate/70); // greater than one cycle at low pitch (Hz)
|
||||
if (which == 2) {
|
||||
if ((translator->langopts.param[LOPT_LONG_VOWEL_THRESHOLD] > 0) && ((this_ph->std_length >= translator->langopts.param[LOPT_LONG_VOWEL_THRESHOLD]) || (plist->synthflags & SFLAG_LENGTHEN) || (this_ph->phflags & phLONG)))
|
||||
length_min *= 2; // ensure long vowels are longer
|
||||
@@ -915,7 +947,7 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L
|
||||
syllable_centre = wcmdq_tail;
|
||||
}
|
||||
|
||||
int length_sum = 0;
|
||||
length_sum = 0;
|
||||
for (frameix = 1; frameix < n_frames; frameix++) {
|
||||
length_factor = length_mod;
|
||||
if (frames[frameix-1].frflags & FRFLAG_LEN_MOD) // reduce effect of length mod
|
||||
|
||||
@@ -143,25 +143,32 @@ static void SetLetterVowel(Translator *tr, int c)
|
||||
static void ResetLetterBits(Translator *tr, int groups)
|
||||
{
|
||||
// Clear all the specified groups
|
||||
unsigned int mask = ~groups;
|
||||
unsigned int ix;
|
||||
unsigned int mask;
|
||||
|
||||
for (int ix = 0; ix < sizeof(tr->letter_bits); ix++)
|
||||
mask = ~groups;
|
||||
|
||||
for (ix = 0; ix < sizeof(tr->letter_bits); ix++)
|
||||
tr->letter_bits[ix] &= mask;
|
||||
}
|
||||
|
||||
static void SetLetterBits(Translator *tr, int group, const char *string)
|
||||
{
|
||||
int bits;
|
||||
unsigned char c;
|
||||
|
||||
int bits = (1L << group);
|
||||
bits = (1L << group);
|
||||
while ((c = *string++) != 0)
|
||||
tr->letter_bits[c] |= bits;
|
||||
}
|
||||
|
||||
static void SetLetterBitsRange(Translator *tr, int group, int first, int last)
|
||||
{
|
||||
int bits = (1L << group);
|
||||
for (int ix = first; ix <= last; ix++)
|
||||
int bits;
|
||||
int ix;
|
||||
|
||||
bits = (1L << group);
|
||||
for (ix = first; ix <= last; ix++)
|
||||
tr->letter_bits[ix] |= bits;
|
||||
}
|
||||
|
||||
@@ -187,6 +194,7 @@ const char string_ordinal[] = { 0xc2, 0xba, 0 }; // masculine ordinal character,
|
||||
static Translator *NewTranslator(void)
|
||||
{
|
||||
Translator *tr;
|
||||
int ix;
|
||||
static const unsigned char stress_amps2[] = { 18, 18, 20, 20, 20, 22, 22, 20 };
|
||||
static const short stress_lengths2[8] = { 182, 140, 220, 220, 220, 240, 260, 280 };
|
||||
static const wchar_t empty_wstring[1] = { 0 };
|
||||
@@ -254,7 +262,7 @@ static Translator *NewTranslator(void)
|
||||
tr->punct_within_word = punct_in_word;
|
||||
tr->chars_ignore = chars_ignore_default;
|
||||
|
||||
for (int ix = 0; ix < 8; ix++) {
|
||||
for (ix = 0; ix < 8; ix++) {
|
||||
tr->stress_amps[ix] = stress_amps2[ix];
|
||||
tr->stress_amps_r[ix] = stress_amps2[ix] - 1;
|
||||
tr->stress_lengths[ix] = stress_lengths2[ix];
|
||||
|
||||
@@ -458,8 +458,9 @@ void DeleteTranslator(Translator *tr)
|
||||
int lookupwchar(const unsigned short *list, int c)
|
||||
{
|
||||
// Is the character c in the list ?
|
||||
int ix;
|
||||
|
||||
for (int ix = 0; list[ix] != 0; ix++) {
|
||||
for (ix = 0; list[ix] != 0; ix++) {
|
||||
if (list[ix] == c)
|
||||
return ix+1;
|
||||
}
|
||||
@@ -471,7 +472,9 @@ int lookupwchar2(const unsigned short *list, int c)
|
||||
// Replace character c by another character.
|
||||
// Returns 0 = not found, 1 = delete character
|
||||
|
||||
for (int ix = 0; list[ix] != 0; ix += 2) {
|
||||
int ix;
|
||||
|
||||
for (ix = 0; list[ix] != 0; ix += 2) {
|
||||
if (list[ix] == c)
|
||||
return list[ix+1];
|
||||
}
|
||||
@@ -491,6 +494,8 @@ int utf8_out(unsigned int c, char *buf)
|
||||
// returns the number of bytes written
|
||||
|
||||
int n_bytes;
|
||||
int j;
|
||||
int shift;
|
||||
static char unsigned code[4] = { 0, 0xc0, 0xe0, 0xf0 };
|
||||
|
||||
if (c < 0x80) {
|
||||
@@ -508,9 +513,9 @@ int utf8_out(unsigned int c, char *buf)
|
||||
else
|
||||
n_bytes = 3;
|
||||
|
||||
int shift = 6*n_bytes;
|
||||
shift = 6*n_bytes;
|
||||
buf[0] = code[n_bytes] | (c >> shift);
|
||||
for (int j = 0; j < n_bytes; j++) {
|
||||
for (j = 0; j < n_bytes; j++) {
|
||||
shift -= 6;
|
||||
buf[j+1] = 0x80 + ((c >> shift) & 0x3f);
|
||||
}
|
||||
@@ -538,6 +543,8 @@ int utf8_in2(int *c, const char *buf, int backwards)
|
||||
// backwards: set if we are moving backwards through the UTF8 string
|
||||
|
||||
int c1;
|
||||
int n_bytes;
|
||||
int ix;
|
||||
static const unsigned char mask[4] = { 0xff, 0x1f, 0x0f, 0x07 };
|
||||
|
||||
// find the start of the next/previous character
|
||||
@@ -549,7 +556,7 @@ int utf8_in2(int *c, const char *buf, int backwards)
|
||||
buf++;
|
||||
}
|
||||
|
||||
int n_bytes = 0;
|
||||
n_bytes = 0;
|
||||
|
||||
if ((c1 = *buf++) & 0x80) {
|
||||
if ((c1 & 0xe0) == 0xc0)
|
||||
@@ -560,7 +567,7 @@ int utf8_in2(int *c, const char *buf, int backwards)
|
||||
n_bytes = 3;
|
||||
|
||||
c1 &= mask[n_bytes];
|
||||
for (int ix = 0; ix < n_bytes; ix++)
|
||||
for (ix = 0; ix < n_bytes; ix++)
|
||||
c1 = (c1 << 6) + (*buf++ & 0x3f);
|
||||
}
|
||||
*c = c1;
|
||||
@@ -626,13 +633,14 @@ static int CheckDottedAbbrev(char *word1, WORD_TAB *wtab)
|
||||
int count = 0;
|
||||
int nbytes;
|
||||
int ok;
|
||||
int ix;
|
||||
char *word;
|
||||
char *wbuf;
|
||||
char word_buf[80];
|
||||
|
||||
word = word1;
|
||||
wbuf = word_buf;
|
||||
int ix = 0;
|
||||
ix = 0;
|
||||
|
||||
for (;;) {
|
||||
ok = 0;
|
||||
@@ -691,6 +699,7 @@ int ChangeEquivalentPhonemes(Translator *tr, int lang2, char *phonemes)
|
||||
char *eqlist;
|
||||
char *p_out;
|
||||
char *p_in;
|
||||
int remove_stress = 0;
|
||||
char phonbuf[N_WORD_PHONEMES];
|
||||
|
||||
// has a phoneme equivalence table been specified for this language pair?
|
||||
@@ -709,7 +718,7 @@ int ChangeEquivalentPhonemes(Translator *tr, int lang2, char *phonemes)
|
||||
len = (pb[2] << 8) + pb[3]; // size of this table in words
|
||||
pb += (len * 4);
|
||||
}
|
||||
int remove_stress = pb[1];
|
||||
remove_stress = pb[1];
|
||||
|
||||
if (option_phonemes & espeakPHONEMES_TRACE) {
|
||||
DecodePhonemes(phonemes, phonbuf);
|
||||
@@ -760,6 +769,7 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
// word1 is terminated by space (0x20) character
|
||||
|
||||
char *word1;
|
||||
int word_length;
|
||||
int ix;
|
||||
char *p;
|
||||
int pfix;
|
||||
@@ -779,6 +789,7 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
char end_phonemes2[N_WORD_PHONEMES];
|
||||
char word_copy[N_WORD_BYTES];
|
||||
char word_copy2[N_WORD_BYTES];
|
||||
int word_copy_length;
|
||||
char prefix_chars[0x3f + 2];
|
||||
int found = 0;
|
||||
int end_flags;
|
||||
@@ -792,6 +803,8 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
int spell_word;
|
||||
int stress_bits;
|
||||
int emphasize_allcaps = 0;
|
||||
int wflags;
|
||||
int wmark;
|
||||
int was_unpronouncable = 0;
|
||||
int loopcount;
|
||||
int add_suffix_phonemes = 0;
|
||||
@@ -807,8 +820,8 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
memset(wtab_null, 0, sizeof(wtab_null));
|
||||
wtab = wtab_null;
|
||||
}
|
||||
int wflags = wtab->flags;
|
||||
int wmark = wtab->wmark;
|
||||
wflags = wtab->flags;
|
||||
wmark = wtab->wmark;
|
||||
|
||||
dictionary_flags[0] = 0;
|
||||
dictionary_flags[1] = 0;
|
||||
@@ -833,13 +846,13 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
wordx = word1;
|
||||
|
||||
utf8_in(&first_char, wordx);
|
||||
int word_length = 0;
|
||||
word_length = 0;
|
||||
while ((*wordx != 0) && (*wordx != ' ')) {
|
||||
wordx += utf8_in(&last_char, wordx);
|
||||
word_length++;
|
||||
}
|
||||
|
||||
int word_copy_length = wordx - word_start;
|
||||
word_copy_length = wordx - word_start;
|
||||
if (word_copy_length >= N_WORD_BYTES)
|
||||
word_copy_length = N_WORD_BYTES-1;
|
||||
memcpy(word_copy2, word_start, word_copy_length);
|
||||
@@ -987,9 +1000,13 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt
|
||||
// word's pronunciation is not given in the dictionary list, although
|
||||
// dictionary_flags may have ben set there
|
||||
|
||||
int posn = 0;
|
||||
int non_initial = 0;
|
||||
int length = 999;
|
||||
int posn;
|
||||
int non_initial;
|
||||
int length;
|
||||
|
||||
posn = 0;
|
||||
non_initial = 0;
|
||||
length = 999;
|
||||
wordx = word1;
|
||||
|
||||
while (((length < 3) && (length > 0)) || (word_length > 1 && Unpronouncable(tr, wordx, posn))) {
|
||||
@@ -2149,12 +2166,13 @@ static const char *UCase_ga[] = { "bp", "bhf", "dt", "gc", "hA", "mb", "nd", "ng
|
||||
|
||||
int UpperCaseInWord(Translator *tr, char *word, int c)
|
||||
{
|
||||
int ix;
|
||||
int len;
|
||||
const char *p;
|
||||
|
||||
if (tr->translator_name == L('g', 'a')) {
|
||||
// Irish
|
||||
for (int ix = 0;; ix++) {
|
||||
for (ix = 0;; ix++) {
|
||||
if ((p = UCase_ga[ix]) == NULL)
|
||||
break;
|
||||
|
||||
|
||||
+29
-15
@@ -256,8 +256,9 @@ static void SetToneAdjust(voice_t *voice, int *tone_pts)
|
||||
void ReadTonePoints(char *string, int *tone_pts)
|
||||
{
|
||||
// tone_pts[] is int[12]
|
||||
int ix;
|
||||
|
||||
for (int ix = 0; ix < 12; ix++)
|
||||
for (ix = 0; ix < 12; ix++)
|
||||
tone_pts[ix] = -1;
|
||||
|
||||
sscanf(string, "%d %d %d %d %d %d %d %d %d %d",
|
||||
@@ -283,7 +284,9 @@ static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char *le
|
||||
char *p;
|
||||
espeak_VOICE *voice_data;
|
||||
int priority;
|
||||
int age;
|
||||
int n_variants = 4; // default, number of variants of this voice before using another voice
|
||||
int gender;
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
char fname_buf[sizeof(path_home)+15];
|
||||
@@ -300,7 +303,7 @@ static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char *le
|
||||
|
||||
vname[0] = 0;
|
||||
vgender[0] = 0;
|
||||
int age = 0;
|
||||
age = 0;
|
||||
|
||||
while (fgets_strip(linebuf, sizeof(linebuf), f_in) != NULL) {
|
||||
if (memcmp(linebuf, "name", 4) == 0) {
|
||||
@@ -328,7 +331,7 @@ static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char *le
|
||||
}
|
||||
languages[langix++] = 0;
|
||||
|
||||
int gender = LookupMnem(genders, vgender);
|
||||
gender = LookupMnem(genders, vgender);
|
||||
|
||||
if (n_languages == 0)
|
||||
return NULL; // no language lines in the voice file
|
||||
@@ -361,6 +364,7 @@ void VoiceReset(int tone_only)
|
||||
{
|
||||
// Set voice to the default values
|
||||
|
||||
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 };
|
||||
|
||||
@@ -391,7 +395,7 @@ void VoiceReset(int tone_only)
|
||||
voice->roughness = 2;
|
||||
|
||||
InitBreath();
|
||||
for (int pk = 0; pk < N_PEAKS; pk++) {
|
||||
for (pk = 0; pk < N_PEAKS; pk++) {
|
||||
voice->freq[pk] = 256;
|
||||
voice->height[pk] = default_heights[pk]*2;
|
||||
voice->width[pk] = default_widths[pk]*2;
|
||||
@@ -423,13 +427,14 @@ void VoiceReset(int tone_only)
|
||||
static void VoiceFormant(char *p)
|
||||
{
|
||||
// Set parameters for a formant
|
||||
int ix;
|
||||
int formant;
|
||||
int freq = 100;
|
||||
int height = 100;
|
||||
int width = 100;
|
||||
int freqadd = 0;
|
||||
|
||||
int ix = sscanf(p, "%d %d %d %d %d", &formant, &freq, &height, &width, &freqadd);
|
||||
ix = sscanf(p, "%d %d %d %d %d", &formant, &freq, &height, &width, &freqadd);
|
||||
if (ix < 2)
|
||||
return;
|
||||
|
||||
@@ -447,13 +452,14 @@ static void VoiceFormant(char *p)
|
||||
|
||||
static void PhonemeReplacement(int type, char *p)
|
||||
{
|
||||
int n;
|
||||
int phon;
|
||||
int flags = 0;
|
||||
char phon_string1[12];
|
||||
char phon_string2[12];
|
||||
|
||||
strcpy(phon_string2, "NULL");
|
||||
int n = sscanf(p, "%d %s %s", &flags, phon_string1, phon_string2);
|
||||
n = sscanf(p, "%d %s %s", &flags, phon_string1, phon_string2);
|
||||
if ((n < 2) || (n_replace_phonemes >= N_REPLACE_PHONEMES))
|
||||
return;
|
||||
|
||||
@@ -476,10 +482,11 @@ static int Read8Numbers(char *data_in, int *data)
|
||||
static unsigned int StringToWord2(const char *string)
|
||||
{
|
||||
// Convert a language name string to a word such as L('e','n')
|
||||
int ix;
|
||||
int c;
|
||||
unsigned int value = 0;
|
||||
|
||||
for (int ix = 0; (ix < 4) && ((c = string[ix]) != 0); ix++)
|
||||
for (ix = 0; (ix < 4) && ((c = string[ix]) != 0); ix++)
|
||||
value = (value << 8) | (c & 0xff);
|
||||
return value;
|
||||
}
|
||||
@@ -1175,6 +1182,7 @@ static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int s
|
||||
static int SetVoiceScores(espeak_VOICE *voice_select, espeak_VOICE **voices, int control)
|
||||
{
|
||||
// control: bit0=1 include mbrola voices
|
||||
int ix;
|
||||
int score;
|
||||
int nv; // number of candidates
|
||||
int n_parts = 0;
|
||||
@@ -1187,7 +1195,7 @@ static int SetVoiceScores(espeak_VOICE *voice_select, espeak_VOICE **voices, int
|
||||
if ((voice_select->languages != NULL) && (voice_select->languages[0] != 0)) {
|
||||
n_parts = 1;
|
||||
lang_len = strlen(voice_select->languages);
|
||||
for (int ix = 0; (ix <= lang_len) && ((unsigned)ix < sizeof(language)); ix++) {
|
||||
for (ix = 0; (ix <= lang_len) && ((unsigned)ix < sizeof(language)); ix++) {
|
||||
if ((language[ix] = tolower(voice_select->languages[ix])) == '-')
|
||||
n_parts++;
|
||||
}
|
||||
@@ -1210,7 +1218,7 @@ static int SetVoiceScores(espeak_VOICE *voice_select, espeak_VOICE **voices, int
|
||||
|
||||
// select those voices which match the specified language
|
||||
nv = 0;
|
||||
for (int ix = 0; ix < n_voices_list; ix++) {
|
||||
for (ix = 0; ix < n_voices_list; ix++) {
|
||||
vp = voices_list[ix];
|
||||
|
||||
if (((control & 1) == 0) && (memcmp(vp->identifier, "mb/", 3) == 0))
|
||||
@@ -1234,11 +1242,13 @@ static int SetVoiceScores(espeak_VOICE *voice_select, espeak_VOICE **voices, int
|
||||
|
||||
espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name2)
|
||||
{
|
||||
int ix;
|
||||
int match_fname = -1;
|
||||
int match_fname2 = -1;
|
||||
int match_name = -1;
|
||||
const char *id; // this is the filename within espeak-data/voices
|
||||
char *variant_name;
|
||||
int last_part_len;
|
||||
char last_part[41];
|
||||
char name[40];
|
||||
|
||||
@@ -1255,9 +1265,9 @@ espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name2)
|
||||
}
|
||||
|
||||
sprintf(last_part, "%c%s", PATHSEP, name);
|
||||
int last_part_len = strlen(last_part);
|
||||
last_part_len = strlen(last_part);
|
||||
|
||||
for (int ix = 0; voices[ix] != NULL; ix++) {
|
||||
for (ix = 0; voices[ix] != NULL; ix++) {
|
||||
if (strcmp(name, voices[ix]->name) == 0) {
|
||||
match_name = ix; // found matching voice name
|
||||
break;
|
||||
@@ -1497,6 +1507,7 @@ static void GetVoices(const char *path)
|
||||
espeak_ERROR SetVoiceByName(const char *name)
|
||||
{
|
||||
espeak_VOICE *v;
|
||||
int ix;
|
||||
espeak_VOICE voice_selector;
|
||||
char *variant_name;
|
||||
static char buf[60];
|
||||
@@ -1505,7 +1516,7 @@ espeak_ERROR SetVoiceByName(const char *name)
|
||||
|
||||
variant_name = ExtractVoiceVariantName(buf, 0, 1);
|
||||
|
||||
for (int ix = 0;; ix++) {
|
||||
for (ix = 0;; ix++) {
|
||||
// convert voice name to lower case (ascii)
|
||||
if ((buf[ix] = tolower(buf[ix])) == 0)
|
||||
break;
|
||||
@@ -1562,7 +1573,8 @@ espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector)
|
||||
|
||||
void FreeVoiceList()
|
||||
{
|
||||
for (int ix = 0; ix < n_voices_list; ix++) {
|
||||
int ix;
|
||||
for (ix = 0; ix < n_voices_list; ix++) {
|
||||
if (voices_list[ix] != NULL) {
|
||||
free(voices_list[ix]);
|
||||
voices_list[ix] = NULL;
|
||||
@@ -1577,6 +1589,8 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)
|
||||
{
|
||||
char path_voices[sizeof(path_home)+12];
|
||||
|
||||
int ix;
|
||||
int j;
|
||||
espeak_VOICE *v;
|
||||
static espeak_VOICE **voices = NULL;
|
||||
|
||||
@@ -1599,8 +1613,8 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)
|
||||
SetVoiceScores(voice_spec, voices, 1);
|
||||
} else {
|
||||
// list all: omit variant voices and mbrola voices and test voices
|
||||
int j = 0;
|
||||
for (int ix = 0; (v = voices_list[ix]) != NULL; ix++) {
|
||||
j = 0;
|
||||
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))
|
||||
voices[j++] = v;
|
||||
|
||||
@@ -170,6 +170,7 @@ size_t wave_write(void *theHandler,
|
||||
char *theMono16BitsWaveBuffer,
|
||||
size_t theSize)
|
||||
{
|
||||
size_t num;
|
||||
if (my_callback_is_output_enabled && (0 == my_callback_is_output_enabled()))
|
||||
return 0;
|
||||
|
||||
@@ -188,7 +189,7 @@ size_t wave_write(void *theHandler,
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t 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
|
||||
@@ -228,12 +229,13 @@ size_t wave_write(void *theHandler,
|
||||
//
|
||||
int wave_close(void *theHandler)
|
||||
{
|
||||
int ret;
|
||||
audio_info_t ainfo;
|
||||
int audio_fd = (int)theHandler;
|
||||
if (!audio_fd)
|
||||
audio_fd = sun_audio_fd;
|
||||
// [[[WDW: maybe do a pause/resume ioctl???]]]
|
||||
int ret = ioctl(audio_fd, I_FLUSH, FLUSHRW);
|
||||
ret = ioctl(audio_fd, I_FLUSH, FLUSHRW);
|
||||
ioctl(audio_fd, AUDIO_GETINFO, &ainfo);
|
||||
|
||||
// Calculate the number of samples that won't get
|
||||
|
||||
+72
-34
@@ -280,7 +280,8 @@ void WcmdqStop()
|
||||
|
||||
int WcmdqFree()
|
||||
{
|
||||
int i = wcmdq_head - wcmdq_tail;
|
||||
int i;
|
||||
i = wcmdq_head - wcmdq_tail;
|
||||
if (i <= 0) i += N_WCMDQ;
|
||||
return i;
|
||||
}
|
||||
@@ -365,14 +366,17 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,
|
||||
PaStreamCallbackFlags flags, void *userData)
|
||||
#endif
|
||||
{
|
||||
int ix;
|
||||
int result;
|
||||
unsigned char *p;
|
||||
unsigned char *out_buf;
|
||||
unsigned char *out_end2;
|
||||
int pa_size;
|
||||
|
||||
int pa_size = framesPerBuffer*2;
|
||||
pa_size = framesPerBuffer*2;
|
||||
|
||||
// make a buffer 3x size of the portaudio output
|
||||
int ix = pa_size*3;
|
||||
ix = pa_size*3;
|
||||
if (ix > outbuffer_size) {
|
||||
outbuffer = (unsigned char *)realloc(outbuffer, ix);
|
||||
if (outbuffer == NULL) {
|
||||
@@ -389,7 +393,7 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,
|
||||
|
||||
event_list_ix = 0;
|
||||
|
||||
int result = WavegenFill(1);
|
||||
result = WavegenFill(1);
|
||||
|
||||
// copy from the outbut buffer into the portaudio buffer
|
||||
if (result && (out_ptr > out_end2))
|
||||
@@ -622,6 +626,7 @@ int WavegenInitSound()
|
||||
|
||||
void WavegenInit(int rate, int wavemult_fact)
|
||||
{
|
||||
int ix;
|
||||
double x;
|
||||
|
||||
if (wavemult_fact == 0)
|
||||
@@ -639,7 +644,7 @@ void WavegenInit(int rate, int wavemult_fact)
|
||||
wdata.amplitude = 32;
|
||||
wdata.amplitude_fmt = 100;
|
||||
|
||||
for (int ix = 0; ix < N_EMBEDDED_VALUES; ix++)
|
||||
for (ix = 0; ix < N_EMBEDDED_VALUES; ix++)
|
||||
embedded_value[ix] = embedded_default[ix];
|
||||
|
||||
// set up window to generate a spread of harmonics from a
|
||||
@@ -652,7 +657,7 @@ void WavegenInit(int rate, int wavemult_fact)
|
||||
if (samplerate != 22050) {
|
||||
// wavemult table has preset values for 22050 Hz, we only need to
|
||||
// recalculate them if we have a different sample rate
|
||||
for (int ix = 0; ix < wavemult_max; ix++) {
|
||||
for (ix = 0; ix < wavemult_max; ix++) {
|
||||
x = 127*(1.0 - cos(PI2*ix/wavemult_max));
|
||||
wavemult[ix] = (int)x;
|
||||
}
|
||||
@@ -667,19 +672,24 @@ void WavegenInit(int rate, int wavemult_fact)
|
||||
|
||||
int GetAmplitude(void)
|
||||
{
|
||||
int amp;
|
||||
|
||||
// normal, none, reduced, moderate, strong
|
||||
static const unsigned char amp_emphasis[5] = { 16, 16, 10, 16, 22 };
|
||||
|
||||
int amp = (embedded_value[EMBED_A])*55/100;
|
||||
amp = (embedded_value[EMBED_A])*55/100;
|
||||
general_amplitude = amp * amp_emphasis[embedded_value[EMBED_F]] / 16;
|
||||
return general_amplitude;
|
||||
}
|
||||
|
||||
static void WavegenSetEcho(void)
|
||||
{
|
||||
int delay;
|
||||
int amp;
|
||||
|
||||
voicing = wvoice->voicing;
|
||||
int delay = wvoice->echo_delay;
|
||||
int amp = wvoice->echo_amp;
|
||||
delay = wvoice->echo_delay;
|
||||
amp = wvoice->echo_amp;
|
||||
|
||||
if (delay >= N_ECHO_BUF)
|
||||
delay = N_ECHO_BUF-1;
|
||||
@@ -726,15 +736,17 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
int fp; // centre freq of peak
|
||||
int fhi; // high freq of peak
|
||||
int h; // harmonic number
|
||||
int pk;
|
||||
int pk;
|
||||
int hmax;
|
||||
int hmax_samplerate; // highest harmonic allowed for the samplerate
|
||||
int x;
|
||||
int ix;
|
||||
int ix;
|
||||
int h1;
|
||||
|
||||
// initialise as much of *out as we will need
|
||||
if (wvoice == NULL)
|
||||
return 1;
|
||||
int hmax = (peaks[wvoice->n_harmonic_peaks].freq + peaks[wvoice->n_harmonic_peaks].right)/pitch;
|
||||
hmax = (peaks[wvoice->n_harmonic_peaks].freq + peaks[wvoice->n_harmonic_peaks].right)/pitch;
|
||||
if (hmax >= MAX_HARMONIC)
|
||||
hmax = MAX_HARMONIC-1;
|
||||
|
||||
@@ -763,9 +775,11 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
htab[h++] += pk_shape[(f-fp)/(p->right>>8)] * p->height;
|
||||
}
|
||||
|
||||
int y;
|
||||
int h2;
|
||||
// increase bass
|
||||
int y = peaks[1].height * 10; // addition as a multiple of 1/256s
|
||||
int h2 = (1000<<16)/pitch; // decrease until 1000Hz
|
||||
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;
|
||||
@@ -801,7 +815,7 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
}
|
||||
|
||||
// adjust the amplitude of the first harmonic, affects tonal quality
|
||||
int h1 = htab[1] * option_harmonic1;
|
||||
h1 = htab[1] * option_harmonic1;
|
||||
htab[1] = h1/8;
|
||||
|
||||
// calc intermediate increments of LF harmonics
|
||||
@@ -817,13 +831,14 @@ static void AdvanceParameters()
|
||||
{
|
||||
// Called every 64 samples to increment the formant freq, height, and widths
|
||||
|
||||
int x;
|
||||
int ix;
|
||||
static int Flutter_ix = 0;
|
||||
|
||||
// advance the pitch
|
||||
wdata.pitch_ix += wdata.pitch_inc;
|
||||
if ((ix = wdata.pitch_ix>>8) > 127) ix = 127;
|
||||
int x = wdata.pitch_env[ix] * wdata.pitch_range;
|
||||
x = wdata.pitch_env[ix] * wdata.pitch_range;
|
||||
wdata.pitch = (x>>8) + wdata.pitch_base;
|
||||
|
||||
amp_ix += amp_inc;
|
||||
@@ -868,7 +883,9 @@ static void AdvanceParameters()
|
||||
|
||||
static double resonator(RESONATOR *r, double input)
|
||||
{
|
||||
double x = r->a * input + r->b * r->x1 + r->c * r->x2;
|
||||
double x;
|
||||
|
||||
x = r->a * input + r->b * r->x1 + r->c * r->x2;
|
||||
r->x2 = r->x1;
|
||||
r->x1 = x;
|
||||
|
||||
@@ -881,13 +898,16 @@ static void setresonator(RESONATOR *rp, int freq, int bwidth, int init)
|
||||
// bwidth Bandwidth of resonator in Hz
|
||||
// init Initialize internal data
|
||||
|
||||
double x;
|
||||
double arg;
|
||||
|
||||
if (init) {
|
||||
rp->x1 = 0;
|
||||
rp->x2 = 0;
|
||||
}
|
||||
|
||||
double arg = minus_pi_t * bwidth;
|
||||
double x = exp(arg);
|
||||
arg = minus_pi_t * bwidth;
|
||||
x = exp(arg);
|
||||
|
||||
rp->c = -(x * x);
|
||||
|
||||
@@ -899,19 +919,23 @@ static void setresonator(RESONATOR *rp, int freq, int bwidth, int init)
|
||||
|
||||
void InitBreath(void)
|
||||
{
|
||||
int ix;
|
||||
|
||||
minus_pi_t = -PI / samplerate;
|
||||
two_pi_t = -2.0 * minus_pi_t;
|
||||
|
||||
for (int ix = 0; ix < N_PEAKS; ix++)
|
||||
for (ix = 0; ix < N_PEAKS; ix++)
|
||||
setresonator(&rbreath[ix], 2000, 200, 1);
|
||||
}
|
||||
|
||||
static void SetBreath()
|
||||
{
|
||||
int pk;
|
||||
|
||||
if (wvoice->breath[0] == 0)
|
||||
return;
|
||||
|
||||
for (int pk = 1; pk < N_PEAKS; pk++) {
|
||||
for (pk = 1; pk < N_PEAKS; pk++) {
|
||||
if (wvoice->breath[pk] != 0) {
|
||||
// breath[0] indicates that some breath formants are needed
|
||||
// set the freq from the current ynthesis formant and the width from the voice data
|
||||
@@ -923,12 +947,14 @@ static void SetBreath()
|
||||
static int ApplyBreath(void)
|
||||
{
|
||||
int value = 0;
|
||||
int noise;
|
||||
int ix;
|
||||
int amp;
|
||||
|
||||
// use two random numbers, for alternate formants
|
||||
int noise = (rand() & 0x3fff) - 0x2000;
|
||||
noise = (rand() & 0x3fff) - 0x2000;
|
||||
|
||||
for (int ix = 1; ix < N_PEAKS; ix++) {
|
||||
for (ix = 1; ix < N_PEAKS; ix++) {
|
||||
if ((amp = wvoice->breath[ix]) != 0) {
|
||||
amp *= (peaks[ix].height >> 14);
|
||||
value += (int)resonator(&rbreath[ix], noise) * amp;
|
||||
@@ -1256,6 +1282,7 @@ static int SetWithRange0(int value, int max)
|
||||
|
||||
static void SetPitchFormants()
|
||||
{
|
||||
int ix;
|
||||
int factor = 256;
|
||||
int pitch_value;
|
||||
|
||||
@@ -1268,7 +1295,7 @@ static void SetPitchFormants()
|
||||
factor = 256 + (25 * (pitch_value - 50))/50;
|
||||
}
|
||||
|
||||
for (int ix = 0; ix <= 5; ix++)
|
||||
for (ix = 0; ix <= 5; ix++)
|
||||
wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256;
|
||||
|
||||
factor = embedded_value[EMBED_T]*3;
|
||||
@@ -1280,8 +1307,9 @@ void SetEmbedded(int control, int value)
|
||||
{
|
||||
// there was an embedded command in the text at this point
|
||||
int sign = 0;
|
||||
int command;
|
||||
|
||||
int command = control & 0x1f;
|
||||
command = control & 0x1f;
|
||||
if ((control & 0x60) == 0x60)
|
||||
sign = -1;
|
||||
else if ((control & 0x60) == 0x40)
|
||||
@@ -1352,10 +1380,13 @@ static void SetAmplitude(int length, unsigned char *amp_env, int value)
|
||||
|
||||
void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range)
|
||||
{
|
||||
int x;
|
||||
int base;
|
||||
int range;
|
||||
int pitch_value;
|
||||
|
||||
if (pitch1 > pitch2) {
|
||||
int x = pitch1; // swap values
|
||||
x = pitch1; // swap values
|
||||
pitch1 = pitch2;
|
||||
pitch2 = x;
|
||||
}
|
||||
@@ -1366,8 +1397,8 @@ void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pit
|
||||
if (pitch_value < 0)
|
||||
pitch_value = 0;
|
||||
|
||||
int base = (voice->pitch_base * pitch_adjust_tab[pitch_value])/128;
|
||||
int range = (voice->pitch_range * embedded_value[EMBED_R])/50;
|
||||
base = (voice->pitch_base * pitch_adjust_tab[pitch_value])/128;
|
||||
range = (voice->pitch_range * embedded_value[EMBED_R])/50;
|
||||
|
||||
// compensate for change in pitch when the range is narrowed or widened
|
||||
base -= (range - voice->pitch_range)*18;
|
||||
@@ -1400,6 +1431,10 @@ void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
|
||||
{
|
||||
int ix;
|
||||
DOUBLEX next;
|
||||
int length2;
|
||||
int length4;
|
||||
int qix;
|
||||
int cmd;
|
||||
static int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256
|
||||
static int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256
|
||||
|
||||
@@ -1419,11 +1454,11 @@ void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
|
||||
glottal_reduce = glottal_reduce_tab2[(modn >> 8) & 3];
|
||||
}
|
||||
|
||||
for (int qix = wcmdq_head+1;; qix++) {
|
||||
for (qix = wcmdq_head+1;; qix++) {
|
||||
if (qix >= N_WCMDQ) qix = 0;
|
||||
if (qix == wcmdq_tail) break;
|
||||
|
||||
int cmd = wcmdq[qix][0];
|
||||
cmd = wcmdq[qix][0];
|
||||
if (cmd == WCMD_SPECT) {
|
||||
end_wave = 0; // next wave generation is from another spectrum
|
||||
break;
|
||||
@@ -1433,7 +1468,7 @@ void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
|
||||
}
|
||||
|
||||
// round the length to a multiple of the stepsize
|
||||
int length2 = (length + STEPSIZE/2) & ~0x3f;
|
||||
length2 = (length + STEPSIZE/2) & ~0x3f;
|
||||
if (length2 == 0)
|
||||
length2 = STEPSIZE;
|
||||
|
||||
@@ -1441,7 +1476,7 @@ void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
|
||||
samplecount_start = samplecount;
|
||||
nsamples += length2;
|
||||
|
||||
int length4 = length2/4;
|
||||
length4 = length2/4;
|
||||
|
||||
peaks[7].freq = (7800 * v->freq[7] + v->freqadd[7]*256) << 8;
|
||||
peaks[8].freq = (9000 * v->freq[8] + v->freqadd[8]*256) << 8;
|
||||
@@ -1487,7 +1522,9 @@ static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_
|
||||
void Write4Bytes(FILE *f, int value)
|
||||
{
|
||||
// Write 4 bytes to a file, least significant first
|
||||
for (int ix = 0; ix < 4; ix++) {
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
fputc(value & 0xff, f);
|
||||
value = value >> 8;
|
||||
}
|
||||
@@ -1642,12 +1679,13 @@ static int SpeedUp(short *outbuf, int length_in, int length_out, int end_of_text
|
||||
// Call WavegenFill2, and then speed up the output samples.
|
||||
int WavegenFill(int fill_zeros)
|
||||
{
|
||||
int finished;
|
||||
unsigned char *p_start;
|
||||
|
||||
p_start = out_ptr;
|
||||
|
||||
// fill_zeros is ignored. It is now done in the portaudio callback
|
||||
int finished = WavegenFill2(0);
|
||||
finished = WavegenFill2(0);
|
||||
|
||||
#if HAVE_SONIC_H
|
||||
if (sonicSpeed > 1.0) {
|
||||
|
||||
+17
-9
@@ -127,6 +127,7 @@ USHORT voice_pcnt[N_PEAKS+1][3];
|
||||
|
||||
void DisplayVoices(FILE *f_out, char *language)
|
||||
{
|
||||
int ix;
|
||||
const char *p;
|
||||
int len;
|
||||
int count;
|
||||
@@ -153,7 +154,7 @@ void DisplayVoices(FILE *f_out, char *language)
|
||||
|
||||
fprintf(f_out, "Pty Language Age/Gender VoiceName File Other Languages\n");
|
||||
|
||||
for (int ix = 0; (v = voices[ix]) != NULL; ix++) {
|
||||
for (ix = 0; (v = voices[ix]) != NULL; ix++) {
|
||||
count = 0;
|
||||
p = v->languages;
|
||||
while (*p != 0) {
|
||||
@@ -223,11 +224,13 @@ static int OpenWaveFile(const char *path, int rate)
|
||||
|
||||
static void CloseWaveFile()
|
||||
{
|
||||
unsigned int pos;
|
||||
|
||||
if ((f_wave == NULL) || (f_wave == stdout))
|
||||
return;
|
||||
|
||||
fflush(f_wave);
|
||||
unsigned int pos = ftell(f_wave);
|
||||
pos = ftell(f_wave);
|
||||
|
||||
fseek(f_wave, 4, SEEK_SET);
|
||||
Write4Bytes(f_wave, pos - 8);
|
||||
@@ -235,19 +238,21 @@ static void CloseWaveFile()
|
||||
fseek(f_wave, 40, SEEK_SET);
|
||||
Write4Bytes(f_wave, pos - 44);
|
||||
|
||||
|
||||
fclose(f_wave);
|
||||
f_wave = NULL;
|
||||
}
|
||||
|
||||
static int WavegenFile(void)
|
||||
{
|
||||
int finished;
|
||||
unsigned char wav_outbuf[1024];
|
||||
char fname[210];
|
||||
|
||||
out_ptr = out_start = wav_outbuf;
|
||||
out_end = wav_outbuf + sizeof(wav_outbuf);
|
||||
|
||||
int finished = WavegenFill(0);
|
||||
finished = WavegenFill(0);
|
||||
|
||||
if (quiet)
|
||||
return finished;
|
||||
@@ -329,6 +334,8 @@ static void init_path(char *argv0, char *path_specified)
|
||||
|
||||
static int initialise(void)
|
||||
{
|
||||
int param;
|
||||
int result;
|
||||
int srate = 22050; // default sample rate
|
||||
|
||||
// It seems that the wctype functions don't work until the locale has been set
|
||||
@@ -339,7 +346,6 @@ static int initialise(void)
|
||||
setlocale(LC_CTYPE, "");
|
||||
}
|
||||
|
||||
int result;
|
||||
if ((result = LoadPhData(&srate)) != 1) {
|
||||
if (result == -1) {
|
||||
fprintf(stderr, "Failed to load espeak-data\n");
|
||||
@@ -352,7 +358,7 @@ static int initialise(void)
|
||||
SetVoiceStack(NULL, "");
|
||||
SynthesizeInit();
|
||||
|
||||
for (int param = 0; param < N_SPEECH_PARAM; param++)
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++)
|
||||
param_stack[0].parameter[param] = param_defaults[param];
|
||||
|
||||
return 0;
|
||||
@@ -405,6 +411,7 @@ int main(int argc, char **argv)
|
||||
int c;
|
||||
int value;
|
||||
int speed = 175;
|
||||
int ix;
|
||||
char *optarg2;
|
||||
int amp = 100; // default
|
||||
int wordgap = 0;
|
||||
@@ -435,6 +442,7 @@ int main(int argc, char **argv)
|
||||
optind = 1;
|
||||
opt_string = "";
|
||||
while (optind < argc) {
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
if ((c = *opt_string) == 0) {
|
||||
@@ -454,10 +462,10 @@ int main(int argc, char **argv)
|
||||
break; // -- means don't interpret further - as commands
|
||||
|
||||
opt_string = "";
|
||||
for (int ix = 0;; ix++) {
|
||||
for (ix = 0;; ix++) {
|
||||
if (long_options[ix].name == 0)
|
||||
break;
|
||||
size_t len = strlen(long_options[ix].name);
|
||||
len = strlen(long_options[ix].name);
|
||||
if (memcmp(long_options[ix].name, p, len) == 0) {
|
||||
c = long_options[ix].val;
|
||||
optarg2 = NULL;
|
||||
@@ -559,7 +567,7 @@ int main(int argc, char **argv)
|
||||
case 0x103: // --punct
|
||||
option_punctuation = 1;
|
||||
if (optarg2 != NULL) {
|
||||
int ix = 0;
|
||||
ix = 0;
|
||||
while ((ix < N_PUNCTLIST) && ((option_punctlist[ix] = optarg2[ix]) != 0)) ix++;
|
||||
option_punctlist[N_PUNCTLIST-1] = 0;
|
||||
option_punctuation = 2;
|
||||
@@ -726,7 +734,7 @@ int main(int argc, char **argv)
|
||||
InitText(0);
|
||||
SpeakNextClause(f_text, p_text, 0);
|
||||
|
||||
int ix = 1;
|
||||
ix = 1;
|
||||
for (;;) {
|
||||
if (WavegenFile() != 0) {
|
||||
if (ix == 0)
|
||||
|
||||
Reference in New Issue
Block a user