buflength: The length in mS of sound buffers passed to the SynthCallback function. | buflength: The length in mS of sound buffers passed to the SynthCallback function. | ||||
Value=0 gives a default of 60mS. | Value=0 gives a default of 60mS. | ||||
This paramater is only used for AUDIO_OUTPUT_RETRIEVAL and AUDIO_OUTPUT_SYNCHRONOUS modes. | |||||
This parameter is only used for AUDIO_OUTPUT_RETRIEVAL and AUDIO_OUTPUT_SYNCHRONOUS modes. | |||||
path: The directory which contains the espeak-ng-data directory, or NULL for the default location. | path: The directory which contains the espeak-ng-data directory, or NULL for the default location. | ||||
sometimes be zero (which does NOT indicate end of synthesis). | sometimes be zero (which does NOT indicate end of synthesis). | ||||
events: an array of espeak_EVENT items which indicate word and sentence events, and | events: an array of espeak_EVENT items which indicate word and sentence events, and | ||||
also the occurance if <mark> and <audio> elements within the text. The list of | |||||
also the occurrence if <mark> and <audio> elements within the text. The list of | |||||
events is terminated by an event of type = 0. | events is terminated by an event of type = 0. | ||||
static int NextItemBrackets(int type, int control) | static int NextItemBrackets(int type, int control) | ||||
{ | { | ||||
// Expect a parameter inside parantheses | |||||
// Expect a parameter inside parentheses | |||||
// control: bit 0 0= need ( | // control: bit 0 0= need ( | ||||
// bit 1 1= allow comma | // bit 1 1= allow comma | ||||
for (p = phon_buf2; *p != 0;) { | for (p = phon_buf2; *p != 0;) { | ||||
p += utf8_in(&c, p); | p += utf8_in(&c, p); | ||||
if (use_tie != 0) { | if (use_tie != 0) { | ||||
// look for non-inital alphabetic character, but not diacritic, superscript etc. | |||||
// look for non-initial alphabetic character, but not diacritic, superscript etc. | |||||
if ((count > 0) && !(flags & (1 << (count-1))) && ((c < 0x2b0) || (c > 0x36f)) && iswalpha(c)) | if ((count > 0) && !(flags & (1 << (count-1))) && ((c < 0x2b0) || (c > 0x36f)) && iswalpha(c)) | ||||
buf += utf8_out(use_tie, buf); | buf += utf8_out(use_tie, buf); | ||||
} | } | ||||
* Returns number of letter group | * Returns number of letter group | ||||
*/ | */ | ||||
int groupNo = *rule; | int groupNo = *rule; | ||||
groupNo = groupNo - 'A'; // substracting 'A' makes letter_group equal to number in .Lxx definition | |||||
groupNo = groupNo - 'A'; // subtracting 'A' makes letter_group equal to number in .Lxx definition | |||||
if (groupNo < 0) // fix sign if necessary | if (groupNo < 0) // fix sign if necessary | ||||
groupNo += 256; | groupNo += 256; | ||||
return groupNo; | return groupNo; | ||||
// is it a bracket ? | // is it a bracket ? | ||||
if (letter == 0xe000+'(') { | if (letter == 0xe000+'(') { | ||||
if (pre_pause < tr->langopts.param2[LOPT_BRACKET_PAUSE]) | if (pre_pause < tr->langopts.param2[LOPT_BRACKET_PAUSE]) | ||||
pre_pause = tr->langopts.param2[LOPT_BRACKET_PAUSE]; // a bracket, aleady spoken by AnnouncePunctuation() | |||||
pre_pause = tr->langopts.param2[LOPT_BRACKET_PAUSE]; // a bracket, already spoken by AnnouncePunctuation() | |||||
} | } | ||||
if (IsBracket(letter)) { | if (IsBracket(letter)) { | ||||
if (pre_pause < tr->langopts.param[LOPT_BRACKET_PAUSE]) | if (pre_pause < tr->langopts.param[LOPT_BRACKET_PAUSE]) | ||||
int len; | int len; | ||||
char ending[50] = {0}; | char ending[50] = {0}; | ||||
// these lists are language specific, but are only relevent if the 'e' suffix flag is used | |||||
// these lists are language specific, but are only relevant if the 'e' suffix flag is used | |||||
static const char *add_e_exceptions[] = { | static const char *add_e_exceptions[] = { | ||||
"ion", NULL | "ion", NULL | ||||
}; | }; |
* along with this program; if not, see: <http://www.gnu.org/licenses/>. | * along with this program; if not, see: <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
// This source file is only used for asynchronious modes | |||||
// This source file is only used for asynchronous modes | |||||
#include "config.h" | #include "config.h" | ||||
// Initialize the event component. | // Initialize the event component. | ||||
// First function to be called. | // First function to be called. | ||||
// the callback will be called when the event actually occurs. | // the callback will be called when the event actually occurs. | ||||
// The callback is detailled in speak_lib.h . | |||||
// The callback is detailed in speak_lib.h . | |||||
void event_init(void); | void event_init(void); | ||||
void event_set_callback(t_espeak_callback *cb); | void event_set_callback(t_espeak_callback *cb); | ||||
* along with this program; if not, see: <http://www.gnu.org/licenses/>. | * along with this program; if not, see: <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
// This source file is only used for asynchronious modes | |||||
// This source file is only used for asynchronous modes | |||||
#include "config.h" | #include "config.h" | ||||
pitch_range = (tune->head_end - tune->head_start) << 8; | pitch_range = (tune->head_end - tune->head_start) << 8; | ||||
pitch_range_abs = abs(pitch_range); | pitch_range_abs = abs(pitch_range); | ||||
drops = drops_0; // this should be controled by tune->head_drops | |||||
drops = drops_0; // this should be controlled by tune->head_drops | |||||
initial = true; | initial = true; | ||||
stage = 0; | stage = 0; | ||||
PHONEME_TAB *prevw_tph; // remember across word boundary | PHONEME_TAB *prevw_tph; // remember across word boundary | ||||
PHONEME_LIST *prev_p; | PHONEME_LIST *prev_p; | ||||
int pitch_adjust = 0; // pitch gradient through the clause - inital value | |||||
int pitch_adjust = 0; // pitch gradient through the clause - initial value | |||||
int pitch_decrement = 0; // decrease by this for each stressed syllable | int pitch_decrement = 0; // decrease by this for each stressed syllable | ||||
int pitch_low = 0; // until it drops to this | int pitch_low = 0; // until it drops to this | ||||
int pitch_high = 0; // then reset to this | int pitch_high = 0; // then reset to this |
/* | /* | ||||
function SETABC | function SETABC | ||||
Convert formant freqencies and bandwidth into resonator difference | |||||
Convert formant frequencies and bandwidth into resonator difference | |||||
equation constants. | equation constants. | ||||
*/ | */ | ||||
/* | /* | ||||
function SETZEROABC | function SETZEROABC | ||||
Convert formant freqencies and bandwidth into anti-resonator difference | |||||
Convert formant frequencies and bandwidth into anti-resonator difference | |||||
equation constants. | equation constants. | ||||
*/ | */ | ||||
long T0; /* Fundamental period in output samples times 4 */ | long T0; /* Fundamental period in output samples times 4 */ | ||||
long nopen; /* Number of samples in open phase of period */ | long nopen; /* Number of samples in open phase of period */ | ||||
long nmod; /* Position in period to begin noise amp. modul */ | long nmod; /* Position in period to begin noise amp. modul */ | ||||
long nrand; /* Varible used by random number generator */ | |||||
long nrand; /* Variable used by random number generator */ | |||||
double pulse_shape_a; /* Makes waveshape of glottal pulse when open */ | double pulse_shape_a; /* Makes waveshape of glottal pulse when open */ | ||||
double pulse_shape_b; /* Makes waveshape of glottal pulse when open */ | double pulse_shape_b; /* Makes waveshape of glottal pulse when open */ | ||||
double minus_pi_t; | double minus_pi_t; |
if (ph_ordinal2[0] != 0) { | if (ph_ordinal2[0] != 0) { | ||||
ix = strlen(buf1); | ix = strlen(buf1); | ||||
if ((ix > 0) && (buf1[ix-1] == phonPAUSE_SHORT)) | if ((ix > 0) && (buf1[ix-1] == phonPAUSE_SHORT)) | ||||
buf1[ix-1] = 0; // remove pause before addding ordinal suffix | |||||
buf1[ix-1] = 0; // remove pause before adding ordinal suffix | |||||
strcpy(buf2, ph_ordinal2); | strcpy(buf2, ph_ordinal2); | ||||
} | } | ||||
} | } |
static int LookupSoundicon(int c) | static int LookupSoundicon(int c) | ||||
{ | { | ||||
// Find the sound icon number for a punctuation chatacter | |||||
// Find the sound icon number for a punctuation character | |||||
int ix; | int ix; | ||||
for (ix = N_SOUNDICON_SLOTS; ix < n_soundicon_tab; ix++) { | for (ix = N_SOUNDICON_SLOTS; ix < n_soundicon_tab; ix++) { |
static void EndPitch(int voice_break) | static void EndPitch(int voice_break) | ||||
{ | { | ||||
// posssible end of pitch envelope, fill in the length | |||||
// possible end of pitch envelope, fill in the length | |||||
if ((pitch_length > 0) && (last_pitch_cmd >= 0)) { | if ((pitch_length > 0) && (last_pitch_cmd >= 0)) { | ||||
if (wcmdq[last_pitch_cmd][1] == 0) | if (wcmdq[last_pitch_cmd][1] == 0) | ||||
wcmdq[last_pitch_cmd][1] = pitch_length; | wcmdq[last_pitch_cmd][1] = pitch_length; |
#define INSTN_RETURN 0x0001 | #define INSTN_RETURN 0x0001 | ||||
#define INSTN_CONTINUE 0x0002 | #define INSTN_CONTINUE 0x0002 | ||||
// Group 0 instrcutions with 8 bit operand. These values go into bits 8-15 of the instruction | |||||
// Group 0 instructions with 8 bit operand. These values go into bits 8-15 of the instruction | |||||
#define i_CHANGE_PHONEME 0x01 | #define i_CHANGE_PHONEME 0x01 | ||||
#define i_REPLACE_NEXT_PHONEME 0x02 | #define i_REPLACE_NEXT_PHONEME 0x02 | ||||
#define i_INSERT_PHONEME 0x03 | #define i_INSERT_PHONEME 0x03 |
static void SetCyrillicLetters(Translator *tr) | static void SetCyrillicLetters(Translator *tr) | ||||
{ | { | ||||
// Set letter types for Cyrillic script languages: bg (Bulgarian), ru (Russian), tt (Tatar), uk (Ukranian). | |||||
// Set letter types for Cyrillic script languages: bg (Bulgarian), ru (Russian), tt (Tatar), uk (Ukrainian). | |||||
// character codes offset by 0x420 | // character codes offset by 0x420 | ||||
static const char cyrl_soft[] = { 0x2c, 0x19, 0x27, 0x29, 0 }; // letter group B [k ts; s;] -- ь й ч щ | static const char cyrl_soft[] = { 0x2c, 0x19, 0x27, 0x29, 0 }; // letter group B [k ts; s;] -- ь й ч щ | ||||
tr->letter_bits_offset = OFFSET_TAMIL; | tr->letter_bits_offset = OFFSET_TAMIL; | ||||
tr->langopts.numbers = NUM_OMIT_1_THOUSAND; | tr->langopts.numbers = NUM_OMIT_1_THOUSAND; | ||||
tr->langopts.numbers2 = NUM2_ORDINAL_AND_THOUSANDS; | tr->langopts.numbers2 = NUM2_ORDINAL_AND_THOUSANDS; | ||||
tr->langopts.param[LOPT_WORD_MERGE] = 1; // don't break vowels betwen words | |||||
tr->langopts.param[LOPT_WORD_MERGE] = 1; // don't break vowels between words | |||||
} else if (name2 == L('m', 'l')) { | } else if (name2 == L('m', 'l')) { | ||||
static const short stress_lengths_ml[8] = { 180, 160, 240, 240, 0, 0, 260, 260 }; | static const short stress_lengths_ml[8] = { 180, 160, 240, 240, 0, 0, 260, 260 }; | ||||
SetupTranslator(tr, stress_lengths_ml, stress_amps_equal); | SetupTranslator(tr, stress_lengths_ml, stress_amps_equal); |
if (spell_word > 2) | if (spell_word > 2) | ||||
capitals = 2; // speak 'capital' | capitals = 2; // speak 'capital' | ||||
if (spell_word > 1) | if (spell_word > 1) | ||||
capitals |= 4; // speak charater code for unknown letters | |||||
capitals |= 4; // speak character code for unknown letters | |||||
while ((*word != ' ') && (*word != 0)) { | while ((*word != ' ') && (*word != 0)) { | ||||
word += TranslateLetter(tr, word, phonemes, capitals | non_initial, current_alphabet); | word += TranslateLetter(tr, word, phonemes, capitals | non_initial, current_alphabet); | ||||
if (final > 0) | if (final > 0) | ||||
*insert = final + 0x11a7; | *insert = final + 0x11a7; | ||||
} else { | } else { | ||||
// extact the initial and insert the remainder with a null initial | |||||
// extract the initial and insert the remainder with a null initial | |||||
c = initial + 0x1100; | c = initial + 0x1100; | ||||
*insert = (11*28*21) + (medial*28) + final + 0xac00; | *insert = (11*28*21) + (medial*28) + final + 0xac00; | ||||
} | } |
#define FLAG_LAST_WORD 0x10 // last word in clause | #define FLAG_LAST_WORD 0x10 // last word in clause | ||||
#define FLAG_EMBEDDED 0x40 // word is preceded by embedded commands | #define FLAG_EMBEDDED 0x40 // word is preceded by embedded commands | ||||
#define FLAG_HYPHEN 0x80 | #define FLAG_HYPHEN 0x80 | ||||
#define FLAG_NOSPACE 0x100 // word is not seperated from previous word by a space | |||||
#define FLAG_NOSPACE 0x100 // word is not separated from previous word by a space | |||||
#define FLAG_FIRST_WORD 0x200 // first word in clause | #define FLAG_FIRST_WORD 0x200 // first word in clause | ||||
#define FLAG_FOCUS 0x400 // the focus word of a clause | #define FLAG_FOCUS 0x400 // the focus word of a clause | ||||
#define FLAG_EMPHASIZED 0x800 | #define FLAG_EMPHASIZED 0x800 | ||||
// bit 1=LANG=cz,bg don't propagate over [v] | // bit 1=LANG=cz,bg don't propagate over [v] | ||||
// bit 2=don't propagate acress word boundaries | // bit 2=don't propagate acress word boundaries | ||||
// bit 3=LANG=pl, propagate over liquids and nasals | // bit 3=LANG=pl, propagate over liquids and nasals | ||||
// bit 4=LANG=cz,sk don't progagate to [v] | |||||
// bit 4=LANG=cz,sk don't propagate to [v] | |||||
// bit 8=devoice word-final consonants | // bit 8=devoice word-final consonants | ||||
#define LOPT_REGRESSIVE_VOICING 4 | #define LOPT_REGRESSIVE_VOICING 4 | ||||
// bit 1: stressed syllable: $alt change [e],[o] to [E],[O], $alt2 change [E],[O] to [e],[o] | // bit 1: stressed syllable: $alt change [e],[o] to [E],[O], $alt2 change [E],[O] to [e],[o] | ||||
#define LOPT_ALT 15 | #define LOPT_ALT 15 | ||||
// pause for bracket (default=4), pause when annoucing bracket names (default=2) | |||||
// pause for bracket (default=4), pause when announcing bracket names (default=2) | |||||
#define LOPT_BRACKET_PAUSE 16 | #define LOPT_BRACKET_PAUSE 16 | ||||
// bit 1, don't break clause before annoucning . ? ! | // bit 1, don't break clause before annoucning . ? ! | ||||
#define NUM_HUNDRED_AND 0x00000040 // add "and" after hundred or thousand | #define NUM_HUNDRED_AND 0x00000040 // add "and" after hundred or thousand | ||||
#define NUM_SINGLE_AND 0x00000080 // don't have "and" both after hundreds and also between tens and units | #define NUM_SINGLE_AND 0x00000080 // don't have "and" both after hundreds and also between tens and units | ||||
#define NUM_SINGLE_STRESS 0x00000100 // only one primary stress in tens+units | #define NUM_SINGLE_STRESS 0x00000100 // only one primary stress in tens+units | ||||
#define NUM_SINGLE_VOWEL 0x00000200 // only one vowel betwen tens and units | |||||
#define NUM_SINGLE_VOWEL 0x00000200 // only one vowel between tens and units | |||||
#define NUM_OMIT_1_HUNDRED 0x00000400 // omit "one" before "hundred" | #define NUM_OMIT_1_HUNDRED 0x00000400 // omit "one" before "hundred" | ||||
#define NUM_1900 0x00000800 // say 19** as nineteen hundred | #define NUM_1900 0x00000800 // say 19** as nineteen hundred | ||||
#define NUM_ALLOW_SPACE 0x00001000 // allow space as thousands separator (in addition to langopts.thousands_sep) | #define NUM_ALLOW_SPACE 0x00001000 // allow space as thousands separator (in addition to langopts.thousands_sep) |