/**
* Copyright 2000-2008 DFKI GmbH.
* All Rights Reserved. Use is subject to license terms.
*
* This file is part of MARY TTS.
*
* MARY TTS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package marytts.language.de.features;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import marytts.exceptions.MaryConfigurationException;
import marytts.features.MaryGenericFeatureProcessors;
import marytts.features.MaryLanguageFeatureProcessors;
import marytts.modules.phonemiser.AllophoneSet;
import marytts.modules.synthesis.Voice;
import marytts.server.MaryProperties;
import marytts.util.MaryRuntimeUtils;
public class FeatureProcessorManager extends marytts.features.FeatureProcessorManager {
/**
* Builds a new manager. This manager uses the english phoneset of FreeTTS and a PoS conversion file if the english PoS tagger
* is used. All feature processors loaded are language specific.
*/
public FeatureProcessorManager() {
super();
setupAdditionalFeatureProcessors();
}
/**
* Constructor called from a Voice in Locale DE that has its own acoustic models
*
* @param voice
* voice
* @throws MaryConfigurationException
* MaryConfigurationException
*/
public FeatureProcessorManager(Voice voice) throws MaryConfigurationException {
super(voice.getLocale());
setupAdditionalFeatureProcessors();
registerAcousticModels(voice);
}
/**
* specific stuff, moved here so that it can be called by more than one constructor without unnecessary code duplication
*/
private void setupAdditionalFeatureProcessors() {
try {
String[] pos = { "0", "NN", "NE", "NNm", "ADJA", "ADJD", "CARD", "CARDj", "ORD", "ITJ", "PDS", "PPOSS", "TRUNC",
"ADV", "ADVq", "ADVf", "APPR", "APPRbis", "APPRART", "APPO", "APZR", "ART", "ARTdna", "ARTg", "ARTngd", "FM",
"KOUI", "KOUS", "KON", "KOKOM", "KOKOMa", "PDAT", "PIS", "PIAT", "PIDAT", "PIDAT2", "PPER", "PPOSAT",
"PRELS", "PRELAT", "PRF", "PWS", "PWAT", "PWAV", "PAV", "PTKZU", "PTKNEG", "PTKVZ", "PTKANT", "PTKA", "SGML",
"SPELL", "VVFIN", "VVIMP", "VVINF", "VVIZU", "VVPP", "VV", "VAFIN", "VAIMP", "VAINF", "VAPP", "VMFIN",
"VMINF", "VMPP", "XY" };
addFeatureProcessor(new MaryLanguageFeatureProcessors.Pos(pos));
// TODO: dummy code, replace with something useful:
Map<String, String> posConverter = new HashMap<String, String>();
addFeatureProcessor(new MaryLanguageFeatureProcessors.Gpos(posConverter));
// property is set in de.config
AllophoneSet allophoneSet = MaryRuntimeUtils.needAllophoneSet("de.allophoneset");
// Phonetic features of the current segment:
String[] phones = allophoneSet.getAllophoneNames().toArray(new String[0]);
String[] phoneValues = new String[phones.length + 1];
phoneValues[0] = "0";
System.arraycopy(phones, 0, phoneValues, 1, phones.length);
setupHardcodedPhoneFeatureValues();
// Adding uvular consonant place for German:
// cplace: 0-n/a l-labial a-alveolar p-palatal b-labio_dental d-dental v-velar u-uvular g-?
String[] cplaceValues = new String[] { "0", "l", "a", "p", "b", "d", "v", "u", "g" };
phonefeatures2values.put("cplace", cplaceValues);
String pauseSymbol = allophoneSet.getSilence().name();
setupPhoneFeatureProcessors(allophoneSet, phoneValues, pauseSymbol, phonefeatures2values);
String wordFrequencyFilename = MaryProperties.getProperty("de.wordFrequency.fst");
InputStream wordFrequencyStream = MaryProperties.getStream("de.wordFrequency.fst");
String wordFrequencyEncoding = MaryProperties.getProperty("de.wordFrequency.encoding");
addFeatureProcessor(new MaryLanguageFeatureProcessors.WordFrequency(wordFrequencyStream, wordFrequencyFilename,
wordFrequencyEncoding));
/* for database selection */
String[] phoneClasses = new String[] { "0", "c_labial", "c_alveolar", "c_palatal", "c_labiodental", "c_dental",
"c_velar", "c_glottal", "c_uvular", "v_i", "v_u", "v_O", "v_E", "v_EI", "v_@", "v_aU", "v_6", "v_~", "v_a",
"v_y", "v_2", "v_e", "v_o", "v_9", "v_OY", "v_Ya", "v_aI" };
// map from phones to their classes
Map<String, String> phone2Classes = new HashMap<String, String>();
// put in vowels
phone2Classes.put("I", "v_i");
phone2Classes.put("i", "v_i");
phone2Classes.put("i:", "v_i");
phone2Classes.put("U", "v_u");
phone2Classes.put("u", "v_u");
phone2Classes.put("u:", "v_u");
phone2Classes.put("O", "v_O");
phone2Classes.put("E", "v_E");
phone2Classes.put("E:", "v_E");
phone2Classes.put("EI", "v_EI");
phone2Classes.put("@", "v_@");
phone2Classes.put("aU", "v_aU");
phone2Classes.put("6", "v_6");
phone2Classes.put("a~", "v_~");
phone2Classes.put("e~", "v_~");
phone2Classes.put("o~", "v_~");
phone2Classes.put("9~", "v_~");
phone2Classes.put("a", "v_a");
phone2Classes.put("a:", "v_a");
phone2Classes.put("y", "v_y");
phone2Classes.put("y:", "v_y");
phone2Classes.put("Y", "v_y");
phone2Classes.put("2", "v_2");
phone2Classes.put("2:", "v_2");
phone2Classes.put("e", "v_e");
phone2Classes.put("e:", "v_e");
phone2Classes.put("o", "v_o");
phone2Classes.put("o:", "v_o");
phone2Classes.put("9", "v_9");
phone2Classes.put("OY", "v_OY");
phone2Classes.put("Ya", "v_Ya");
phone2Classes.put("aI", "v_aI");
// put in consonants
phone2Classes.put("b", "c_labial");
phone2Classes.put("m", "c_labial");
phone2Classes.put("p", "c_labial");
phone2Classes.put("w", "c_labial");
phone2Classes.put("pf", "c_labial");
phone2Classes.put("d", "c_alveolar");
phone2Classes.put("l", "c_alveolar");
phone2Classes.put("n", "c_alveolar");
phone2Classes.put("r", "c_alveolar");
phone2Classes.put("s", "c_alveolar");
phone2Classes.put("t", "c_alveolar");
phone2Classes.put("z", "c_alveolar");
phone2Classes.put("ts", "c_alveolar");
phone2Classes.put("tS", "c_palatal");
phone2Classes.put("S", "c_palatal");
phone2Classes.put("j", "c_palatal");
phone2Classes.put("Z", "c_palatal");
phone2Classes.put("f", "c_labiodental");
phone2Classes.put("v", "c_labiodental");
phone2Classes.put("D", "c_dental");
phone2Classes.put("T", "c_dental");
phone2Classes.put("g", "c_velar");
phone2Classes.put("k", "c_velar");
phone2Classes.put("N", "c_velar");
phone2Classes.put("C", "c_velar");
phone2Classes.put("x", "c_uvular");
phone2Classes.put("R", "c_uvular");
phone2Classes.put("h", "c_glottal");
phone2Classes.put("?", "c_glottal");
phone2Classes.put("_", "0");
MaryGenericFeatureProcessors.TargetElementNavigator nextSegment = new MaryGenericFeatureProcessors.NextSegmentNavigator();
MaryGenericFeatureProcessors.TargetElementNavigator nextWord = new MaryGenericFeatureProcessors.NextWordNavigator();
MaryGenericFeatureProcessors.TargetElementNavigator firstSegNextWord = new MaryGenericFeatureProcessors.FirstSegmentNextWordNavigator();
addFeatureProcessor(new MaryLanguageFeatureProcessors.Selection_PhoneClass(phone2Classes, phoneClasses, nextSegment));
addFeatureProcessor(new MaryLanguageFeatureProcessors.Pos("next_pos", pos, nextWord));
// features of first segment in next word
addFeatureProcessor(new MaryLanguageFeatureProcessors.PhoneFeature(allophoneSet, "next_wordbegin_cplace", "cplace",
cplaceValues, "_", firstSegNextWord));
addFeatureProcessor(new MaryLanguageFeatureProcessors.PhoneFeature(allophoneSet, "next_wordbegin_ctype", "ctype",
phonefeatures2values.get("ctype"), "_", firstSegNextWord));
/*
* processors_en.put("seg_coda_fric", new LanguageFeatureProcessors.SegCodaFric(phoneSet));
* processors_en.put("seg_onset_fric", new LanguageFeatureProcessors.SegOnsetFric(phoneSet));
*
* processors_en.put("seg_coda_stop", new LanguageFeatureProcessors.SegCodaStop(phoneSet));
* processors_en.put("seg_onset_stop", new LanguageFeatureProcessors.SegOnsetStop(phoneSet));
*
* processors_en.put("seg_coda_nasal", new LanguageFeatureProcessors.SegCodaNasal(phoneSet));
* processors_en.put("seg_onset_nasal", new LanguageFeatureProcessors.SegOnsetNasal(phoneSet));
*
* processors_en.put("seg_coda_glide", new LanguageFeatureProcessors.SegCodaGlide(phoneSet));
* processors_en.put("seg_onset_glide", new LanguageFeatureProcessors.SegOnsetGlide(phoneSet));
*
* processors_en.put("syl_codasize", new LanguageFeatureProcessors.SylCodaSize(phoneSet));
* processors_en.put("syl_onsetsize", new LanguageFeatureProcessors.SylOnsetSize(phoneSet));
* processors_en.put("accented", new GenericFeatureProcessors.Accented());
*
* processors_en.put("token_pos_guess", new LanguageFeatureProcessors.TokenPosGuess());
*/
} catch (Exception e) {
e.printStackTrace();
throw new Error("Problem building Pos or PhoneSet");
}
}
@Override
public Locale getLocale() {
return Locale.GERMAN;
}
}