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; |