@@ -543,33 +543,11 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b | |||
SetWordStress(tr, ph_buf1, dict_flags, -1, control & 1); | |||
} | |||
// unicode ranges for non-ascii digits 0-9 (these must be in ascending order) | |||
static const int number_ranges[] = { | |||
0x660, 0x6f0, // arabic | |||
0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xbe6, 0xc66, 0xce6, 0xd66, // indic | |||
0xe50, 0xed0, 0xf20, 0x1040, 0x1090, | |||
0 | |||
}; | |||
static int NonAsciiNumber(int letter) | |||
{ | |||
// Change non-ascii digit into ascii digit '0' to '9', (or -1 if not) | |||
const int *p; | |||
int base; | |||
for (p = number_ranges; (base = *p) != 0; p++) { | |||
if (letter < base) | |||
break; // not found | |||
if (letter < (base+10)) | |||
return letter-base+'0'; | |||
} | |||
return -1; | |||
} | |||
#define L_SUB 0x4000 // subscript | |||
#define L_SUP 0x8000 // superscript | |||
static const char *modifiers[] = { NULL, "_sub", "_sup", NULL }; | |||
// this list must be in ascending order | |||
static unsigned short derived_letters[] = { | |||
@@ -638,15 +616,7 @@ static unsigned short derived_letters[] = { | |||
0, 0 | |||
}; | |||
// names, using phonemes available to all languages | |||
static const char *hex_letters[] = { | |||
"'e:j", | |||
"b'i:", | |||
"s'i:", | |||
"d'i:", | |||
"'i:", | |||
"'ef" | |||
}; | |||
int IsSuperscript(int letter) | |||
{ | |||
@@ -663,247 +633,6 @@ int IsSuperscript(int letter) | |||
return 0; | |||
} | |||
int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALPHABET *current_alphabet) | |||
{ | |||
// get pronunciation for an isolated letter | |||
// return number of bytes used by the letter | |||
// control bit 0: a non-initial letter in a word | |||
// bit 1: say 'capital' | |||
// bit 2: say character code for unknown letters | |||
int n_bytes; | |||
int letter; | |||
int len; | |||
int ix; | |||
int c; | |||
char *p2; | |||
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]; | |||
char ph_buf2[80]; | |||
char ph_alphabet[80]; | |||
char hexbuf[12]; | |||
static const char pause_string[] = { phonPAUSE, 0 }; | |||
ph_buf[0] = 0; | |||
ph_alphabet[0] = 0; | |||
capital[0] = 0; | |||
phontab_1 = translator->phoneme_tab_ix; | |||
n_bytes = utf8_in(&letter, word); | |||
if ((letter & 0xfff00) == 0x0e000) | |||
letter &= 0xff; // uncode private usage area | |||
if (control & 2) { | |||
// include CAPITAL information | |||
if (iswupper(letter)) | |||
Lookup(tr, "_cap", capital); | |||
} | |||
letter = towlower2(letter, tr); | |||
LookupLetter(tr, letter, word[n_bytes], ph_buf, control & 1); | |||
if (ph_buf[0] == 0) { | |||
// is this a subscript or superscript letter ? | |||
if ((c = IsSuperscript(letter)) != 0) { | |||
letter = c & 0x3fff; | |||
if ((control & 4 ) && ((modifier = modifiers[c >> 14]) != NULL)) { | |||
// don't say "superscript" during normal text reading | |||
Lookup(tr, modifier, capital); | |||
if (capital[0] == 0) { | |||
capital[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 | |||
Lookup(translator3, modifier, &capital[3]); | |||
if (capital[3] != 0) { | |||
capital[0] = phonPAUSE; | |||
capital[1] = phonSWITCH; | |||
len = strlen(&capital[3]); | |||
capital[len+3] = phonSWITCH; | |||
capital[len+4] = phontab_1; | |||
capital[len+5] = 0; | |||
} | |||
} | |||
} | |||
} | |||
LookupLetter(tr, letter, word[n_bytes], ph_buf, control & 1); | |||
} | |||
if (ph_buf[0] == phonSWITCH) { | |||
strcpy(phonemes, ph_buf); | |||
return 0; | |||
} | |||
if ((ph_buf[0] == 0) && ((number = NonAsciiNumber(letter)) > 0)) { | |||
// convert a non-ascii number to 0-9 | |||
LookupLetter(tr, number, 0, ph_buf, control & 1); | |||
} | |||
al_offset = 0; | |||
al_flags = 0; | |||
if ((alphabet = AlphabetFromChar(letter)) != NULL) { | |||
al_offset = alphabet->offset; | |||
al_flags = alphabet->flags; | |||
} | |||
if (alphabet != current_alphabet) { | |||
// speak the name of the alphabet | |||
current_alphabet = alphabet; | |||
if ((alphabet != NULL) && !(al_flags & AL_DONT_NAME) && (al_offset != translator->letter_bits_offset)) { | |||
if ((al_flags & AL_DONT_NAME) || (al_offset == translator->langopts.alt_alphabet) || (al_offset == translator->langopts.our_alphabet)) { | |||
// don't say the alphabet name | |||
} else { | |||
ph_buf2[0] = 0; | |||
if (Lookup(translator, alphabet->name, ph_alphabet) == 0) { // the original language for the current voice | |||
// Can't find the local name for this alphabet, use the English name | |||
ph_alphabet[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 | |||
Lookup(translator3, alphabet->name, ph_buf2); | |||
} else if (translator != tr) { | |||
phontab_1 = tr->phoneme_tab_ix; | |||
strcpy(ph_buf2, ph_alphabet); | |||
ph_alphabet[2] = translator->phoneme_tab_ix; | |||
} | |||
if (ph_buf2[0] != 0) { | |||
// we used a different language for the alphabet name (now in ph_buf2) | |||
ph_alphabet[0] = phonPAUSE; | |||
ph_alphabet[1] = phonSWITCH; | |||
strcpy(&ph_alphabet[3], ph_buf2); | |||
len = strlen(ph_buf2) + 3; | |||
ph_alphabet[len] = phonSWITCH; | |||
ph_alphabet[len+1] = phontab_1; | |||
ph_alphabet[len+2] = 0; | |||
} | |||
} | |||
} | |||
} | |||
// caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number | |||
if (ph_buf[0] == 0) { | |||
if ((al_offset != 0) && (al_offset == translator->langopts.alt_alphabet)) | |||
language = translator->langopts.alt_alphabet_lang; | |||
else if ((alphabet != NULL) && (alphabet->language != 0) && !(al_flags & AL_NOT_LETTERS)) | |||
language = alphabet->language; | |||
else | |||
language = L('e', 'n'); | |||
if ((language != tr->translator_name) || (language == L('k', 'o'))) { | |||
char *p3; | |||
int initial, code; | |||
char hangul_buf[12]; | |||
// speak in the language for this alphabet (or English) | |||
ph_buf[2] = SetTranslator3(WordToString2(language)); | |||
if (translator3 != NULL) { | |||
if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) { | |||
// Special case for Korean letters. | |||
// break a syllable hangul into 2 or 3 individual jamo | |||
hangul_buf[0] = ' '; | |||
p3 = &hangul_buf[1]; | |||
if ((initial = (code/28)/21) != 11) { | |||
p3 += utf8_out(initial + 0x1100, p3); | |||
} | |||
utf8_out(((code/28) % 21) + 0x1161, p3); // medial | |||
utf8_out((code % 28) + 0x11a7, &p3[3]); // final | |||
p3[6] = ' '; | |||
p3[7] = 0; | |||
ph_buf[3] = 0; | |||
TranslateRules(translator3, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL); | |||
SetWordStress(translator3, &ph_buf[3], NULL, -1, 0); | |||
} else | |||
LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
if (ph_buf[3] == phonSWITCH) { | |||
// another level of language change | |||
ph_buf[2] = SetTranslator3(&ph_buf[4]); | |||
LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
} | |||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table | |||
if (ph_buf[3] != 0) { | |||
ph_buf[0] = phonPAUSE; | |||
ph_buf[1] = phonSWITCH; | |||
len = strlen(&ph_buf[3]) + 3; | |||
ph_buf[len] = phonSWITCH; // switch back | |||
ph_buf[len+1] = tr->phoneme_tab_ix; | |||
ph_buf[len+2] = 0; | |||
} | |||
} | |||
} | |||
} | |||
if (ph_buf[0] == 0) { | |||
// character name not found | |||
if (ph_buf[0] == 0) { | |||
speak_letter_number = 1; | |||
if (!(al_flags & AL_NO_SYMBOL)) { | |||
if (iswalpha(letter)) | |||
Lookup(translator, "_?A", ph_buf); | |||
if ((ph_buf[0] == 0) && !iswspace(letter)) | |||
Lookup(translator, "_??", ph_buf); | |||
if (ph_buf[0] == 0) | |||
EncodePhonemes("l'et@", ph_buf, NULL); | |||
} | |||
if (!(control & 4) && (al_flags & AL_NOT_CODE)) { | |||
// don't speak the character code number, unless we want full details of this character | |||
speak_letter_number = 0; | |||
} | |||
if (speak_letter_number) { | |||
if (al_offset == 0x2800) { | |||
// braille dots symbol, list the numbered dots | |||
p2 = hexbuf; | |||
for (ix = 0; ix < 8; ix++) { | |||
if (letter & (1 << ix)) | |||
*p2++ = '1'+ix; | |||
} | |||
*p2 = 0; | |||
} else { | |||
// speak the hexadecimal number of the character code | |||
sprintf(hexbuf, "%x", letter); | |||
} | |||
pbuf = ph_buf; | |||
for (p2 = hexbuf; *p2 != 0; p2++) { | |||
pbuf += strlen(pbuf); | |||
*pbuf++ = phonPAUSE_VSHORT; | |||
LookupLetter(translator, *p2, 0, pbuf, 1); | |||
if (((pbuf[0] == 0) || (pbuf[0] == phonSWITCH)) && (*p2 >= 'a')) { | |||
// This language has no translation for 'a' to 'f', speak English names using base phonemes | |||
EncodePhonemes(hex_letters[*p2 - 'a'], pbuf, NULL); | |||
} | |||
} | |||
strcat(pbuf, pause_string); | |||
} | |||
} | |||
} | |||
len = strlen(phonemes); | |||
if (tr->langopts.accents & 2) // 'capital' before or after the word ? | |||
sprintf(ph_buf2, "%c%s%s%s", 0xff, ph_alphabet, ph_buf, capital); | |||
else | |||
sprintf(ph_buf2, "%c%s%s%s", 0xff, ph_alphabet, capital, ph_buf); // the 0xff marker will be removed or replaced in SetSpellingStress() | |||
if ((len + strlen(ph_buf2)) < N_WORD_PHONEMES) | |||
strcpy(&phonemes[len], ph_buf2); | |||
return n_bytes; | |||
} | |||
void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars) | |||
{ | |||
// Individual letter names, reduce the stress of some. |
@@ -34,7 +34,6 @@ int IsSuperscript(int letter); | |||
void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars); | |||
int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab); | |||
int TranslateNumber(Translator *tr, char *word1, char *ph_out, unsigned int *flags, WORD_TAB *wtab, int control); | |||
int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALPHABET *current_alphabet); | |||
#ifdef __cplusplus |
@@ -34,7 +34,7 @@ | |||
#include "translate.h" | |||
#include "dictionary.h" // for TranslateRules, LookupDictList, Cha... | |||
#include "numbers.h" // for SetSpellingStress, TranslateLetter | |||
#include "numbers.h" // for SetSpellingStress | |||
#include "phoneme.h" // for phonSWITCH, PHONEME_TAB, phonPAUSE_... | |||
#include "phonemelist.h" // for MakePhonemeList | |||
#include "readclause.h" // for towlower2, Eof, ReadClause, is_str_... |
@@ -43,6 +43,10 @@ | |||
#include "ucd/ucd.h" // for ucd_toupper | |||
#include "voice.h" // for voice, voice_t | |||
#include "speech.h" // for MAKE_MEM_UNDEFINED | |||
#include "translateword.h" | |||
static int NonAsciiNumber(int letter); | |||
char *SpeakIndividualLetters(Translator *tr, char *word, char *phonemes, int spell_word, ALPHABET *current_alphabet, char word_phonemes[]) | |||
{ | |||
@@ -68,3 +72,272 @@ char *SpeakIndividualLetters(Translator *tr, char *word, char *phonemes, int spe | |||
SetSpellingStress(tr, phonemes, spell_word, posn); | |||
return word; | |||
} | |||
static const char *hex_letters[] = {"'e:j", "b'i:", "s'i:", "d'i:", "'i:", "'ef"}; | |||
static const char *modifiers[] = { NULL, "_sub", "_sup", NULL }; | |||
// unicode ranges for non-ascii digits 0-9 (these must be in ascending order) | |||
static const int number_ranges[] = { | |||
0x660, 0x6f0, // arabic | |||
0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xbe6, 0xc66, 0xce6, 0xd66, // indic | |||
0xe50, 0xed0, 0xf20, 0x1040, 0x1090, | |||
0 | |||
}; | |||
int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALPHABET *current_alphabet) | |||
{ | |||
// get pronunciation for an isolated letter | |||
// return number of bytes used by the letter | |||
// control bit 0: a non-initial letter in a word | |||
// bit 1: say 'capital' | |||
// bit 2: say character code for unknown letters | |||
int n_bytes; | |||
int letter; | |||
int len; | |||
int ix; | |||
int c; | |||
char *p2; | |||
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]; | |||
char ph_buf2[80]; | |||
char ph_alphabet[80]; | |||
char hexbuf[12]; | |||
static const char pause_string[] = { phonPAUSE, 0 }; | |||
ph_buf[0] = 0; | |||
ph_alphabet[0] = 0; | |||
capital[0] = 0; | |||
phontab_1 = translator->phoneme_tab_ix; | |||
n_bytes = utf8_in(&letter, word); | |||
if ((letter & 0xfff00) == 0x0e000) | |||
letter &= 0xff; // uncode private usage area | |||
if (control & 2) { | |||
// include CAPITAL information | |||
if (iswupper(letter)) | |||
Lookup(tr, "_cap", capital); | |||
} | |||
letter = towlower2(letter, tr); | |||
LookupLetter(tr, letter, word[n_bytes], ph_buf, control & 1); | |||
if (ph_buf[0] == 0) { | |||
// is this a subscript or superscript letter ? | |||
if ((c = IsSuperscript(letter)) != 0) { | |||
letter = c & 0x3fff; | |||
if ((control & 4 ) && ((modifier = modifiers[c >> 14]) != NULL)) { | |||
// don't say "superscript" during normal text reading | |||
Lookup(tr, modifier, capital); | |||
if (capital[0] == 0) { | |||
capital[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 | |||
Lookup(translator3, modifier, &capital[3]); | |||
if (capital[3] != 0) { | |||
capital[0] = phonPAUSE; | |||
capital[1] = phonSWITCH; | |||
len = strlen(&capital[3]); | |||
capital[len+3] = phonSWITCH; | |||
capital[len+4] = phontab_1; | |||
capital[len+5] = 0; | |||
} | |||
} | |||
} | |||
} | |||
LookupLetter(tr, letter, word[n_bytes], ph_buf, control & 1); | |||
} | |||
if (ph_buf[0] == phonSWITCH) { | |||
strcpy(phonemes, ph_buf); | |||
return 0; | |||
} | |||
if ((ph_buf[0] == 0) && ((number = NonAsciiNumber(letter)) > 0)) { | |||
// convert a non-ascii number to 0-9 | |||
LookupLetter(tr, number, 0, ph_buf, control & 1); | |||
} | |||
al_offset = 0; | |||
al_flags = 0; | |||
if ((alphabet = AlphabetFromChar(letter)) != NULL) { | |||
al_offset = alphabet->offset; | |||
al_flags = alphabet->flags; | |||
} | |||
if (alphabet != current_alphabet) { | |||
// speak the name of the alphabet | |||
current_alphabet = alphabet; | |||
if ((alphabet != NULL) && !(al_flags & AL_DONT_NAME) && (al_offset != translator->letter_bits_offset)) { | |||
if ((al_flags & AL_DONT_NAME) || (al_offset == translator->langopts.alt_alphabet) || (al_offset == translator->langopts.our_alphabet)) { | |||
// don't say the alphabet name | |||
} else { | |||
ph_buf2[0] = 0; | |||
if (Lookup(translator, alphabet->name, ph_alphabet) == 0) { // the original language for the current voice | |||
// Can't find the local name for this alphabet, use the English name | |||
ph_alphabet[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 | |||
Lookup(translator3, alphabet->name, ph_buf2); | |||
} else if (translator != tr) { | |||
phontab_1 = tr->phoneme_tab_ix; | |||
strcpy(ph_buf2, ph_alphabet); | |||
ph_alphabet[2] = translator->phoneme_tab_ix; | |||
} | |||
if (ph_buf2[0] != 0) { | |||
// we used a different language for the alphabet name (now in ph_buf2) | |||
ph_alphabet[0] = phonPAUSE; | |||
ph_alphabet[1] = phonSWITCH; | |||
strcpy(&ph_alphabet[3], ph_buf2); | |||
len = strlen(ph_buf2) + 3; | |||
ph_alphabet[len] = phonSWITCH; | |||
ph_alphabet[len+1] = phontab_1; | |||
ph_alphabet[len+2] = 0; | |||
} | |||
} | |||
} | |||
} | |||
// caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number | |||
if (ph_buf[0] == 0) { | |||
if ((al_offset != 0) && (al_offset == translator->langopts.alt_alphabet)) | |||
language = translator->langopts.alt_alphabet_lang; | |||
else if ((alphabet != NULL) && (alphabet->language != 0) && !(al_flags & AL_NOT_LETTERS)) | |||
language = alphabet->language; | |||
else | |||
language = L('e', 'n'); | |||
if ((language != tr->translator_name) || (language == L('k', 'o'))) { | |||
char *p3; | |||
int initial, code; | |||
char hangul_buf[12]; | |||
// speak in the language for this alphabet (or English) | |||
ph_buf[2] = SetTranslator3(WordToString2(language)); | |||
if (translator3 != NULL) { | |||
if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) { | |||
// Special case for Korean letters. | |||
// break a syllable hangul into 2 or 3 individual jamo | |||
hangul_buf[0] = ' '; | |||
p3 = &hangul_buf[1]; | |||
if ((initial = (code/28)/21) != 11) { | |||
p3 += utf8_out(initial + 0x1100, p3); | |||
} | |||
utf8_out(((code/28) % 21) + 0x1161, p3); // medial | |||
utf8_out((code % 28) + 0x11a7, &p3[3]); // final | |||
p3[6] = ' '; | |||
p3[7] = 0; | |||
ph_buf[3] = 0; | |||
TranslateRules(translator3, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL); | |||
SetWordStress(translator3, &ph_buf[3], NULL, -1, 0); | |||
} else | |||
LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
if (ph_buf[3] == phonSWITCH) { | |||
// another level of language change | |||
ph_buf[2] = SetTranslator3(&ph_buf[4]); | |||
LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
} | |||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table | |||
if (ph_buf[3] != 0) { | |||
ph_buf[0] = phonPAUSE; | |||
ph_buf[1] = phonSWITCH; | |||
len = strlen(&ph_buf[3]) + 3; | |||
ph_buf[len] = phonSWITCH; // switch back | |||
ph_buf[len+1] = tr->phoneme_tab_ix; | |||
ph_buf[len+2] = 0; | |||
} | |||
} | |||
} | |||
} | |||
if (ph_buf[0] == 0) { | |||
// character name not found | |||
if (ph_buf[0] == 0) { | |||
speak_letter_number = 1; | |||
if (!(al_flags & AL_NO_SYMBOL)) { | |||
if (iswalpha(letter)) | |||
Lookup(translator, "_?A", ph_buf); | |||
if ((ph_buf[0] == 0) && !iswspace(letter)) | |||
Lookup(translator, "_??", ph_buf); | |||
if (ph_buf[0] == 0) | |||
EncodePhonemes("l'et@", ph_buf, NULL); | |||
} | |||
if (!(control & 4) && (al_flags & AL_NOT_CODE)) { | |||
// don't speak the character code number, unless we want full details of this character | |||
speak_letter_number = 0; | |||
} | |||
if (speak_letter_number) { | |||
if (al_offset == 0x2800) { | |||
// braille dots symbol, list the numbered dots | |||
p2 = hexbuf; | |||
for (ix = 0; ix < 8; ix++) { | |||
if (letter & (1 << ix)) | |||
*p2++ = '1'+ix; | |||
} | |||
*p2 = 0; | |||
} else { | |||
// speak the hexadecimal number of the character code | |||
sprintf(hexbuf, "%x", letter); | |||
} | |||
pbuf = ph_buf; | |||
for (p2 = hexbuf; *p2 != 0; p2++) { | |||
pbuf += strlen(pbuf); | |||
*pbuf++ = phonPAUSE_VSHORT; | |||
LookupLetter(translator, *p2, 0, pbuf, 1); | |||
if (((pbuf[0] == 0) || (pbuf[0] == phonSWITCH)) && (*p2 >= 'a')) { | |||
// This language has no translation for 'a' to 'f', speak English names using base phonemes | |||
EncodePhonemes(hex_letters[*p2 - 'a'], pbuf, NULL); | |||
} | |||
} | |||
strcat(pbuf, pause_string); | |||
} | |||
} | |||
} | |||
len = strlen(phonemes); | |||
if (tr->langopts.accents & 2) // 'capital' before or after the word ? | |||
sprintf(ph_buf2, "%c%s%s%s", 0xff, ph_alphabet, ph_buf, capital); | |||
else | |||
sprintf(ph_buf2, "%c%s%s%s", 0xff, ph_alphabet, capital, ph_buf); // the 0xff marker will be removed or replaced in SetSpellingStress() | |||
if ((len + strlen(ph_buf2)) < N_WORD_PHONEMES) | |||
strcpy(&phonemes[len], ph_buf2); | |||
return n_bytes; | |||
} | |||
static int NonAsciiNumber(int letter) | |||
{ | |||
// Change non-ascii digit into ascii digit '0' to '9', (or -1 if not) | |||
const int *p; | |||
int base; | |||
for (p = number_ranges; (base = *p) != 0; p++) { | |||
if (letter < base) | |||
break; // not found | |||
if (letter < (base+10)) | |||
return letter-base+'0'; | |||
} | |||
return -1; | |||
} |
@@ -31,7 +31,7 @@ extern "C" | |||
#endif | |||
char *SpeakIndividualLetters(Translator *tr, char *word, char *phonemes, int spell_word, ALPHABET *current_alphabet, char word_phonemes[]); | |||
int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALPHABET *current_alphabet); | |||
#ifdef __cplusplus | |||
} | |||
#endif |