git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@63 d46cf337-b52f-0410-862d-fd96e6ae7743master
| _) t (_ te | _) t (_ te | ||||
| t t // bataille | t t // bataille | ||||
| t (_ t2 // silent at end of word unless next word starts with a vowel | t (_ t2 // silent at end of word unless next word starts with a vowel | ||||
| ts (_ z2 // silent at end of word unless next word starts with a vowel | |||||
| ts (_S1 z2 // silent at end of word unless next word starts with a vowel | |||||
| C) t (_ t // compost watt soft script malttact abrupt | C) t (_ t // compost watt soft script malttact abrupt | ||||
| n) t (_ t2 // emprunt | n) t (_ t2 // emprunt | ||||
| r) t (_ t2 // fort | r) t (_ t2 // fort |
| espeak_VOICE voice; | espeak_VOICE voice; | ||||
| memset(&voice, 0, sizeof(espeak_VOICE)); | memset(&voice, 0, sizeof(espeak_VOICE)); | ||||
| voice.languages = "en"; | |||||
| //voice.gender = 2; | |||||
| voice.age = 4; | |||||
| // voice.name = "default"; | |||||
| // voice.languages = "en"; | |||||
| voice.gender = 2; | |||||
| // voice.age = 4; | |||||
| result = espeak_SetVoiceByProperties(&voice); | result = espeak_SetVoiceByProperties(&voice); | ||||
| assert(result == EE_OK); | assert(result == EE_OK); |
| voice_select.age = ssml_stack[0].voice_age; | voice_select.age = ssml_stack[0].voice_age; | ||||
| voice_select.gender = ssml_stack[0].voice_gender; | voice_select.gender = ssml_stack[0].voice_gender; | ||||
| voice_select.variant = ssml_stack[0].voice_variant; | voice_select.variant = ssml_stack[0].voice_variant; | ||||
| voice_select.name = voice_name; | |||||
| voice_select.languages = language; | |||||
| voice_select.identifier = NULL; | voice_select.identifier = NULL; | ||||
| for(ix=0; ix<n_ssml_stack; ix++) | for(ix=0; ix<n_ssml_stack; ix++) | ||||
| { | { | ||||
| sp = &ssml_stack[ix]; | sp = &ssml_stack[ix]; | ||||
| // if(sp->voice_name[0] != 0) | |||||
| strcpy(voice_name, sp->voice_name); // don't inherit name from previous levels ?? | |||||
| if(sp->voice_name[0] != 0) | |||||
| { | |||||
| strcpy(voice_name, sp->voice_name); | |||||
| language[0] = 0; | |||||
| voice_select.gender = 0; | |||||
| voice_select.age = 0; | |||||
| voice_select.variant = 0; | |||||
| } | |||||
| if(sp->language[0] != 0) | if(sp->language[0] != 0) | ||||
| strcpy(language, sp->language); | strcpy(language, sp->language); | ||||
| if(sp->voice_gender != 0) | if(sp->voice_gender != 0) | ||||
| voice_select.variant = sp->voice_variant; | voice_select.variant = sp->voice_variant; | ||||
| } | } | ||||
| voice_select.name = voice_name; | |||||
| voice_select.languages = language; | |||||
| v = SelectVoice(&voice_select,&variant); | v = SelectVoice(&voice_select,&variant); | ||||
| *voice_variant = variant; | *voice_variant = variant; | ||||
| if((v == NULL) || (v->identifier == NULL)) | if((v == NULL) || (v->identifier == NULL)) | ||||
| void InitText2(void) | void InitText2(void) | ||||
| {//================= | {//================= | ||||
| int param; | int param; | ||||
| espeak_VOICE *pvoice; | |||||
| n_ssml_stack =1; | n_ssml_stack =1; | ||||
| n_param_stack = 1; | n_param_stack = 1; | ||||
| option_punctuation = speech_parameters[espeakPUNCTUATION]; | option_punctuation = speech_parameters[espeakPUNCTUATION]; | ||||
| option_capitals = speech_parameters[espeakCAPITALS]; | option_capitals = speech_parameters[espeakCAPITALS]; | ||||
| //#ifdef deleted | |||||
| pvoice = espeak_GetCurrentVoice(); | |||||
| ssml_sp = &ssml_stack[0]; | |||||
| ssml_sp->tag_type = 0; | |||||
| ssml_sp->voice_variant = 0; | |||||
| ssml_sp->voice_gender = 0; | |||||
| ssml_sp->voice_age = 0; | |||||
| if(pvoice != NULL) | |||||
| { | |||||
| strncpy0(ssml_sp->voice_name,pvoice->name,sizeof(ssml_sp->voice_name)); | |||||
| strncpy0(ssml_sp->language,&pvoice->languages[1],sizeof(ssml_sp->language)); | |||||
| } | |||||
| //#endif | |||||
| current_voice_id[0] = 0; | current_voice_id[0] = 0; | ||||
| n_param_stack = 1; | |||||
| ignore_text = 0; | ignore_text = 0; | ||||
| clear_skipping_text = 0; | clear_skipping_text = 0; | ||||
| count_characters = -1; | count_characters = -1; |
| #include "translate.h" | #include "translate.h" | ||||
| #include "wave.h" | #include "wave.h" | ||||
| const char *version_string = "1.27.07 09.Jul.07"; | |||||
| const char *version_string = "1.27.08 09.Jul.07"; | |||||
| const int version_phdata = 0x012701; | const int version_phdata = 0x012701; | ||||
| int option_device_number = -1; | int option_device_number = -1; |
| static void DoVoice(voice_t *v) | static void DoVoice(voice_t *v) | ||||
| {//============================ | {//============================ | ||||
| // allocate memory for a copy of the voice data, and free it in wavegenfill() | |||||
| voice_t *v2; | |||||
| v2 = (voice_t *)malloc(sizeof(voice_t)); | |||||
| memcpy(v2,v,sizeof(voice_t)); | |||||
| wcmdq[wcmdq_tail][0] = WCMD_VOICE; | wcmdq[wcmdq_tail][0] = WCMD_VOICE; | ||||
| wcmdq[wcmdq_tail][1] = (long)v; | |||||
| wcmdq[wcmdq_tail][1] = (long)(v2); | |||||
| WcmdqInc(); | WcmdqInc(); | ||||
| } | } | ||||
| if(!found & ((word_flags & FLAG_UPPERS) != FLAG_FIRST_UPPER)) | if(!found & ((word_flags & FLAG_UPPERS) != FLAG_FIRST_UPPER)) | ||||
| { | { | ||||
| // either all upper or all lower case | // either all upper or all lower case | ||||
| found = TranslateRoman(word,phonemes); | |||||
| if((found = TranslateRoman(word,phonemes)) != 0) | |||||
| dictionary_flags |= FLAG_ABBREV; // don't spell capital Roman numbers as individual letters | |||||
| } | } | ||||
| if(!found && (wflags & FLAG_ALL_UPPER) && (clause_upper_count <= clause_lower_count) && | |||||
| if((wflags & FLAG_ALL_UPPER) && (clause_upper_count <= clause_lower_count) && | |||||
| !(dictionary_flags & (FLAG_ABBREV | FLAG_SKIPWORDS)) && (word_length>1) && (word_length<4) && iswalpha(first_char)) | !(dictionary_flags & (FLAG_ABBREV | FLAG_SKIPWORDS)) && (word_length>1) && (word_length<4) && iswalpha(first_char)) | ||||
| { | { | ||||
| // An upper case word in a lower case clause. This could be an abbreviation. | // An upper case word in a lower case clause. This could be an abbreviation. |
| int formant_factor; // adjust nominal formant frequencies by this because of the voice's pitch (256ths) | int formant_factor; // adjust nominal formant frequencies by this because of the voice's pitch (256ths) | ||||
| // parameters used by Wavegen | // parameters used by Wavegen | ||||
| int freq[N_PEAKS]; // 100% = 256 | |||||
| int height[N_PEAKS]; // 100% = 256 | |||||
| int width[N_PEAKS]; // 100% = 256 | |||||
| short freq[N_PEAKS]; // 100% = 256 | |||||
| short height[N_PEAKS]; // 100% = 256 | |||||
| short width[N_PEAKS]; // 100% = 256 | |||||
| // copies without temporary adjustments from embedded commands | // copies without temporary adjustments from embedded commands | ||||
| int freq2[N_PEAKS]; // 100% = 256 | |||||
| int height2[N_PEAKS]; // 100% = 256 | |||||
| int width2[N_PEAKS]; // 100% = 256 | |||||
| short freq2[N_PEAKS]; // 100% = 256 | |||||
| short height2[N_PEAKS]; // 100% = 256 | |||||
| short width2[N_PEAKS]; // 100% = 256 | |||||
| int breath[N_PEAKS]; // amount of breath for each formant. breath[0] indicates whether any are set. | int breath[N_PEAKS]; // amount of breath for each formant. breath[0] indicates whether any are set. | ||||
| int breathw[N_PEAKS]; // width of each breath formant | int breathw[N_PEAKS]; // width of each breath formant |
| const char *p, *p_start; | const char *p, *p_start; | ||||
| espeak_VOICE *vp = NULL; | espeak_VOICE *vp = NULL; | ||||
| espeak_VOICE *vp2; | espeak_VOICE *vp2; | ||||
| espeak_VOICE voice_select2; | |||||
| espeak_VOICE *voices[N_VOICES_LIST]; // list of candidates | espeak_VOICE *voices[N_VOICES_LIST]; // list of candidates | ||||
| espeak_VOICE *voices2[N_VOICES_LIST+N_VOICE_VARIANTS]; | espeak_VOICE *voices2[N_VOICES_LIST+N_VOICE_VARIANTS]; | ||||
| static espeak_VOICE voice_variants[N_VOICE_VARIANTS]; | static espeak_VOICE voice_variants[N_VOICE_VARIANTS]; | ||||
| memcpy(&voice_select2,voice_select,sizeof(voice_select2)); | |||||
| if(n_voices_list == 0) | if(n_voices_list == 0) | ||||
| espeak_ListVoices(NULL); // create the voices list | espeak_ListVoices(NULL); // create the voices list | ||||
| if((voice_select2.languages == NULL) || (voice_select2.languages[0] == 0)) | |||||
| { | |||||
| // no language is specified. Get language from the named voice | |||||
| int var; | |||||
| char *p2; | |||||
| static char buf[60]; | |||||
| if(voice_select2.name == NULL) | |||||
| { | |||||
| if((voice_select2.name = voice_select2.identifier) == NULL) | |||||
| voice_select2.name = "default"; | |||||
| } | |||||
| strncpy0(buf,voice_select2.name,sizeof(buf)); | |||||
| if((p2 = strchr(buf,'+')) != NULL) | |||||
| { | |||||
| // remove the voice variant suffix, from eg. en+3 | |||||
| *p2 = 0; | |||||
| var = atoi(p2+1); | |||||
| } | |||||
| vp = SelectVoiceByName(voices_list,buf); | |||||
| if(vp != NULL) | |||||
| { | |||||
| voice_select2.languages = &(vp->languages[1]); | |||||
| if((voice_select2.gender==0) && (voice_select2.age==0) && (voice_select2.variant==0)) | |||||
| { | |||||
| *variant = var; | |||||
| return(vp); | |||||
| } | |||||
| } | |||||
| } | |||||
| // select and sort voices for the required language | // select and sort voices for the required language | ||||
| nv = SetVoiceScores(voice_select,voices,0); | |||||
| nv = SetVoiceScores(&voice_select2,voices,0); | |||||
| if(nv == 0) | if(nv == 0) | ||||
| { | { | ||||
| } | } | ||||
| gender = 0; | gender = 0; | ||||
| if((voice_select->gender == 2) || ((voice_select->age > 0) && (voice_select->age < 13))) | |||||
| if((voice_select2.gender == 2) || ((voice_select2.age > 0) && (voice_select2.age < 13))) | |||||
| gender = 2; | gender = 2; | ||||
| else | else | ||||
| if(voice_select->gender == 1) | |||||
| if(voice_select2.gender == 1) | |||||
| gender = 1; | gender = 1; | ||||
| #define AGE_OLD 60 | #define AGE_OLD 60 | ||||
| if(voice_select->age < AGE_OLD) | |||||
| if(voice_select2.age < AGE_OLD) | |||||
| aged = 0; | aged = 0; | ||||
| p = p_start = variant_lists[gender]; | p = p_start = variant_lists[gender]; | ||||
| } | } | ||||
| // index the sorted list by the required variant number | // index the sorted list by the required variant number | ||||
| vp = voices2[voice_select->variant % ix2]; | |||||
| vp = voices2[voice_select2.variant % ix2]; | |||||
| *variant = vp->variant; | *variant = vp->variant; | ||||
| return(vp); | return(vp); | ||||
| } // end of SelectVoice | } // end of SelectVoice | ||||
| } | } | ||||
| memset(&voice_selector,0,sizeof(voice_selector)); | memset(&voice_selector,0,sizeof(voice_selector)); | ||||
| voice_selector.variant = variant; | |||||
| voice_selector.name = (char *)name; | voice_selector.name = (char *)name; | ||||
| // first check for a voice with this filename | // first check for a voice with this filename |
| int WavegenFill(int fill_zeros); | int WavegenFill(int fill_zeros); | ||||
| #ifdef LOG_FRAMES | |||||
| static void LogMarker(int type, int value) | |||||
| {//======================================= | |||||
| if(option_log_frames == 0) | |||||
| return; | |||||
| if((type == espeakEVENT_PHONEME) || (type == espeakEVENT_SENTENCE)) | |||||
| { | |||||
| f_log=fopen("log-espeakedit","a"); | |||||
| if(f_log) | |||||
| { | |||||
| if(type == espeakEVENT_PHONEME) | |||||
| fprintf(f_log,"Phoneme [%s]\n",WordToString(value)); | |||||
| else | |||||
| fprintf(f_log,"\n"); | |||||
| fclose(f_log); | |||||
| f_log = NULL; | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | |||||
| void WcmdqStop() | void WcmdqStop() | ||||
| {//============= | {//============= | ||||
| wcmdq_head = 0; | wcmdq_head = 0; | ||||
| void WavegenSetVoice(voice_t *v) | void WavegenSetVoice(voice_t *v) | ||||
| {//============================= | {//============================= | ||||
| wvoice = v; | |||||
| static voice_t v2; | |||||
| memcpy(&v2,v,sizeof(v2)); | |||||
| wvoice = &v2; | |||||
| if(v->peak_shape==0) | if(v->peak_shape==0) | ||||
| pk_shape = pk_shape1; | pk_shape = pk_shape1; | ||||
| } // end of SetSynth | } // end of SetSynth | ||||
| #ifdef LOG_FRAMES | |||||
| static void LogMarker(int type, int value) | |||||
| {//======================================= | |||||
| if(option_log_frames == 0) | |||||
| return; | |||||
| if((type == espeakEVENT_PHONEME) || (type == espeakEVENT_SENTENCE)) | |||||
| { | |||||
| f_log=fopen("log-espeakedit","a"); | |||||
| if(f_log) | |||||
| { | |||||
| if(type == espeakEVENT_PHONEME) | |||||
| fprintf(f_log,"Phoneme [%s]\n",WordToString(value)); | |||||
| else | |||||
| fprintf(f_log,"\n"); | |||||
| fclose(f_log); | |||||
| f_log = NULL; | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | |||||
| static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2) | static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2) | ||||
| {//==================================================================================== | {//==================================================================================== | ||||
| if(resume==0) | if(resume==0) | ||||
| case WCMD_VOICE: | case WCMD_VOICE: | ||||
| WavegenSetVoice((voice_t *)q[1]); | WavegenSetVoice((voice_t *)q[1]); | ||||
| free((voice_t *)q[1]); | |||||
| break; | break; | ||||
| case WCMD_EMBEDDED: | case WCMD_EMBEDDED: |