| int pt; | int pt; | ||||
| int y; | int y; | ||||
| int freq1 = 0; | int freq1 = 0; | ||||
| int freq2; | |||||
| int height1 = tone_pts[1]; | int height1 = tone_pts[1]; | ||||
| int height2; | |||||
| for (pt = 0; pt < 12; pt += 2) { | for (pt = 0; pt < 12; pt += 2) { | ||||
| if (tone_pts[pt] == -1) { | if (tone_pts[pt] == -1) { | ||||
| if (pt > 0) | if (pt > 0) | ||||
| tone_pts[pt+1] = tone_pts[pt-1]; | tone_pts[pt+1] = tone_pts[pt-1]; | ||||
| } | } | ||||
| int freq2; | |||||
| int height2; | |||||
| freq2 = tone_pts[pt] / 8; // 8Hz steps | freq2 = tone_pts[pt] / 8; // 8Hz steps | ||||
| height2 = tone_pts[pt+1]; | height2 = tone_pts[pt+1]; | ||||
| if ((freq2 - freq1) > 0) { | if ((freq2 - freq1) > 0) { | ||||
| // store them as flags in *flags | // store them as flags in *flags | ||||
| // the meaning of the numbers is bit ordinals, not integer values | // the meaning of the numbers is bit ordinals, not integer values | ||||
| // give an error if number > maxValue is read | // give an error if number > maxValue is read | ||||
| int n; | |||||
| while (*p != 0) { | while (*p != 0) { | ||||
| while (isspace(*p)) p++; | while (isspace(*p)) p++; | ||||
| int n; | |||||
| if ((n = atoi(p)) > 0) { | if ((n = atoi(p)) > 0) { | ||||
| p++; | p++; | ||||
| if (n < maxValue) { | if (n < maxValue) { | ||||
| char phonemes_name[40] = ""; | char phonemes_name[40] = ""; | ||||
| const char *language_type; | const char *language_type; | ||||
| char buf[sizeof(path_home)+30]; | char buf[sizeof(path_home)+30]; | ||||
| char path_voices[sizeof(path_home)+12]; | |||||
| char name1[40]; | char name1[40]; | ||||
| char name2[80]; | char name2[80]; | ||||
| if (voicename[0] == 0 && !(control & 8)/*compiling phonemes*/) | if (voicename[0] == 0 && !(control & 8)/*compiling phonemes*/) | ||||
| strcpy(voicename, ESPEAKNG_DEFAULT_VOICE); | strcpy(voicename, ESPEAKNG_DEFAULT_VOICE); | ||||
| char path_voices[sizeof(path_home)+12]; | |||||
| sprintf(path_voices, "%s%cvoices%c", path_home, PATHSEP, PATHSEP); | sprintf(path_voices, "%s%cvoices%c", path_home, PATHSEP, PATHSEP); | ||||
| sprintf(buf, "%s%s", path_voices, voicename); // look in the main voices directory | sprintf(buf, "%s%s", path_voices, voicename); // look in the main voices directory | ||||
| // Remove any voice variant suffix (name or number) from a voice name | // Remove any voice variant suffix (name or number) from a voice name | ||||
| // Returns the voice variant name | // Returns the voice variant name | ||||
| char *p; | |||||
| static char variant_name[40]; | static char variant_name[40]; | ||||
| char variant_prefix[5]; | char variant_prefix[5]; | ||||
| variant_prefix[0] = 0; | variant_prefix[0] = 0; | ||||
| if (vname != NULL) { | if (vname != NULL) { | ||||
| char *p; | |||||
| if ((p = strchr(vname, '+')) != NULL) { | if ((p = strchr(vname, '+')) != NULL) { | ||||
| // The voice name has a +variant suffix | // The voice name has a +variant suffix | ||||
| variant_num = 0; | variant_num = 0; | ||||
| static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, 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; | |||||
| const char *p; | const char *p; | ||||
| int c1, c2; | |||||
| int language_priority; | |||||
| int n_parts; | |||||
| int matching; | |||||
| int matching_parts; | |||||
| int score = 0; | int score = 0; | ||||
| int x; | int x; | ||||
| int ratio; | |||||
| int required_age; | |||||
| int diff; | |||||
| p = voice->languages; // list of languages+dialects for which this voice is suitable | p = voice->languages; // list of languages+dialects for which this voice is suitable | ||||
| // compare the required language with each of the languages of this voice | // compare the required language with each of the languages of this voice | ||||
| while (*p != 0) { | while (*p != 0) { | ||||
| language_priority = *p++; | |||||
| int language_priority = *p++; | |||||
| matching = 1; | |||||
| matching_parts = 0; | |||||
| n_parts = 1; | |||||
| int n_parts = 1; | |||||
| int matching = 1; | |||||
| int matching_parts = 0; | |||||
| int ix; | |||||
| for (ix = 0;; ix++) { | for (ix = 0;; ix++) { | ||||
| int c1, c2; | |||||
| if ((ix >= spec_lang_len) || ((c1 = spec_language[ix]) == '-')) | if ((ix >= spec_lang_len) || ((c1 = spec_language[ix]) == '-')) | ||||
| c1 = 0; | c1 = 0; | ||||
| if ((c2 = p[ix]) == '-') | if ((c2 = p[ix]) == '-') | ||||
| x = 5; | x = 5; | ||||
| // reduce the score if not all parts of the required language match | // reduce the score if not all parts of the required language match | ||||
| int diff; | |||||
| if ((diff = (spec_n_parts - matching_parts)) > 0) | if ((diff = (spec_n_parts - matching_parts)) > 0) | ||||
| x -= diff; | x -= diff; | ||||
| score += 5; // give some preference for non-child female voice if a child is requested | score += 5; // give some preference for non-child female voice if a child is requested | ||||
| if (voice->age != 0) { | if (voice->age != 0) { | ||||
| int required_age; | |||||
| if (voice_spec->age == 0) | if (voice_spec->age == 0) | ||||
| required_age = 30; | required_age = 30; | ||||
| else | else | ||||
| required_age = voice_spec->age; | required_age = voice_spec->age; | ||||
| int ratio; | |||||
| ratio = (required_age*100)/voice->age; | ratio = (required_age*100)/voice->age; | ||||
| if (ratio < 100) | if (ratio < 100) | ||||
| ratio = 10000/ratio; | ratio = 10000/ratio; | ||||
| int lang_len = 0; | int lang_len = 0; | ||||
| espeak_VOICE *vp; | espeak_VOICE *vp; | ||||
| char language[80]; | char language[80]; | ||||
| char buf[sizeof(path_home)+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)) { | ||||
| lang_len = 2; | lang_len = 2; | ||||
| } | } | ||||
| char buf[sizeof(path_home)+80]; | |||||
| sprintf(buf, "%s/voices/%s", path_home, language); | sprintf(buf, "%s/voices/%s", path_home, language); | ||||
| if (GetFileLength(buf) == -EISDIR) { | if (GetFileLength(buf) == -EISDIR) { | ||||
| // A subdirectory name has been specified. List all the voices in that subdirectory | // A subdirectory name has been specified. List all the voices in that subdirectory | ||||
| { | { | ||||
| char path_voices[sizeof(path_home)+12]; | char path_voices[sizeof(path_home)+12]; | ||||
| int ix; | |||||
| int j; | |||||
| espeak_VOICE *v; | espeak_VOICE *v; | ||||
| static espeak_VOICE **voices = NULL; | static espeak_VOICE **voices = NULL; | ||||
| SetVoiceScores(voice_spec, voices, 1); | SetVoiceScores(voice_spec, voices, 1); | ||||
| } else { | } else { | ||||
| // list all: omit variant and mbrola voices | // list all: omit variant and mbrola voices | ||||
| int ix; | |||||
| int j; | |||||
| j = 0; | j = 0; | ||||
| for (ix = 0; (v = voices_list[ix]) != NULL; ix++) { | for (ix = 0; (v = voices_list[ix]) != NULL; ix++) { | ||||
| if ((v->languages[0] != 0) && (strcmp(&v->languages[1], "variant") != 0) | if ((v->languages[0] != 0) && (strcmp(&v->languages[1], "variant") != 0) |