From 3546b199659c8ffa4cad7b0c6166c1eb377dc7c0 Mon Sep 17 00:00:00 2001 From: jonsd Date: Tue, 10 Jul 2007 16:10:26 +0000 Subject: [PATCH] [1.27.08] Fix to inheriting voice attributes over and tags. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@63 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/fr_rules | 2 +- src/extras.cpp | 7 ++++--- src/readclause.cpp | 30 +++++++++------------------ src/synthdata.cpp | 2 +- src/synthesize.cpp | 7 ++++++- src/translate.cpp | 5 +++-- src/voice.h | 12 +++++------ src/voices.cpp | 48 ++++++++++++++++++++++++++++++++++++------- src/wavegen.cpp | 50 ++++++++++++++++++++++++--------------------- 9 files changed, 99 insertions(+), 64 deletions(-) diff --git a/dictsource/fr_rules b/dictsource/fr_rules index be096e70..1a177f2a 100755 --- a/dictsource/fr_rules +++ b/dictsource/fr_rules @@ -627,7 +627,7 @@ _) t (_ te t t // bataille 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 n) t (_ t2 // emprunt r) t (_ t2 // fort diff --git a/src/extras.cpp b/src/extras.cpp index 4448a339..3d4422dc 100644 --- a/src/extras.cpp +++ b/src/extras.cpp @@ -1185,9 +1185,10 @@ int test4() { espeak_VOICE 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); assert(result == EE_OK); diff --git a/src/readclause.cpp b/src/readclause.cpp index 79314b12..e80beba9 100644 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -600,16 +600,20 @@ static char *VoiceFromStack(int *voice_variant) voice_select.age = ssml_stack[0].voice_age; voice_select.gender = ssml_stack[0].voice_gender; voice_select.variant = ssml_stack[0].voice_variant; - voice_select.name = voice_name; - voice_select.languages = language; voice_select.identifier = NULL; for(ix=0; ixvoice_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) strcpy(language, sp->language); if(sp->voice_gender != 0) @@ -620,6 +624,8 @@ static char *VoiceFromStack(int *voice_variant) voice_select.variant = sp->voice_variant; } + voice_select.name = voice_name; + voice_select.languages = language; v = SelectVoice(&voice_select,&variant); *voice_variant = variant; if((v == NULL) || (v->identifier == NULL)) @@ -1862,7 +1868,6 @@ void InitNamedata(void) void InitText2(void) {//================= int param; - espeak_VOICE *pvoice; n_ssml_stack =1; n_param_stack = 1; @@ -1873,23 +1878,8 @@ void InitText2(void) option_punctuation = speech_parameters[espeakPUNCTUATION]; 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; - n_param_stack = 1; ignore_text = 0; clear_skipping_text = 0; count_characters = -1; diff --git a/src/synthdata.cpp b/src/synthdata.cpp index e4a61eeb..e84f8402 100755 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,7 +35,7 @@ #include "translate.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; int option_device_number = -1; diff --git a/src/synthesize.cpp b/src/synthesize.cpp index 7048ec1d..938c4d08 100755 --- a/src/synthesize.cpp +++ b/src/synthesize.cpp @@ -1001,8 +1001,13 @@ static void DoMarker(int type, int char_posn, int length, int value) 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][1] = (long)v; + wcmdq[wcmdq_tail][1] = (long)(v2); WcmdqInc(); } diff --git a/src/translate.cpp b/src/translate.cpp index ad20be78..728a5f1e 100755 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -671,10 +671,11 @@ if((wmark > 0) && (wmark < 8)) if(!found & ((word_flags & FLAG_UPPERS) != FLAG_FIRST_UPPER)) { // 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)) { // An upper case word in a lower case clause. This could be an abbreviation. diff --git a/src/voice.h b/src/voice.h index f206de2b..68eb1482 100644 --- a/src/voice.h +++ b/src/voice.h @@ -40,14 +40,14 @@ typedef struct { int formant_factor; // adjust nominal formant frequencies by this because of the voice's pitch (256ths) // 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 - 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 breathw[N_PEAKS]; // width of each breath formant diff --git a/src/voices.cpp b/src/voices.cpp index 52fa61f1..0f485adb 100755 --- a/src/voices.cpp +++ b/src/voices.cpp @@ -1201,16 +1201,51 @@ espeak_VOICE *SelectVoice(espeak_VOICE *voice_select, int *variant) const char *p, *p_start; espeak_VOICE *vp = NULL; espeak_VOICE *vp2; + espeak_VOICE voice_select2; espeak_VOICE *voices[N_VOICES_LIST]; // list of candidates espeak_VOICE *voices2[N_VOICES_LIST+N_VOICE_VARIANTS]; - static espeak_VOICE voice_variants[N_VOICE_VARIANTS]; + memcpy(&voice_select2,voice_select,sizeof(voice_select2)); + if(n_voices_list == 0) 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 - nv = SetVoiceScores(voice_select,voices,0); + nv = SetVoiceScores(&voice_select2,voices,0); if(nv == 0) { @@ -1220,14 +1255,14 @@ espeak_VOICE *SelectVoice(espeak_VOICE *voice_select, int *variant) } 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; else - if(voice_select->gender == 1) + if(voice_select2.gender == 1) gender = 1; #define AGE_OLD 60 - if(voice_select->age < AGE_OLD) + if(voice_select2.age < AGE_OLD) aged = 0; p = p_start = variant_lists[gender]; @@ -1280,7 +1315,7 @@ espeak_VOICE *SelectVoice(espeak_VOICE *voice_select, int *variant) } // index the sorted list by the required variant number - vp = voices2[voice_select->variant % ix2]; + vp = voices2[voice_select2.variant % ix2]; *variant = vp->variant; return(vp); } // end of SelectVoice @@ -1398,7 +1433,6 @@ espeak_ERROR SetVoiceByName(const char *name) } memset(&voice_selector,0,sizeof(voice_selector)); - voice_selector.variant = variant; voice_selector.name = (char *)name; // first check for a voice with this filename diff --git a/src/wavegen.cpp b/src/wavegen.cpp index 6e1c4282..11d11f6b 100755 --- a/src/wavegen.cpp +++ b/src/wavegen.cpp @@ -322,6 +322,28 @@ unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = { 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() {//============= wcmdq_head = 0; @@ -1495,7 +1517,10 @@ void SetEmbedded(int control, int value) void WavegenSetVoice(voice_t *v) {//============================= - wvoice = v; + static voice_t v2; + + memcpy(&v2,v,sizeof(v2)); + wvoice = &v2; if(v->peak_shape==0) pk_shape = pk_shape1; @@ -1684,28 +1709,6 @@ if(option_log_frames) } // 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) {//==================================================================================== if(resume==0) @@ -1894,6 +1897,7 @@ int WavegenFill(int fill_zeros) case WCMD_VOICE: WavegenSetVoice((voice_t *)q[1]); + free((voice_t *)q[1]); break; case WCMD_EMBEDDED: