mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
Create langopts.c for language option configuration (#1419)
Loading Voice and Language options is complicated. They are not separated in the code. This PR creates langopts.c for holding language option related configuration. In the future: 1. all new language options should go to langopts.c 2. voice options should have a similar file 3. LoadVoice should know if it's loading a voice or a language.
This commit is contained in:
@@ -165,6 +165,7 @@ src_libespeak_ng_la_SOURCES = \
|
||||
src/libespeak-ng/espeak_api.c \
|
||||
src/libespeak-ng/ieee80.c \
|
||||
src/libespeak-ng/intonation.c \
|
||||
src/libespeak-ng/langopts.c \
|
||||
src/libespeak-ng/mnemonics.c \
|
||||
src/libespeak-ng/numbers.c \
|
||||
src/libespeak-ng/readclause.c \
|
||||
@@ -195,6 +196,7 @@ noinst_HEADERS = \
|
||||
src/libespeak-ng/ieee80.h \
|
||||
src/libespeak-ng/intonation.h \
|
||||
src/libespeak-ng/klatt.h \
|
||||
src/libespeak-ng/langopts.h \
|
||||
src/libespeak-ng/mbrola.h \
|
||||
src/libespeak-ng/mbrowrap.h \
|
||||
src/libespeak-ng/mnemonics.h \
|
||||
|
||||
@@ -30,6 +30,7 @@ ESPEAK_SOURCES := \
|
||||
src/libespeak-ng/ieee80.c \
|
||||
src/libespeak-ng/intonation.c \
|
||||
src/libespeak-ng/klatt.c \
|
||||
src/libespeak-ng/langopts.c \
|
||||
src/libespeak-ng/mnemonics.c \
|
||||
src/libespeak-ng/numbers.c \
|
||||
src/libespeak-ng/phoneme.c \
|
||||
|
||||
@@ -287,9 +287,6 @@ static TONE_NUCLEUS tone_nucleus_table[N_TONE_NUCLEUS_TABLE] = {
|
||||
{ PITCHfall, 70, 18, PITCHfall, 70, 24, NULL, 32, 20, 0 }, // 12 test
|
||||
};
|
||||
|
||||
int n_tunes = 0;
|
||||
TUNE *tunes = NULL;
|
||||
|
||||
#define SECONDARY 3
|
||||
#define PRIMARY 4
|
||||
#define PRIMARY_STRESSED 6
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (C) 2005 to 2015 by Jonathan Duddington
|
||||
* email: jonsd@users.sourceforge.net
|
||||
* Copyright (C) 2015-2017 Reece H. Dunn
|
||||
* Copyright (C) 2022 Juho Hiltunen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see: <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <espeak-ng/espeak_ng.h>
|
||||
#include <espeak-ng/speak_lib.h>
|
||||
#include <espeak-ng/encoding.h>
|
||||
|
||||
#include "langopts.h"
|
||||
#include "mnemonics.h" // for MNEM_TAB
|
||||
#include "translate.h" // for Translator
|
||||
#include "synthdata.h" // for n_tunes, tunes
|
||||
#include "voice.h" // for ReadNumbers, Read8Numbers, ...
|
||||
|
||||
static int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key);
|
||||
static int LookupTune(const char *name);
|
||||
|
||||
extern const MNEM_TAB langopts_tab[];
|
||||
|
||||
void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) {
|
||||
if (CheckTranslator(translator, langopts_tab, key) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ix;
|
||||
int n;
|
||||
|
||||
switch (key) {
|
||||
case V_DICTMIN: {
|
||||
|
||||
|
||||
if (sscanf(keyValue, "%d", &n) == 1)
|
||||
translator->dict_min_size = n;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case V_DICTRULES: { // conditional dictionary rules and list entries
|
||||
ReadNumbers(keyValue, &translator->dict_condition, 32, langopts_tab, key);
|
||||
break;
|
||||
}
|
||||
case V_INTONATION: {
|
||||
sscanf(keyValue, "%d", &option_tone_flags);
|
||||
if ((option_tone_flags & 0xff) != 0) {
|
||||
translator->langopts.intonation_group = option_tone_flags & 0xff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case V_NUMBERS: {
|
||||
// expect a list of numbers
|
||||
while (*keyValue != 0) {
|
||||
while (isspace(*keyValue)) keyValue++;
|
||||
if ((n = atoi(keyValue)) > 0) {
|
||||
keyValue++;
|
||||
if (n < 32) {
|
||||
translator->langopts.numbers |= (1 << n);
|
||||
} else {
|
||||
if (n < 64)
|
||||
translator->langopts.numbers2 |= (1 << (n-32));
|
||||
else
|
||||
fprintf(stderr, "numbers: Bad option number %d\n", n); }
|
||||
}
|
||||
while (isalnum(*keyValue)) keyValue++;
|
||||
}
|
||||
ProcessLanguageOptions(&(translator->langopts));
|
||||
|
||||
break;
|
||||
}
|
||||
case V_LOWERCASE_SENTENCE: {
|
||||
translator->langopts.lowercase_sentence = true;
|
||||
break;
|
||||
}
|
||||
case V_STRESSADD: { // stressAdd
|
||||
int stress_add_set = 0;
|
||||
int stress_add[8];
|
||||
|
||||
stress_add_set = Read8Numbers(keyValue, stress_add);
|
||||
|
||||
for (ix = 0; ix < stress_add_set; ix++) {
|
||||
translator->stress_lengths[ix] += stress_add[ix];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case V_STRESSAMP: {
|
||||
|
||||
int stress_amps_set = 0;
|
||||
int stress_amps[8];
|
||||
|
||||
stress_amps_set = Read8Numbers(keyValue, stress_amps);
|
||||
|
||||
for (ix = 0; ix < stress_amps_set; ix++) {
|
||||
translator->stress_amps[ix] = stress_amps[ix];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case V_STRESSLENGTH: {
|
||||
//printf("parsing: %s", keyValue);
|
||||
int stress_lengths_set = 0;
|
||||
int stress_lengths[8];
|
||||
stress_lengths_set = Read8Numbers(keyValue, stress_lengths);
|
||||
|
||||
for (ix = 0; ix < stress_lengths_set; ix++) {
|
||||
translator->stress_lengths[ix] = stress_lengths[ix];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case V_STRESSOPT: {
|
||||
ReadNumbers(keyValue, &translator->langopts.stress_flags, 32, langopts_tab, key);
|
||||
break;
|
||||
}
|
||||
case V_STRESSRULE: {
|
||||
sscanf(keyValue, "%d %d %d", &translator->langopts.stress_rule,
|
||||
&translator->langopts.unstressed_wd1,
|
||||
&translator->langopts.unstressed_wd2);
|
||||
|
||||
break;
|
||||
}
|
||||
case V_TUNES: {
|
||||
char names[6][40] = { 0, 0, 0, 0, 0, 0 };
|
||||
n = sscanf(keyValue, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]);
|
||||
translator->langopts.intonation_group = 0;
|
||||
|
||||
for (ix = 0; ix < n; ix++) {
|
||||
if (strcmp(names[ix], "NULL") == 0)
|
||||
continue;
|
||||
|
||||
if ((n = LookupTune(names[ix])) < 0)
|
||||
fprintf(stderr, "Unknown tune '%s'\n", names[ix]);
|
||||
else
|
||||
translator->langopts.tunes[ix] = n;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case V_WORDGAP: {
|
||||
sscanf(keyValue, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case V_MAINTAINER:
|
||||
case V_STATUS:
|
||||
break;
|
||||
default: {
|
||||
if ((key & 0xff00) == 0x100) {
|
||||
sscanf(keyValue, "%d", &translator->langopts.param[key &0xff]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int LookupTune(const char *name) {
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < n_tunes; ix++) {
|
||||
if (strcmp(name, tunes[ix].name) == 0)
|
||||
return ix;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key)
|
||||
{
|
||||
// Return 0 if translator is set.
|
||||
// Return 1 and print an error message for specified key if not
|
||||
// used for parsing language options
|
||||
if (tr)
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "Cannot set %s: language not set, or is invalid.\n", LookupMnemName(keyword_tab, key));
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington
|
||||
* email: jonsd@users.sourceforge.net
|
||||
* Copyright (C) 2015 Reece H. Dunn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see: <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ESPEAK_NG_LANGOPTS_H
|
||||
#define ESPEAK_NG_LANGOPTS_H
|
||||
|
||||
#include <espeak-ng/espeak_ng.h>
|
||||
#include "translate.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void LoadLanguageOptions(Translator *translator, int key, char *keyValue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -42,6 +42,9 @@
|
||||
#include "translate.h" // for Translator, LANGUAGE_OPTIONS
|
||||
#include "voice.h" // for ReadTonePoints, tone_points, voice
|
||||
|
||||
int n_tunes = 0;
|
||||
TUNE *tunes = NULL;
|
||||
|
||||
const int version_phdata = 0x014801;
|
||||
|
||||
// copy the current phoneme table into here
|
||||
|
||||
@@ -56,6 +56,9 @@ int PhonemeCode(unsigned int mnem);
|
||||
void SelectPhonemeTable(int number);
|
||||
int SelectPhonemeTableName(const char *name);
|
||||
|
||||
extern int n_tunes;
|
||||
extern TUNE *tunes;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -382,8 +382,7 @@ typedef struct {
|
||||
int spare2; // the struct length should be a multiple of 4 bytes
|
||||
} TUNE;
|
||||
|
||||
extern int n_tunes;
|
||||
extern TUNE *tunes;
|
||||
|
||||
|
||||
// phoneme table
|
||||
extern PHONEME_TAB *phoneme_tab[N_PHONEME_TAB];
|
||||
|
||||
@@ -808,7 +808,7 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->langopts.param[LOPT_IT_DOUBLING] = 1;
|
||||
tr->langopts.long_stop = 130;
|
||||
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_2 | NUM_ORDINAL_DOT;
|
||||
// tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_2 | NUM_ORDINAL_DOT;
|
||||
SetLetterVowel(tr, 'y');
|
||||
tr->langopts.spelling_stress = 1;
|
||||
tr->langopts.intonation_group = 3; // less intonation, don't raise pitch at comma
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
#include <espeak-ng/espeak_ng.h>
|
||||
|
||||
#include "mnemonics.h"
|
||||
#include "translate.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@@ -81,12 +84,118 @@ extern espeak_VOICE current_voice_selected;
|
||||
extern voice_t *voice;
|
||||
extern int tone_points[12];
|
||||
|
||||
typedef enum {
|
||||
V_NAME = 1,
|
||||
V_LANGUAGE,
|
||||
V_GENDER,
|
||||
V_PHONEMES,
|
||||
V_DICTIONARY,
|
||||
V_VARIANTS,
|
||||
|
||||
V_MAINTAINER,
|
||||
V_STATUS,
|
||||
|
||||
// these affect voice quality, are independent of language
|
||||
V_FORMANT,
|
||||
V_PITCH,
|
||||
V_ECHO,
|
||||
V_FLUTTER,
|
||||
V_ROUGHNESS,
|
||||
V_CLARITY,
|
||||
V_TONE,
|
||||
V_VOICING,
|
||||
V_BREATH,
|
||||
V_BREATHW,
|
||||
|
||||
// these override defaults set by the translator
|
||||
V_LOWERCASE_SENTENCE,
|
||||
V_WORDGAP,
|
||||
V_INTONATION,
|
||||
V_TUNES,
|
||||
V_STRESSLENGTH,
|
||||
V_STRESSAMP,
|
||||
V_STRESSADD,
|
||||
V_DICTRULES,
|
||||
V_STRESSRULE,
|
||||
V_STRESSOPT,
|
||||
V_NUMBERS,
|
||||
|
||||
V_MBROLA,
|
||||
V_KLATT,
|
||||
V_FAST,
|
||||
V_SPEED,
|
||||
V_DICTMIN,
|
||||
|
||||
// these need a phoneme table to have been specified
|
||||
V_REPLACE,
|
||||
V_CONSONANTS
|
||||
} VOICELANGATTRIBUTES;
|
||||
|
||||
static const MNEM_TAB langopts_tab[] = {
|
||||
{ "dictrules", V_DICTRULES },
|
||||
{ "intonation", V_INTONATION },
|
||||
{ "l_dieresis", 0x100+LOPT_DIERESES },
|
||||
{ "l_prefix", 0x100+LOPT_PREFIXES },
|
||||
{ "l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING },
|
||||
{ "l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE },
|
||||
{ "l_sonorant_min", 0x100+LOPT_SONORANT_MIN },
|
||||
{ "lowercaseSentence", V_LOWERCASE_SENTENCE },
|
||||
{ "numbers", V_NUMBERS },
|
||||
{ "stressAdd", V_STRESSADD },
|
||||
{ "stressAmp", V_STRESSAMP },
|
||||
{ "stressLength", V_STRESSLENGTH },
|
||||
{ "stressOpt", V_STRESSOPT },
|
||||
{ "stressRule", V_STRESSRULE },
|
||||
{ "tunes", V_TUNES },
|
||||
{ "words", V_WORDGAP },
|
||||
|
||||
{ "maintainer", V_MAINTAINER },
|
||||
{ "status", V_STATUS },
|
||||
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const MNEM_TAB keyword_tab[] = {
|
||||
{ "name", V_NAME },
|
||||
{ "language", V_LANGUAGE },
|
||||
{ "gender", V_GENDER },
|
||||
{ "variants", V_VARIANTS },
|
||||
{ "formant", V_FORMANT },
|
||||
{ "pitch", V_PITCH },
|
||||
{ "phonemes", V_PHONEMES },
|
||||
{ "dictionary", V_DICTIONARY },
|
||||
{ "replace", V_REPLACE },
|
||||
{ "echo", V_ECHO },
|
||||
{ "flutter", V_FLUTTER },
|
||||
{ "roughness", V_ROUGHNESS },
|
||||
{ "clarity", V_CLARITY },
|
||||
{ "tone", V_TONE },
|
||||
{ "voicing", V_VOICING },
|
||||
{ "breath", V_BREATH },
|
||||
{ "breathw", V_BREATHW },
|
||||
{ "mbrola", V_MBROLA },
|
||||
{ "consonants", V_CONSONANTS },
|
||||
{ "klatt", V_KLATT },
|
||||
{ "fast_test2", V_FAST },
|
||||
{ "speed", V_SPEED },
|
||||
{ "dict_min", V_DICTMIN },
|
||||
|
||||
|
||||
{ "apostrophe", 0x100+LOPT_APOSTROPHE },
|
||||
{ "brackets", 0x100+LOPT_BRACKET_PAUSE },
|
||||
{ "bracketsAnnounced", 0x100+LOPT_BRACKET_PAUSE_ANNOUNCED },
|
||||
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const char *SelectVoice(espeak_VOICE *voice_select, int *found);
|
||||
espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name);
|
||||
voice_t *LoadVoice(const char *voice_name, int control);
|
||||
voice_t *LoadVoiceVariant(const char *voice_name, int variant);
|
||||
espeak_ng_STATUS DoVoiceChange(voice_t *v);
|
||||
void WavegenSetVoice(voice_t *v);
|
||||
void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab, int key);
|
||||
int Read8Numbers(char *data_in, int data[8]);
|
||||
void ReadTonePoints(char *string, int *tone_pts);
|
||||
void VoiceReset(int control);
|
||||
void FreeVoiceList(void);
|
||||
|
||||
+169
-419
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 to 2015 by Jonathan Duddington
|
||||
* email: jonsd@users.sourceforge.net
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "voice.h" // for voice_t, DoVoiceChange, N_PEAKS
|
||||
#include "common.h" // for GetFileLength, strncpy0
|
||||
#include "dictionary.h" // for LoadDictionary
|
||||
#include "langopts.h" // for LoadLanguageOptions
|
||||
#include "mnemonics.h" // for LookupMnemName, MNEM_TAB
|
||||
#include "phoneme.h" // for REPLACE_PHONEMES, n_replace_pho...
|
||||
#include "speech.h" // for PATHSEP
|
||||
@@ -50,6 +52,8 @@
|
||||
#include "translate.h" // for LANGUAGE_OPTIONS, DeleteTranslator
|
||||
#include "wavegen.h" // for InitBreath
|
||||
|
||||
|
||||
|
||||
static const MNEM_TAB genders[] = {
|
||||
{ "male", ENGENDER_MALE },
|
||||
{ "female", ENGENDER_FEMALE },
|
||||
@@ -69,107 +73,6 @@ static espeak_VOICE *voices_list[N_VOICES_LIST];
|
||||
|
||||
espeak_VOICE current_voice_selected;
|
||||
|
||||
enum {
|
||||
V_NAME = 1,
|
||||
V_LANGUAGE,
|
||||
V_GENDER,
|
||||
V_PHONEMES,
|
||||
V_DICTIONARY,
|
||||
V_VARIANTS,
|
||||
|
||||
V_MAINTAINER,
|
||||
V_STATUS,
|
||||
|
||||
// these affect voice quality, are independent of language
|
||||
V_FORMANT,
|
||||
V_PITCH,
|
||||
V_ECHO,
|
||||
V_FLUTTER,
|
||||
V_ROUGHNESS,
|
||||
V_CLARITY,
|
||||
V_TONE,
|
||||
V_VOICING,
|
||||
V_BREATH,
|
||||
V_BREATHW,
|
||||
|
||||
// these override defaults set by the translator
|
||||
V_LOWERCASE_SENTENCE,
|
||||
V_WORDGAP,
|
||||
V_INTONATION,
|
||||
V_TUNES,
|
||||
V_STRESSLENGTH,
|
||||
V_STRESSAMP,
|
||||
V_STRESSADD,
|
||||
V_DICTRULES,
|
||||
V_STRESSRULE,
|
||||
V_STRESSOPT,
|
||||
V_NUMBERS,
|
||||
|
||||
V_MBROLA,
|
||||
V_KLATT,
|
||||
V_FAST,
|
||||
V_SPEED,
|
||||
V_DICTMIN,
|
||||
|
||||
// these need a phoneme table to have been specified
|
||||
V_REPLACE,
|
||||
V_CONSONANTS
|
||||
};
|
||||
|
||||
static const MNEM_TAB keyword_tab[] = {
|
||||
{ "name", V_NAME },
|
||||
{ "language", V_LANGUAGE },
|
||||
{ "gender", V_GENDER },
|
||||
|
||||
{ "maintainer", V_MAINTAINER },
|
||||
{ "status", V_STATUS },
|
||||
|
||||
|
||||
{ "lowercaseSentence", V_LOWERCASE_SENTENCE },
|
||||
{ "variants", V_VARIANTS },
|
||||
{ "formant", V_FORMANT },
|
||||
{ "pitch", V_PITCH },
|
||||
{ "phonemes", V_PHONEMES },
|
||||
{ "dictionary", V_DICTIONARY },
|
||||
{ "stressLength", V_STRESSLENGTH },
|
||||
{ "stressAmp", V_STRESSAMP },
|
||||
{ "stressAdd", V_STRESSADD },
|
||||
{ "intonation", V_INTONATION },
|
||||
{ "tunes", V_TUNES },
|
||||
{ "dictrules", V_DICTRULES },
|
||||
{ "stressRule", V_STRESSRULE },
|
||||
{ "stressOpt", V_STRESSOPT },
|
||||
{ "replace", V_REPLACE },
|
||||
{ "words", V_WORDGAP },
|
||||
{ "echo", V_ECHO },
|
||||
{ "flutter", V_FLUTTER },
|
||||
{ "roughness", V_ROUGHNESS },
|
||||
{ "clarity", V_CLARITY },
|
||||
{ "tone", V_TONE },
|
||||
{ "voicing", V_VOICING },
|
||||
{ "breath", V_BREATH },
|
||||
{ "breathw", V_BREATHW },
|
||||
{ "numbers", V_NUMBERS },
|
||||
{ "mbrola", V_MBROLA },
|
||||
{ "consonants", V_CONSONANTS },
|
||||
{ "klatt", V_KLATT },
|
||||
{ "fast_test2", V_FAST },
|
||||
{ "speed", V_SPEED },
|
||||
{ "dict_min", V_DICTMIN },
|
||||
|
||||
// these just set a value in langopts.param[]
|
||||
{ "l_dieresis", 0x100+LOPT_DIERESES },
|
||||
{ "l_prefix", 0x100+LOPT_PREFIXES },
|
||||
{ "l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING },
|
||||
{ "l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE },
|
||||
{ "l_sonorant_min", 0x100+LOPT_SONORANT_MIN },
|
||||
{ "apostrophe", 0x100+LOPT_APOSTROPHE },
|
||||
{ "brackets", 0x100+LOPT_BRACKET_PAUSE },
|
||||
{ "bracketsAnnounced", 0x100+LOPT_BRACKET_PAUSE_ANNOUNCED },
|
||||
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
#define N_VOICE_VARIANTS 12
|
||||
const char variants_either[N_VOICE_VARIANTS] = { 1, 2, 12, 3, 13, 4, 14, 5, 11, 0 };
|
||||
const char variants_male[N_VOICE_VARIANTS] = { 1, 2, 3, 4, 5, 6, 0 };
|
||||
@@ -203,17 +106,6 @@ static char *fgets_strip(char *buf, int size, FILE *f_in)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int LookupTune(const char *name)
|
||||
{
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < n_tunes; ix++) {
|
||||
if (strcmp(name, tunes[ix].name) == 0)
|
||||
return ix;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void SetToneAdjust(voice_t *voice, int *tone_pts)
|
||||
{
|
||||
int ix;
|
||||
@@ -473,7 +365,7 @@ static void PhonemeReplacement(char *p)
|
||||
replace_phonemes[n_replace_phonemes++].type = flags;
|
||||
}
|
||||
|
||||
static int Read8Numbers(char *data_in, int data[8])
|
||||
int Read8Numbers(char *data_in, int data[8])
|
||||
{
|
||||
// Read 8 integer numbers
|
||||
memset(data, 0, 8*sizeof(int));
|
||||
@@ -481,7 +373,7 @@ static int Read8Numbers(char *data_in, int data[8])
|
||||
&data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]);
|
||||
}
|
||||
|
||||
static void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab, int key) {
|
||||
void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab, int key) {
|
||||
// read a list of numbers from string p
|
||||
// store them as flags in *flags
|
||||
// the meaning of the numbers is bit ordinals, not integer values
|
||||
@@ -501,18 +393,6 @@ static void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyw
|
||||
}
|
||||
}
|
||||
|
||||
static int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key)
|
||||
{
|
||||
// Return 0 if translator is set.
|
||||
// Return 1 and print an error message for specified key if not
|
||||
// used for parsing language options
|
||||
if (tr)
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "Cannot set %s: language not set, or is invalid.\n", LookupMnemName(keyword_tab, key));
|
||||
return 1;
|
||||
}
|
||||
|
||||
voice_t *LoadVoice(const char *vname, int control)
|
||||
{
|
||||
// control, bit 0 1= no_default
|
||||
@@ -527,7 +407,6 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
char *p;
|
||||
int key;
|
||||
int ix;
|
||||
int n;
|
||||
int value;
|
||||
int langix = 0;
|
||||
int tone_only = control & 2;
|
||||
@@ -543,8 +422,7 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
char buf[sizeof(path_home)+30];
|
||||
char path_voices[sizeof(path_home)+12];
|
||||
|
||||
int stress_add[8];
|
||||
char names[8][40];
|
||||
|
||||
char name1[40];
|
||||
char name2[80];
|
||||
|
||||
@@ -627,312 +505,184 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
|
||||
if (buf[0] == 0) continue;
|
||||
|
||||
key = LookupMnem(keyword_tab, buf);
|
||||
key = LookupMnem(langopts_tab, buf);
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case V_LANGUAGE:
|
||||
{
|
||||
unsigned int len;
|
||||
int priority;
|
||||
if (key != 0) {
|
||||
LoadLanguageOptions(translator, key, p);
|
||||
} else {
|
||||
key = LookupMnem(keyword_tab, buf);
|
||||
switch (key)
|
||||
{
|
||||
case V_LANGUAGE:
|
||||
{
|
||||
unsigned int len;
|
||||
int priority;
|
||||
|
||||
if (tone_only)
|
||||
break;
|
||||
if (tone_only)
|
||||
break;
|
||||
|
||||
priority = DEFAULT_LANGUAGE_PRIORITY;
|
||||
language_name[0] = 0;
|
||||
priority = DEFAULT_LANGUAGE_PRIORITY;
|
||||
language_name[0] = 0;
|
||||
|
||||
sscanf(p, "%s %d", language_name, &priority);
|
||||
if (strcmp(language_name, "variant") == 0)
|
||||
break;
|
||||
sscanf(p, "%s %d", language_name, &priority);
|
||||
if (strcmp(language_name, "variant") == 0)
|
||||
break;
|
||||
|
||||
len = strlen(language_name) + 2;
|
||||
// check for space in languages[]
|
||||
if (len < (sizeof(voice_languages)-langix-1)) {
|
||||
voice_languages[langix] = priority;
|
||||
len = strlen(language_name) + 2;
|
||||
// check for space in languages[]
|
||||
if (len < (sizeof(voice_languages)-langix-1)) {
|
||||
voice_languages[langix] = priority;
|
||||
|
||||
strcpy(&voice_languages[langix+1], language_name);
|
||||
langix += len;
|
||||
}
|
||||
strcpy(&voice_languages[langix+1], language_name);
|
||||
langix += len;
|
||||
}
|
||||
|
||||
// only act on the first language line
|
||||
if (language_set == false) {
|
||||
language_type = strtok(language_name, "-");
|
||||
language_set = true;
|
||||
strcpy(translator_name, language_type);
|
||||
strcpy(new_dictionary, language_type);
|
||||
strcpy(phonemes_name, language_type);
|
||||
SelectPhonemeTableName(phonemes_name);
|
||||
// only act on the first language line
|
||||
if (language_set == false) {
|
||||
language_type = strtok(language_name, "-");
|
||||
language_set = true;
|
||||
strcpy(translator_name, language_type);
|
||||
strcpy(new_dictionary, language_type);
|
||||
strcpy(phonemes_name, language_type);
|
||||
SelectPhonemeTableName(phonemes_name);
|
||||
|
||||
translator = SelectTranslator(translator_name);
|
||||
strncpy0(voice->language_name, language_name, sizeof(voice->language_name));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V_NAME:
|
||||
if (tone_only == 0) {
|
||||
while (isspace(*p)) p++;
|
||||
strncpy0(voice_name, p, sizeof(voice_name));
|
||||
}
|
||||
break;
|
||||
case V_GENDER:
|
||||
{
|
||||
int age = 0;
|
||||
char vgender[80];
|
||||
sscanf(p, "%s %d", vgender, &age);
|
||||
current_voice_selected.gender = LookupMnem(genders, vgender);
|
||||
current_voice_selected.age = age;
|
||||
}
|
||||
break;
|
||||
case V_DICTIONARY: // dictionary
|
||||
sscanf(p, "%s", new_dictionary);
|
||||
break;
|
||||
case V_PHONEMES: // phoneme table
|
||||
sscanf(p, "%s", phonemes_name);
|
||||
break;
|
||||
case V_FORMANT:
|
||||
VoiceFormant(p);
|
||||
break;
|
||||
case V_LOWERCASE_SENTENCE: {
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
translator = SelectTranslator(translator_name);
|
||||
strncpy0(voice->language_name, language_name, sizeof(voice->language_name));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V_NAME:
|
||||
if (tone_only == 0) {
|
||||
while (isspace(*p)) p++;
|
||||
strncpy0(voice_name, p, sizeof(voice_name));
|
||||
}
|
||||
break;
|
||||
case V_GENDER:
|
||||
{
|
||||
int age = 0;
|
||||
char vgender[80];
|
||||
sscanf(p, "%s %d", vgender, &age);
|
||||
current_voice_selected.gender = LookupMnem(genders, vgender);
|
||||
current_voice_selected.age = age;
|
||||
}
|
||||
break;
|
||||
case V_DICTIONARY: // dictionary
|
||||
sscanf(p, "%s", new_dictionary);
|
||||
break;
|
||||
case V_PHONEMES: // phoneme table
|
||||
sscanf(p, "%s", phonemes_name);
|
||||
break;
|
||||
case V_FORMANT:
|
||||
VoiceFormant(p);
|
||||
break;
|
||||
case V_PITCH:
|
||||
// default is pitch 82 118
|
||||
if (sscanf(p, "%d %d", &pitch1, &pitch2) == 2) {
|
||||
voice->pitch_base = (pitch1 - 9) << 12;
|
||||
voice->pitch_range = (pitch2 - pitch1) * 108;
|
||||
double factor = (double)(pitch1 - 82)/82;
|
||||
voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch
|
||||
}
|
||||
break;
|
||||
|
||||
translator->langopts.lowercase_sentence = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case V_PITCH:
|
||||
// default is pitch 82 118
|
||||
if (sscanf(p, "%d %d", &pitch1, &pitch2) == 2) {
|
||||
voice->pitch_base = (pitch1 - 9) << 12;
|
||||
voice->pitch_range = (pitch2 - pitch1) * 108;
|
||||
double factor = (double)(pitch1 - 82)/82;
|
||||
voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch
|
||||
}
|
||||
break;
|
||||
case V_STRESSLENGTH: {// stressLength
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
int stress_lengths_set = 0;
|
||||
int stress_lengths[8];
|
||||
stress_lengths_set = Read8Numbers(p, stress_lengths);
|
||||
|
||||
for (ix = 0; ix < stress_lengths_set; ix++) {
|
||||
translator->stress_lengths[ix] = stress_lengths[ix];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case V_STRESSAMP: { // stressAmp
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
case V_REPLACE:
|
||||
if (phonemes_set == false) {
|
||||
// must set up a phoneme table before we can lookup phoneme mnemonics
|
||||
SelectPhonemeTableName(phonemes_name);
|
||||
phonemes_set = true;
|
||||
}
|
||||
PhonemeReplacement(p);
|
||||
break;
|
||||
|
||||
int stress_amps_set = 0;
|
||||
int stress_amps[8];
|
||||
stress_amps_set = Read8Numbers(p, stress_amps);
|
||||
for (ix = 0; ix < stress_amps_set; ix++) {
|
||||
translator->stress_amps[ix] = stress_amps[ix];
|
||||
}
|
||||
case V_ECHO:
|
||||
// echo. suggest: 135mS 11%
|
||||
value = 0;
|
||||
voice->echo_amp = 0;
|
||||
sscanf(p, "%d %d", &voice->echo_delay, &voice->echo_amp);
|
||||
break;
|
||||
case V_FLUTTER: // flutter
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
voice->flutter = value * 32;
|
||||
break;
|
||||
case V_ROUGHNESS: // roughness
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
voice->roughness = value;
|
||||
break;
|
||||
case V_CLARITY: // formantshape
|
||||
if (sscanf(p, "%d", &value) == 1) {
|
||||
if (value > 4) {
|
||||
voice->peak_shape = 1; // squarer formant peaks
|
||||
value = 4;
|
||||
}
|
||||
voice->n_harmonic_peaks = 1+value;
|
||||
}
|
||||
break;
|
||||
case V_TONE:
|
||||
{
|
||||
int tone_data[12];
|
||||
ReadTonePoints(p, tone_data);
|
||||
SetToneAdjust(voice, tone_data);
|
||||
}
|
||||
break;
|
||||
case V_VOICING:
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
voice->voicing = (value * 64)/100;
|
||||
break;
|
||||
case V_BREATH:
|
||||
voice->breath[0] = Read8Numbers(p, &voice->breath[1]);
|
||||
for (ix = 1; ix < 8; ix++) {
|
||||
if (ix % 2)
|
||||
voice->breath[ix] = -voice->breath[ix];
|
||||
}
|
||||
break;
|
||||
case V_BREATHW:
|
||||
voice->breathw[0] = Read8Numbers(p, &voice->breathw[1]);
|
||||
break;
|
||||
case V_CONSONANTS:
|
||||
value = sscanf(p, "%d %d", &voice->consonant_amp, &voice->consonant_ampv);
|
||||
break;
|
||||
case V_SPEED:
|
||||
sscanf(p, "%d", &voice->speed_percent);
|
||||
SetSpeed(3);
|
||||
break;
|
||||
case V_MBROLA:
|
||||
{
|
||||
int srate = 16000;
|
||||
|
||||
break;
|
||||
}
|
||||
case V_STRESSADD: { // stressAdd
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
name2[0] = 0;
|
||||
sscanf(p, "%s %s %d", name1, name2, &srate);
|
||||
espeak_ng_STATUS status = LoadMbrolaTable(name1, name2, &srate);
|
||||
if (status != ENS_OK) {
|
||||
espeak_ng_PrintStatusCodeMessage(status, stderr, NULL);
|
||||
fclose(f_voice);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
voice->samplerate = srate;
|
||||
}
|
||||
break;
|
||||
case V_KLATT:
|
||||
voice->klattv[0] = 1; // default source: IMPULSIVE
|
||||
Read8Numbers(p, voice->klattv);
|
||||
voice->klattv[KLATT_Kopen] -= 40;
|
||||
break;
|
||||
case V_FAST:
|
||||
sscanf(p, "%d", &speed.fast_settings);
|
||||
SetSpeed(3);
|
||||
break;
|
||||
|
||||
int stress_add_set = 0;
|
||||
stress_add_set = Read8Numbers(p, stress_add);
|
||||
|
||||
for (ix = 0; ix < stress_add_set; ix++) {
|
||||
translator->stress_lengths[ix] += stress_add[ix];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case V_INTONATION: // intonation
|
||||
sscanf(p, "%d", &option_tone_flags);
|
||||
if ((option_tone_flags & 0xff) != 0) {
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
translator->langopts.intonation_group = option_tone_flags & 0xff;
|
||||
}
|
||||
break;
|
||||
case V_TUNES:
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
n = sscanf(p, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]);
|
||||
translator->langopts.intonation_group = 0;
|
||||
|
||||
for (ix = 0; ix < n; ix++) {
|
||||
if (strcmp(names[ix], "NULL") == 0)
|
||||
continue;
|
||||
|
||||
if ((value = LookupTune(names[ix])) < 0)
|
||||
fprintf(stderr, "Unknown tune '%s'\n", names[ix]);
|
||||
else
|
||||
translator->langopts.tunes[ix] = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case V_DICTRULES: // conditional dictionary rules and list entries
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
ReadNumbers(p, &translator->dict_condition, 32, keyword_tab, key);
|
||||
break;
|
||||
case V_STRESSOPT:
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
ReadNumbers(p, &translator->langopts.stress_flags, 32, keyword_tab, key);
|
||||
break;
|
||||
|
||||
case V_NUMBERS:
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
// expect a list of numbers
|
||||
while (*p != 0) {
|
||||
while (isspace(*p)) p++;
|
||||
if ((n = atoi(p)) > 0) {
|
||||
p++;
|
||||
if (n < 32) {
|
||||
translator->langopts.numbers |= (1 << n);
|
||||
} else {
|
||||
if (n < 64)
|
||||
translator->langopts.numbers2 |= (1 << (n-32));
|
||||
else
|
||||
fprintf(stderr, "numbers: Bad option number %d\n", n); }
|
||||
}
|
||||
while (isalnum(*p)) p++;
|
||||
}
|
||||
ProcessLanguageOptions(&(translator->langopts));
|
||||
|
||||
break;
|
||||
case V_REPLACE:
|
||||
if (phonemes_set == false) {
|
||||
// must set up a phoneme table before we can lookup phoneme mnemonics
|
||||
SelectPhonemeTableName(phonemes_name);
|
||||
phonemes_set = true;
|
||||
}
|
||||
PhonemeReplacement(p);
|
||||
break;
|
||||
case V_WORDGAP: // words
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
sscanf(p, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause);
|
||||
break;
|
||||
case V_STRESSRULE:
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
sscanf(p, "%d %d %d", &translator->langopts.stress_rule,
|
||||
&translator->langopts.unstressed_wd1,
|
||||
&translator->langopts.unstressed_wd2);
|
||||
|
||||
break;
|
||||
case V_ECHO:
|
||||
// echo. suggest: 135mS 11%
|
||||
value = 0;
|
||||
voice->echo_amp = 0;
|
||||
sscanf(p, "%d %d", &voice->echo_delay, &voice->echo_amp);
|
||||
break;
|
||||
case V_FLUTTER: // flutter
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
voice->flutter = value * 32;
|
||||
break;
|
||||
case V_ROUGHNESS: // roughness
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
voice->roughness = value;
|
||||
break;
|
||||
case V_CLARITY: // formantshape
|
||||
if (sscanf(p, "%d", &value) == 1) {
|
||||
if (value > 4) {
|
||||
voice->peak_shape = 1; // squarer formant peaks
|
||||
value = 4;
|
||||
}
|
||||
voice->n_harmonic_peaks = 1+value;
|
||||
}
|
||||
break;
|
||||
case V_TONE:
|
||||
{
|
||||
int tone_data[12];
|
||||
ReadTonePoints(p, tone_data);
|
||||
SetToneAdjust(voice, tone_data);
|
||||
}
|
||||
break;
|
||||
case V_VOICING:
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
voice->voicing = (value * 64)/100;
|
||||
break;
|
||||
case V_BREATH:
|
||||
voice->breath[0] = Read8Numbers(p, &voice->breath[1]);
|
||||
for (ix = 1; ix < 8; ix++) {
|
||||
if (ix % 2)
|
||||
voice->breath[ix] = -voice->breath[ix];
|
||||
}
|
||||
break;
|
||||
case V_BREATHW:
|
||||
voice->breathw[0] = Read8Numbers(p, &voice->breathw[1]);
|
||||
break;
|
||||
case V_CONSONANTS:
|
||||
value = sscanf(p, "%d %d", &voice->consonant_amp, &voice->consonant_ampv);
|
||||
break;
|
||||
case V_SPEED:
|
||||
sscanf(p, "%d", &voice->speed_percent);
|
||||
SetSpeed(3);
|
||||
break;
|
||||
case V_MBROLA:
|
||||
{
|
||||
int srate = 16000;
|
||||
|
||||
name2[0] = 0;
|
||||
sscanf(p, "%s %s %d", name1, name2, &srate);
|
||||
espeak_ng_STATUS status = LoadMbrolaTable(name1, name2, &srate);
|
||||
if (status != ENS_OK) {
|
||||
espeak_ng_PrintStatusCodeMessage(status, stderr, NULL);
|
||||
fclose(f_voice);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
voice->samplerate = srate;
|
||||
}
|
||||
break;
|
||||
case V_KLATT:
|
||||
voice->klattv[0] = 1; // default source: IMPULSIVE
|
||||
Read8Numbers(p, voice->klattv);
|
||||
voice->klattv[KLATT_Kopen] -= 40;
|
||||
break;
|
||||
case V_FAST:
|
||||
sscanf(p, "%d", &speed.fast_settings);
|
||||
SetSpeed(3);
|
||||
break;
|
||||
case V_DICTMIN: {
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
|
||||
if (sscanf(p, "%d", &value) == 1)
|
||||
translator->dict_min_size = value;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case V_MAINTAINER:
|
||||
case V_STATUS:
|
||||
break;
|
||||
default:
|
||||
if ((key & 0xff00) == 0x100) {
|
||||
if (CheckTranslator(translator, keyword_tab, key) != 0)
|
||||
break;
|
||||
sscanf(p, "%d", &translator->langopts.param[key &0xff]);
|
||||
} else
|
||||
fprintf(stderr, "Bad voice attribute: %s\n", buf);
|
||||
break;
|
||||
}
|
||||
case V_MAINTAINER:
|
||||
case V_STATUS:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad voice attribute: %s\n", buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f_voice != NULL)
|
||||
fclose(f_voice);
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
<ClCompile Include="..\libespeak-ng\ieee80.c" />
|
||||
<ClCompile Include="..\libespeak-ng\intonation.c" />
|
||||
<ClCompile Include="..\libespeak-ng\klatt.c" />
|
||||
<ClCompile Include="..\libespeak-ng\langopts.c" />
|
||||
<ClCompile Include="..\libespeak-ng\mbrowrap.c" />
|
||||
<ClCompile Include="..\libespeak-ng\mnemonics.c" />
|
||||
<ClCompile Include="..\libespeak-ng\numbers.c" />
|
||||
@@ -210,6 +211,7 @@
|
||||
<ClInclude Include="..\libespeak-ng\common.h" />
|
||||
<ClInclude Include="..\libespeak-ng\error.h" />
|
||||
<ClInclude Include="..\libespeak-ng\klatt.h" />
|
||||
<ClInclude Include="..\libespeak-ng\langopts.h" />
|
||||
<ClInclude Include="..\libespeak-ng\mbrowrap.h" />
|
||||
<ClInclude Include="..\libespeak-ng\phoneme.h" />
|
||||
<ClInclude Include="..\libespeak-ng\sintab.h" />
|
||||
@@ -232,4 +234,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -90,6 +90,9 @@
|
||||
<ClCompile Include="..\libespeak-ng\klatt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libespeak-ng\langopts.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libespeak-ng\mbrowrap.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -197,6 +200,9 @@
|
||||
<ClInclude Include="..\libespeak-ng\klatt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libespeak-ng\langopts.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libespeak-ng\mbrowrap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -227,4 +233,4 @@
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user