SSML: <voice>, if a language is specified, forget previously selected voice name. Voice selection, convert language name to lower-case. espeak-data/mbrola_ph files, allow use by both little and big-endian processors. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@149 d46cf337-b52f-0410-862d-fd96e6ae7743master
i i: o O O~ u W w^i | i i: o O O~ u W w^i | ||||
W~ y Y | W~ y Y | ||||
* : ; b c d D dZ | |||||
f g h j k l L m | |||||
n N n2 n^ p p2 r R | |||||
s S t t2 tS v w z | |||||
Z z2 z3 | |||||
* : ; b c d dZ f | |||||
g h j k l L m n | |||||
N n2 n^ p p2 r R s | |||||
S t t2 tS v w z Z | |||||
z2 z3 | |||||
Dictionary hi_dict | Dictionary hi_dict | ||||
Dictionary ku_dict | Dictionary ku_dict | ||||
a e E eI i I o u | |||||
U y | |||||
a e E eI eU i I o | |||||
u U y | |||||
: b d dZ f g h j | : b d dZ f g h j | ||||
k l m n p q r R | k l m n p q r R |
// moving towards US English | // moving towards US English | ||||
name en-rhotic | name en-rhotic | ||||
language en-r | language en-r | ||||
language en-us | |||||
language en 3 | language en 3 | ||||
gender male | gender male | ||||
FILE *f_out; | FILE *f_out; | ||||
int percent; | int percent; | ||||
int n; | int n; | ||||
int *pw; | |||||
int *pw_end; | |||||
int count = 0; | int count = 0; | ||||
int control; | int control; | ||||
char phoneme[40]; | char phoneme[40]; | ||||
} | } | ||||
data[count].name = 0; // list terminator | data[count].name = 0; // list terminator | ||||
fwrite(&mbrola_ctrl,4,1,f_out); | |||||
fwrite(data,sizeof(MBROLA_TAB),count+1,f_out); | |||||
Write4Bytes(f_out, mbrola_ctrl); | |||||
pw_end = (int *)(&data[count+1]); | |||||
for(pw = (int *)data; pw < pw_end; pw++) | |||||
{ | |||||
Write4Bytes(f_out, *pw); | |||||
} | |||||
fclose(f_out); | fclose(f_out); | ||||
wxLogStatus(_T("Mbrola translation file: %d phonemes"),count); | wxLogStatus(_T("Mbrola translation file: %d phonemes"),count); | ||||
} // end of CompileMbrola | } // end of CompileMbrola |
int ix; | int ix; | ||||
SSML_STACK *sp; | SSML_STACK *sp; | ||||
const char *v_id; | const char *v_id; | ||||
int voice_name_specified; | |||||
espeak_VOICE voice_select; | espeak_VOICE voice_select; | ||||
char voice_name[40]; | char voice_name[40]; | ||||
char language[40]; | char language[40]; | ||||
for(ix=0; ix<n_ssml_stack; ix++) | for(ix=0; ix<n_ssml_stack; ix++) | ||||
{ | { | ||||
sp = &ssml_stack[ix]; | sp = &ssml_stack[ix]; | ||||
voice_name_specified = 0; | |||||
if((sp->voice_name[0] != 0) && (SelectVoiceByName(NULL,sp->voice_name) != NULL)) | if((sp->voice_name[0] != 0) && (SelectVoiceByName(NULL,sp->voice_name) != NULL)) | ||||
{ | { | ||||
voice_name_specified = 1; | |||||
strcpy(voice_name, sp->voice_name); | strcpy(voice_name, sp->voice_name); | ||||
language[0] = 0; | language[0] = 0; | ||||
voice_select.gender = 0; | voice_select.gender = 0; | ||||
voice_select.variant = 0; | voice_select.variant = 0; | ||||
} | } | ||||
if(sp->language[0] != 0) | if(sp->language[0] != 0) | ||||
{ | |||||
strcpy(language, sp->language); | strcpy(language, sp->language); | ||||
if(voice_name_specified == 0) | |||||
voice_name[0] = 0; // forget a previous voice name if a language is specified | |||||
} | |||||
if(sp->voice_gender != 0) | if(sp->voice_gender != 0) | ||||
voice_select.gender = sp->voice_gender; | voice_select.gender = sp->voice_gender; | ||||
if(sp->voice_age != 0) | if(sp->voice_age != 0) |
#include "translate.h" | #include "translate.h" | ||||
#include "voice.h" | #include "voice.h" | ||||
extern int Read4Bytes(FILE *f); | |||||
#ifdef USE_MBROLA_LIB | #ifdef USE_MBROLA_LIB | ||||
// Load a phoneme name translation table from espeak-data/mbrola | // Load a phoneme name translation table from espeak-data/mbrola | ||||
int size; | int size; | ||||
int ix; | |||||
int *pw; | |||||
FILE *f_in; | FILE *f_in; | ||||
char path[sizeof(path_home)+15]; | char path[sizeof(path_home)+15]; | ||||
fclose(f_in); | fclose(f_in); | ||||
return(EE_INTERNAL_ERROR); | return(EE_INTERNAL_ERROR); | ||||
} | } | ||||
fread(&mbrola_control,4,1,f_in); | |||||
mbrola_control = Read4Bytes(f_in); | |||||
pw = (int *)mbrola_tab; | |||||
for(ix=4; ix<size; ix+=4) | |||||
{ | |||||
*pw++ = Read4Bytes(f_in); | |||||
} | |||||
fread(mbrola_tab,size,1,f_in); | fread(mbrola_tab,size,1,f_in); | ||||
fclose(f_in); | fclose(f_in); | ||||
#ifdef USE_MBROLA_LIB | #ifdef USE_MBROLA_LIB | ||||
#ifdef PLATFORM_WINDOWS | #ifdef PLATFORM_WINDOWS | ||||
setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0); | setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0); |
#include "translate.h" | #include "translate.h" | ||||
#include "wave.h" | #include "wave.h" | ||||
const char *version_string = "1.31.13 21.Feb.08"; | |||||
const char *version_string = "1.31.14 21.Feb.08"; | |||||
const int version_phdata = 0x013105; | const int version_phdata = 0x013105; | ||||
int option_device_number = -1; | int option_device_number = -1; |
new_c = replace_chars[ix+1]; | new_c = replace_chars[ix+1]; | ||||
break; | break; | ||||
} | } | ||||
if((word >> 16) == (unsigned int)tolower(next_in)) | |||||
if((word >> 16) == (unsigned int)towlower(next_in)) | |||||
{ | { | ||||
new_c = replace_chars[ix+1]; | new_c = replace_chars[ix+1]; | ||||
ignore_next = 1; | ignore_next = 1; | ||||
} | } | ||||
n_ph_list2 += 2; | n_ph_list2 += 2; | ||||
if(count_words == 0) | |||||
{ | |||||
clause_pause = 0; | |||||
} | |||||
if(Eof() && ((word_count == 0) || (option_endpause==0))) | if(Eof() && ((word_count == 0) || (option_endpause==0))) | ||||
{ | { | ||||
clause_pause = 10; | clause_pause = 10; |
} | } | ||||
static int ScoreVoice(espeak_VOICE *voice_spec, int spec_n_parts, int spec_lang_len, espeak_VOICE *voice) | |||||
{//====================================================================================================== | |||||
static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int spec_n_parts, int spec_lang_len, espeak_VOICE *voice) | |||||
{//========================================================================================================================= | |||||
int ix; | int ix; | ||||
const char *p; | const char *p; | ||||
int c1, c2; | int c1, c2; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
if((*p == 0) && (strcmp(voice_spec->languages,"variants")==0)) | |||||
if((*p == 0) && (strcmp(spec_language,"variants")==0)) | |||||
{ | { | ||||
// match on a voice with no languages if the required language is "variants" | // match on a voice with no languages if the required language is "variants" | ||||
score = 100; | score = 100; | ||||
for(ix=0; ; ix++) | for(ix=0; ; ix++) | ||||
{ | { | ||||
if((ix >= spec_lang_len) || ((c1 = voice_spec->languages[ix]) == '-')) | |||||
if((ix >= spec_lang_len) || ((c1 = spec_language[ix]) == '-')) | |||||
c1 = 0; | c1 = 0; | ||||
if((c2 = p[ix]) == '-') | if((c2 = p[ix]) == '-') | ||||
c2 = 0; | c2 = 0; | ||||
int nv; // number of candidates | int nv; // number of candidates | ||||
int n_parts=0; | int n_parts=0; | ||||
int lang_len=0; | int lang_len=0; | ||||
const char *p; | |||||
espeak_VOICE *vp; | espeak_VOICE *vp; | ||||
char language[80]; | |||||
// count number of parts in the specified language | // count number of parts in the specified language | ||||
if((voice_select->languages != NULL) && (voice_select->languages[0] != 0)) | if((voice_select->languages != NULL) && (voice_select->languages[0] != 0)) | ||||
{ | { | ||||
n_parts = 1; | n_parts = 1; | ||||
lang_len = strlen(voice_select->languages); | lang_len = strlen(voice_select->languages); | ||||
for(p = voice_select->languages; *p != 0; p++) | |||||
for(ix=0; (ix<=lang_len) && ((unsigned)ix < sizeof(language)); ix++) | |||||
{ | { | ||||
if(*p == '-') | |||||
if((language[ix] = tolower(voice_select->languages[ix])) == '-') | |||||
n_parts++; | n_parts++; | ||||
} | } | ||||
} | } | ||||
if(((control & 1) == 0) && (memcmp(vp->identifier,"mb/",3) == 0)) | if(((control & 1) == 0) && (memcmp(vp->identifier,"mb/",3) == 0)) | ||||
continue; | continue; | ||||
if((score = ScoreVoice(voice_select, n_parts, lang_len, voices_list[ix])) > 0) | |||||
if((score = ScoreVoice(voice_select, language, n_parts, lang_len, voices_list[ix])) > 0) | |||||
{ | { | ||||
voices[nv++] = vp; | voices[nv++] = vp; | ||||
vp->score = score; | vp->score = score; |