diff options
Diffstat (limited to 'navit/support/espeak/setlengths.c')
| -rw-r--r--[-rwxr-xr-x] | navit/support/espeak/setlengths.c | 660 |
1 files changed, 505 insertions, 155 deletions
diff --git a/navit/support/espeak/setlengths.c b/navit/support/espeak/setlengths.c index ed4421bf9..ca557c888 100755..100644 --- a/navit/support/espeak/setlengths.c +++ b/navit/support/espeak/setlengths.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005 to 2007 by Jonathan Duddington * + * Copyright (C) 2005 to 2011 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * @@ -29,76 +29,103 @@ #include "synthesize.h" #include "voice.h" #include "translate.h" +#include "wavegen.h" -extern int GetAmplitude(void); +extern int saved_parameters[]; // convert from words-per-minute to internal speed factor -static unsigned char speed_lookup[290] = { - 250, 246, 243, 239, 236, // 80 - 233, 229, 226, 223, 220, // 85 - 217, 214, 211, 208, 205, // 90 - 202, 197, 194, 192, 190, // 95 - 187, 185, 183, 180, 178, // 100 - 176, 174, 172, 170, 168, // 105 - 166, 164, 161, 159, 158, // 110 - 156, 154, 152, 150, 148, // 115 - 146, 145, 143, 141, 137, // 120 - 136, 135, 133, 132, 131, // 125 - 129, 128, 127, 126, 125, // 130 - 124, 122, 121, 120, 119, // 135 - 117, 116, 115, 114, 113, // 140 - 112, 111, 110, 108, 107, // 145 - 106, 105, 104, 103, 102, // 150 - 101, 100, 99, 98, 97, // 155 - 96, 95, 93, 92, 92, // 160 - 91, 90, 89, 89, 88, // 165 - 87, 87, 86, 85, 85, // 170 - 84, 83, 83, 82, 81, // 175 - 80, 80, 79, 78, 78, // 180 - 77, 76, 76, 75, 73, // 185 - 72, 72, 71, 71, 70, // 190 - 70, 69, 69, 68, 67, // 195 - 67, 66, 66, 65, 65, // 200 - 64, 64, 63, 63, 62, // 205 - 62, 61, 60, 60, 59, // 210 - 59, 58, 58, 57, 57, // 215 - 56, 56, 55, 55, 55, // 220 - 54, 54, 53, 53, 52, // 225 - 52, 51, 51, 50, 50, // 230 - 49, 49, 49, 48, 48, // 235 - 47, 47, 46, 46, 46, // 240 - 45, 45, 44, 44, 43, // 245 - 43, 43, 42, 42, 41, // 250 - 41, 41, 40, 40, 39, // 255 - 39, 39, 38, 38, 38, // 260 - 37, 37, 37, 36, 36, // 265 - 35, 35, 35, 34, 34, // 270 - 34, 33, 33, 33, 32, // 275 - 32, 32, 32, 31, 31, // 280 - 31, 30, 30, 30, 29, // 285 - 29, 29, 29, 28, 28, // 290 - 28, 28, 27, 27, 27, // 295 - 26, 26, 26, 26, 25, // 300 - 25, 25, 22, 22, 22, // 305 - 22, 22, 22, 22, 22, // 310 - 21, 21, 21, 21, 21, // 315 - 21, 20, 20, 20, 20, // 320 - 20, 15, 15, 15, 15, // 325 - 15, 15, 15, 15, 16, // 330 - 16, 16, 16, 15, 15, // 335 - 15, 15, 15, 15, 15, // 340 - 15, 17, 17, 16, 16, // 345 - 15, 15, 14, 14, 13, // 350 - 13, 12, 12, 11, 11, // 355 - 10, 10, 9, 8, 8, // 360 - 7, 6, 5, 5, 4, // 365 +// Use this to calibrate speed for wpm 80-350 +static unsigned char speed_lookup[] = { + 255, 255, 255, 255, 255, // 80 + 253, 249, 245, 242, 238, // 85 + 235, 232, 228, 225, 222, // 90 + 218, 216, 213, 210, 207, // 95 + 204, 201, 198, 196, 193, // 100 + 191, 188, 186, 183, 181, // 105 + 179, 176, 174, 172, 169, // 110 + 168, 165, 163, 161, 159, // 115 + 158, 155, 153, 152, 150, // 120 + 148, 146, 145, 143, 141, // 125 + 139, 137, 136, 135, 133, // 130 + 131, 130, 129, 127, 126, // 135 + 124, 123, 122, 120, 119, // 140 + 118, 117, 115, 114, 113, // 145 + 112, 111, 110, 109, 107, // 150 + 106, 105, 104, 103, 102, // 155 + 101, 100, 99, 98, 97, // 160 + 96, 95, 94, 93, 92, // 165 + 91, 90, 89, 89, 88, // 170 + 87, 86, 85, 84, 83, // 175 + 82, 82, 81, 80, 80, // 180 + 79, 78, 77, 76, 76, // 185 + 75, 75, 74, 73, 72, // 190 + 71, 71, 70, 69, 69, // 195 + 68, 67, 67, 66, 66, // 200 + 65, 64, 64, 63, 62, // 205 + 62, 61, 61, 60, 59, // 210 + 59, 58, 58, 57, 57, // 215 + 56, 56, 55, 54, 54, // 220 + 53, 53, 52, 52, 52, // 225 + 51, 50, 50, 49, 49, // 230 + 48, 48, 47, 47, 46, // 235 + 46, 46, 45, 45, 44, // 240 + 44, 44, 43, 43, 42, // 245 + 41, 40, 40, 40, 39, // 250 + 39, 39, 38, 38, 38, // 255 + 37, 37, 37, 36, 36, // 260 + 35, 35, 35, 35, 34, // 265 + 34, 34, 33, 33, 33, // 270 + 32, 32, 31, 31, 31, // 275 + 30, 30, 30, 29, 29, // 280 + 29, 29, 28, 28, 27, // 285 + 27, 27, 27, 26, 26, // 290 + 26, 26, 25, 25, 25, // 295 + 24, 24, 24, 24, 23, // 300 + 23, 23, 23, 22, 22, // 305 + 22, 21, 21, 21, 21, // 310 + 20, 20, 20, 20, 19, // 315 + 19, 19, 18, 18, 17, // 320 + 17, 17, 16, 16, 16, // 325 + 16, 16, 16, 15, 15, // 330 + 15, 15, 14, 14, 14, // 335 + 13, 13, 13, 12, 12, // 340 + 12, 12, 11, 11, 11, // 345 + 11, 10, 10, 10, 9, // 350 + 9, 9, 8, 8, 8, // 355 }; -// speed_factor2 adjustments for speeds 370 to 390 -static unsigned char faster[] = { -114,112,110,109,107,105,104,102,100,98, // 370-379 -96,94,92,90,88,85,83,80,78,75,72 }; //380-390 + +// speed_factor1 adjustments for speeds 350 to 374: pauses +static unsigned char pause_factor_350[] = { +22,22,22,22,22,22,22,21,21,21, // 350 +21,20,20,19,19,18,17,16,15,15, // 360 +15,15,15,15,15}; // 370 + +// wav_factor adjustments for speeds 350 to 450 +// Use this to calibrate speed for wpm 350-450 +static unsigned char wav_factor_350[] = { + 120, 121, 120, 119, 119, // 350 + 118, 118, 117, 116, 116, // 355 + 115, 114, 113, 112, 112, // 360 + 111, 111, 110, 109, 108, // 365 + 107, 106, 106, 104, 103, // 370 + 103, 102, 102, 102, 101, // 375 + 101, 99, 98, 98, 97, // 380 + 96, 96, 95, 94, 93, // 385 + 91, 90, 91, 90, 89, // 390 + 88, 86, 85, 86, 85, // 395 + 85, 84, 82, 81, 80, // 400 + 79, 77, 78, 78, 76, // 405 + 77, 75, 75, 74, 73, // 410 + 71, 72, 70, 69, 69, // 415 + 69, 67, 65, 64, 63, // 420 + 63, 63, 61, 61, 59, // 425 + 59, 59, 58, 56, 57, // 430 + 58, 56, 54, 53, 52, // 435 + 52, 53, 52, 52, 50, // 440 + 48, 47, 47, 45, 46, // 445 + 45}; // 450 static int speed1 = 130; static int speed2 = 121; @@ -106,22 +133,96 @@ static int speed3 = 118; +//#define TEST_SPEED + +#ifdef INCLUDE_SONIC + 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; + speed.lenmod_factor = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change + speed.lenmod2_factor = 100; + speed.min_pause = 5; wpm = embedded_value[EMBED_S]; if(control == 2) wpm = embedded_value[EMBED_S2]; - wpm2 = wpm; - if(wpm > 369) wpm = 369; - if(wpm < 80) wpm = 80; + wpm_value = wpm; + + if(voice->speed_percent > 0) + { + wpm = (wpm * voice->speed_percent)/100; + } + + if(control & 2) + { + DoSonicSpeed(1 * 1024); + } + if((wpm_value > 450) || ((wpm_value > speed.fast_settings[0]) && (wpm > 350))) + { + wpm2 = wpm; + wpm = 175; + + // set special eSpeak speed parameters for Sonic use + // The eSpeak output will be speeded up by at least x2 + x = 73; + if(control & 1) + { + speed1 = (x * voice->speedf1)/256; + speed2 = (x * voice->speedf2)/256; + speed3 = (x * voice->speedf3)/256; + } + if(control & 2) + { + sonic = ((double)wpm2)/wpm; + DoSonicSpeed((int)(sonic * 1024)); + speed.pause_factor = 85; + speed.clause_pause_factor = 80; + speed.min_pause = 22; + speed.min_sample_len = 450*2; + speed.wav_factor = 211; + speed.lenmod_factor = 210; + speed.lenmod2_factor = 170; + } + return; + } + - x = speed_lookup[wpm-80]; +#ifdef TEST_SPEED + if(wpm > 1000) + { + // TESTING +// test = wpm / 1000; + wpm = wpm % 1000; + } +#endif + + if(wpm > 450) + wpm = 450; + + if(wpm > 360) + { + speed.loud_consonants = (wpm - 360) / 8; + } + + wpm2 = wpm; + if(wpm > 359) wpm2 = 359; + if(wpm < 80) wpm2 = 80; + x = speed_lookup[wpm2-80]; + + if(wpm >= 380) + x = 7; + if(wpm >= 400) + x = 6; if(control & 1) { @@ -130,45 +231,232 @@ void SetSpeed(int control) speed1 = (x * voice->speedf1)/256; speed2 = (x * voice->speedf2)/256; speed3 = (x * voice->speedf3)/256; + + if(x <= 7) + { + speed1 = x; + speed2 = speed3 = x - 1; + } } if(control & 2) { // these are used in synthesis file + + if(wpm > 350) + { + speed.lenmod_factor = 85 - (wpm - 350) / 3; + speed.lenmod2_factor = 60 - (wpm - 350) / 8; + } + else + if(wpm > 250) + { + speed.lenmod_factor = 110 - (wpm - 250)/4; + speed.lenmod2_factor = 110 - (wpm - 250)/2; + } + s1 = (x * voice->speedf1)/256; - speed.speed_factor1 = (256 * s1)/115; // full speed adjustment, used for pause length -if(speed.speed_factor1 < 15) - speed.speed_factor1 = 15; + if(wpm >= 170) -// speed_factor2 = 100 + (166*s1)/128; // reduced speed adjustment, used for playing recorded sounds - speed.speed_factor2 = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds + speed.wav_factor = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds + else + speed.wav_factor = 128 + (128*s1)/130; // = 215 at 170 wpm + + if(wpm >= 350) + { + speed.wav_factor = wav_factor_350[wpm-350]; + } + + if(wpm >= 390) + { + speed.min_sample_len = 450 - (wpm - 400)/2; + if(wpm > 440) + speed.min_sample_len = 420 - (wpm - 440); + } + +// adjust for different sample rates +speed.min_sample_len = (speed.min_sample_len * samplerate_native) / 22050; + + speed.pause_factor = (256 * s1)/115; // full speed adjustment, used for pause length + speed.clause_pause_factor = 0; + + if(wpm > 430) + { + speed.pause_factor = 12; +// speed.clause_pause_factor = 15; + } else - speed.speed_factor2 = 128 + (128*s1)/130; // = 215 at 170 wpm + if(wpm > 400) + { + speed.pause_factor = 13; +// speed.clause_pause_factor = 15; + } + else + if(wpm > 374) + { + speed.pause_factor = 14; + } + else + if(wpm > 350) + { + speed.pause_factor = pause_factor_350[wpm - 350]; + } - if(wpm2 > 369) + if(speed.clause_pause_factor == 0) { - if(wpm2 > 390) - wpm2 = 390; - speed.speed_factor2 = faster[wpm2 - 370]; + // restrict the reduction of pauses between clauses + if((speed.clause_pause_factor = speed.pause_factor) < 16) + speed.clause_pause_factor = 16; } } +#ifdef TEST_SPEED +//if(control==3) +printf("%3d: speedf %d %d %d pause=%d %d wav=%d lenmod=%d %d\n",wpm,speed1,speed2,speed3, speed.pause_factor,speed.clause_pause_factor, speed.wav_factor,speed.lenmod_factor,speed.lenmod2_factor); +#endif +} // end of SetSpeed + +#else // not using sonic speed-up + +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.speed_factor3 = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change + speed.lenmod_factor = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change + speed.lenmod2_factor = 100; + + wpm = embedded_value[EMBED_S]; + if(control == 2) + wpm = embedded_value[EMBED_S2]; - if(wpm2 >= 370) +#ifdef TEST_SPEED + if(wpm > 1000) { // TESTING - // use experimental fast settings if they have been specified in the Voice - if(speed.fast_settings[0] > 0) - speed.speed_factor1 = speed.fast_settings[0]; - if(speed.fast_settings[1] > 0) - speed.speed_factor2 = speed.fast_settings[1]; - if(speed.fast_settings[2] > 0) - speed.speed_factor3 = speed.fast_settings[2]; + test = wpm / 1000; + wpm = wpm % 1000; } +#endif + + if(voice->speed_percent > 0) + { + wpm = (wpm * voice->speed_percent)/100; + } + if(wpm > 450) + wpm = 450; + + if(wpm > 360) + { + speed.loud_consonants = (wpm - 360) / 8; + } + + wpm2 = wpm; + if(wpm > 359) wpm2 = 359; + if(wpm < 80) wpm2 = 80; + x = speed_lookup[wpm2-80]; + + if(wpm >= 380) + x = 7; + if(wpm >= 400) + x = 6; + + if(control & 1) + { + // set speed factors for different syllable positions within a word + // these are used in CalcLengths() + speed1 = (x * voice->speedf1)/256; + speed2 = (x * voice->speedf2)/256; + speed3 = (x * voice->speedf3)/256; + + if(x <= 7) + { + speed1 = x; + speed2 = speed3 = x - 1; + } + } + + if(control & 2) + { + // these are used in synthesis file + + if(wpm > 350) + { + speed.lenmod_factor = 85 - (wpm - 350) / 3; + speed.lenmod2_factor = 60 - (wpm - 350) / 8; + } + else + if(wpm > 250) + { + speed.lenmod_factor = 110 - (wpm - 250)/4; + speed.lenmod2_factor = 110 - (wpm - 250)/2; + } + + s1 = (x * voice->speedf1)/256; + + if(wpm >= 170) + speed.wav_factor = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds + else + speed.wav_factor = 128 + (128*s1)/130; // = 215 at 170 wpm + + if(wpm >= 350) + { + speed.wav_factor = wav_factor_350[wpm-350]; + } + + if(wpm >= 390) + { + speed.min_sample_len = 450 - (wpm - 400)/2; + if(wpm > 440) + speed.min_sample_len = 420 - (wpm - 440); + } + + speed.pause_factor = (256 * s1)/115; // full speed adjustment, used for pause length + speed.clause_pause_factor = 0; + + if(wpm > 430) + { + speed.pause_factor = 12; +// speed.clause_pause_factor = 15; + } + else + if(wpm > 400) + { + speed.pause_factor = 13; +// speed.clause_pause_factor = 15; + } + else + if(wpm > 374) + { + speed.pause_factor = 14; + } + else + if(wpm > 350) + { + speed.pause_factor = pause_factor_350[wpm - 350]; + } + + if(speed.clause_pause_factor == 0) + { + // restrict the reduction of pauses between clauses + if((speed.clause_pause_factor = speed.pause_factor) < 16) + speed.clause_pause_factor = 16; + } + } + +#ifdef TEST_SPEED +//if(control==3) +printf("%3d: speedf %d %d %d pause=%d %d wav=%d lenmod=%d %d\n",wpm,speed1,speed2,speed3, speed.pause_factor,speed.clause_pause_factor, speed.wav_factor,speed.lenmod_factor,speed.lenmod2_factor); +#endif } // end of SetSpeed +#endif // of INCLUDE_SONIC + #ifdef deleted void SetAmplitude(int amp) @@ -177,7 +465,7 @@ void SetAmplitude(int amp) if((amp >= 0) && (amp <= 20)) { - option_amplitude = (amplitude_factor[amp] * 480)/256; + option_amplitude = (amplitude_factor[amp] * 480)/256; } } #endif @@ -201,6 +489,7 @@ void SetParameter(int parameter, int value, int relative) } } param_stack[0].parameter[parameter] = new_value; + saved_parameters[parameter] = new_value; switch(parameter) { @@ -285,14 +574,17 @@ void CalcLengths(Translator *tr) int last_pitch = 0; int pitch_start; int length_mod; + int next2type; int len; int env2; int end_of_clause; int embedded_ix = 0; int min_drop; + int pitch1; int emphasized; int tone_mod; unsigned char *pitch_env=NULL; + PHONEME_DATA phdata_tone; for(ix=1; ix<n_phoneme_list; ix++) { @@ -317,14 +609,14 @@ void CalcLengths(Translator *tr) case phPAUSE: last_pitch = 0; break; - + case phSTOP: last_pitch = 0; if(prev->type == phFRICATIVE) - p->prepause = 20; + p->prepause = 25; else if((more_syllables > 0) || (stress < 4)) - p->prepause = 40; + p->prepause = 48; else p->prepause = 60; @@ -342,13 +634,17 @@ void CalcLengths(Translator *tr) break; case phVFRICATIVE: - if(next->type==phVOWEL) - { - pre_voiced = 1; - } // drop through case phFRICATIVE: if(p->newword) - p->prepause = 15; + { + if((prev->type == phVOWEL) && (p->ph->phflags & phNOPAUSE)) + { + } + else + { + p->prepause = 15; + } + } if(next->type==phPAUSE && prev->type==phNASAL && !(p->ph->phflags&phFORTIS)) p->prepause = 25; @@ -356,6 +652,9 @@ void CalcLengths(Translator *tr) if(prev->ph->phflags & phBRKAFTER) p->prepause = 30; + if((tr->langopts.word_gap & 0x10) && (p->newword)) + p->prepause = 30; + if((p->ph->phflags & phSIBILANT) && next->type==phSTOP && !next->newword) { if(prev->type == phVOWEL) @@ -366,9 +665,17 @@ void CalcLengths(Translator *tr) else p->length = 256; - if((tr->langopts.word_gap & 0x10) && (p->newword)) - p->prepause = 30; - + if(type == phVFRICATIVE) + { + if(next->type==phVOWEL) + { + pre_voiced = 1; + } + if((prev->type==phVOWEL) || (prev->type == phLIQUID)) + { + p->length = (255 + prev->length)/2; + } + } break; case phVSTOP: @@ -382,8 +689,19 @@ void CalcLengths(Translator *tr) p->prepause = 40; - if((prev->type == phPAUSE) || (prev->type == phVOWEL)) // || (prev->ph->mnemonic == ('/'*256+'r'))) - p->prepause = 0; + if(prev->type == phVOWEL) + { + p->prepause = 0; // use murmur instead to link from the preceding vowel + } + else + if(prev->type == phPAUSE) + { + // reduce by the length of the preceding pause + if(prev->length < p->prepause) + p->prepause -= prev->length; + else + p->prepause = 0; + } else if(p->newword==0) { @@ -403,16 +721,19 @@ void CalcLengths(Translator *tr) case phLIQUID: case phNASAL: - p->amp = tr->stress_amps[1]; // unless changed later + p->amp = tr->stress_amps[0]; // unless changed later p->length = 256; // TEMPORARY min_drop = 0; - + if(p->newword) { if(prev->type==phLIQUID) p->prepause = 25; if(prev->type==phVOWEL) - p->prepause = 12; + { + if(!(p->ph->phflags & phNOPAUSE)) + p->prepause = 12; + } } if(next->type==phVOWEL) @@ -420,43 +741,44 @@ void CalcLengths(Translator *tr) pre_sonorant = 1; } else - if((prev->type==phVOWEL) || (prev->type == phLIQUID)) { - p->length = prev->length; p->pitch2 = last_pitch; - if(p->pitch2 < 7) - p->pitch2 = 7; - p->pitch1 = p->pitch2 - 8; - p->env = PITCHfall; - pre_voiced = 0; - - if(p->type == phLIQUID) - { - p->length = speed1; -//p->pitch1 = p->pitch2 - 20; // post vocalic [r/] - } - if(next->type == phVSTOP) + if((prev->type==phVOWEL) || (prev->type == phLIQUID)) { - p->length = (p->length * 160)/100; - } - if(next->type == phVFRICATIVE) - { - p->length = (p->length * 120)/100; + p->length = prev->length; + + if(p->type == phLIQUID) + { + p->length = speed1; + } + + if(next->type == phVSTOP) + { + p->length = (p->length * 160)/100; + } + if(next->type == phVFRICATIVE) + { + p->length = (p->length * 120)/100; + } } - } - else - { - p->pitch2 = last_pitch; - for(ix2=ix; ix2<n_phoneme_list; ix2++) + else { - if(phoneme_list[ix2].type == phVOWEL) + for(ix2=ix; ix2<n_phoneme_list; ix2++) { - p->pitch2 = phoneme_list[ix2].pitch2; - break; + if(phoneme_list[ix2].type == phVOWEL) + { + p->pitch2 = phoneme_list[ix2].pitch2; + break; + } } } - p->pitch1 = p->pitch2-8; + + p->pitch1 = p->pitch2-16; + if(p->pitch2 < 16) + { + p->pitch1 = 0; + } p->env = PITCHfall; pre_voiced = 0; } @@ -469,6 +791,10 @@ void CalcLengths(Translator *tr) if(stress > 7) stress = 7; +if(stress <= 1) +{ + stress = stress ^ 1; // swap diminished and unstressed (until we swap stress_amps,stress_lengths in tr_languages) +} if(pre_sonorant) p->amp = tr->stress_amps[stress]-1; else @@ -512,9 +838,17 @@ void CalcLengths(Translator *tr) next3 = &phoneme_list[ix+4]; } + next2type = next2->ph->length_mod; if(more_syllables==0) { - len = tr->langopts.length_mods0[next2->ph->length_mod *10+ next->ph->length_mod]; + if(next->newword || next2->newword) + { + // don't use 2nd phoneme over a word boundary, unless it's a pause + if(next2type != 1) + next2type = 0; + } + + len = tr->langopts.length_mods0[next2type *10+ next->ph->length_mod]; if((next->newword) && (tr->langopts.word_gap & 0x20)) { @@ -526,7 +860,7 @@ void CalcLengths(Translator *tr) } else { - length_mod = tr->langopts.length_mods[next2->ph->length_mod *10+ next->ph->length_mod]; + length_mod = tr->langopts.length_mods[next2type *10+ next->ph->length_mod]; if((next->type == phNASAL) && (next2->type == phSTOP || next2->type == phVSTOP) && (next3->ph->phflags & phFORTIS)) length_mod -= 15; @@ -548,20 +882,20 @@ void CalcLengths(Translator *tr) if(stress >= 7) { // tonic syllable, include a constant component so it doesn't decrease directly with speed - length_mod += 20; + length_mod += tr->langopts.lengthen_tonic; if(emphasized) - length_mod += 10; + length_mod += (tr->langopts.lengthen_tonic/2); } else if(emphasized) { - length_mod += 20; + length_mod += tr->langopts.lengthen_tonic; } - + if((len = tr->stress_lengths[stress]) == 0) len = tr->stress_lengths[6]; - length_mod = (length_mod * len)/128; + length_mod = length_mod * len; if(p->tone_ph != 0) { @@ -572,30 +906,45 @@ void CalcLengths(Translator *tr) } } - if(end_of_clause == 2) + + if((end_of_clause == 2) && !(tr->langopts.stress_flags & S_NO_EOC_LENGTHEN)) { // this is the last syllable in the clause, lengthen it - more for short vowels - len = p->ph->std_length; - if(tr->langopts.stress_flags & 0x40000) + len = (p->ph->std_length * 2); + if(tr->langopts.stress_flags & S_EO_CLAUSE1) len=200; // don't lengthen short vowels more than long vowels at end-of-clause length_mod = length_mod * (256 + (280 - len)/3)/256; } + if(length_mod > tr->langopts.max_lengthmod*speed1) + { + //limit the vowel length adjustment for some languages + length_mod = (tr->langopts.max_lengthmod*speed1); + } + + length_mod = length_mod / 128; + if(p->type != phVOWEL) { length_mod = 256; // syllabic consonant - min_drop = 8; + min_drop = 16; } p->length = length_mod; + if(p->env >= (N_ENVELOPE_DATA-1)) + { + fprintf(stderr,"espeak: Bad intonation data\n"); + p->env = 0; + } + // pre-vocalic part // set last-pitch - env2 = p->env; - if(env2 > 1) env2++; // version for use with preceding semi-vowel + env2 = p->env + 1; // version for use with preceding semi-vowel if(p->tone_ph != 0) { - pitch_env = LookupEnvelope(phoneme_tab[p->tone_ph]->spect); + InterpretPhoneme2(p->tone_ph, &phdata_tone); + pitch_env = GetEnvelope(phdata_tone.pitch_env); } else { @@ -607,11 +956,11 @@ if(p->type != phVOWEL) if(pre_sonorant || pre_voiced) { // set pitch for pre-vocalic part - if(pitch_start == 1024) + if(pitch_start == 255) last_pitch = pitch_start; // pitch is not set - if(pitch_start - last_pitch > 8) // was 9 - last_pitch = pitch_start - 8; + if(pitch_start - last_pitch > 16) + last_pitch = pitch_start - 16; prev->pitch1 = last_pitch; prev->pitch2 = pitch_start; @@ -636,11 +985,11 @@ if(p->type != phVOWEL) next->synthflags &= ~SFLAG_SEQCONTINUE; if(next->type == phNASAL && next2->type != phVOWEL) next->synthflags |= SFLAG_SEQCONTINUE; - + if(next->type == phLIQUID) { next->synthflags |= SFLAG_SEQCONTINUE; - + if(next2->type == phVOWEL) { next->synthflags &= ~SFLAG_SEQCONTINUE; @@ -658,9 +1007,10 @@ if(p->type != phVOWEL) if((min_drop > 0) && ((p->pitch2 - p->pitch1) < min_drop)) { - p->pitch1 = p->pitch2 - min_drop; - if(p->pitch1 < 0) - p->pitch1 = 0; + pitch1 = p->pitch2 - min_drop; + if(pitch1 < 0) + pitch1 = 0; + p->pitch1 = pitch1; } last_pitch = p->pitch1 + ((p->pitch2-p->pitch1)*envelope_data[p->env][127])/256; |
