marytts.tools.voiceimport.DatabaseLayout Maven / Gradle / Ivy
The newest version!
/**
* Copyright 2007 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 .
*
*/
package marytts.tools.voiceimport;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import marytts.Version;
import marytts.config.MaryConfig;
import marytts.exceptions.MaryConfigurationException;
import marytts.modules.phonemiser.AllophoneSet;
import marytts.util.MaryUtils;
import marytts.util.io.BasenameList;
/**
* The DatabaseLayout class registers the base directory of a voice database, as well as the various subdirectories where the
* various voice database components should be stored or read from.
*
* @author Anna Hunecke
*
*/
public class DatabaseLayout {
// marybase
public static final String MARYBASE = "db.marybase";
// marybase version
public static final String MARYBASEVERSION = "db.marybaseversion";
// voicename
public static final String VOICENAME = "db.voicename";
// gender
public static final String GENDER = "db.gender";
// domain
public static final String DOMAIN = "db.domain";
// Edinburgh Speech Tools
public static final String ESTDIR = "db.estDir";
// locale
public static final String LOCALE = "db.locale";
// the sampling rate
public static final String SAMPLINGRATE = "db.samplingrate";
// root directory for the database
public static final String ROOTDIR = "db.rootDir";
// directory for Mary config files
public static final String CONFIGDIR = "db.configDir";
// directory for Mary voice files
public static final String FILEDIR = "db.fileDir";
// mary file extension
public static final String MARYEXT = "db.maryExtension";
// basename list file
public static final String BASENAMEFILE = "db.basenameFile";
// text file dir
public static final String TEXTDIR = "db.textDir";
// text file extension
public static final String TEXTEXT = "db.textExtension";
// wav file dir
public static final String WAVDIR = "db.wavDir";
// wav file extension
public static final String WAVEXT = "db.wavExtension";
// phonetic label files
public static final String LABDIR = "db.labDir";
// phonetic label file extension
public static final String LABEXT = "db.labExtension";
// halfphone label file extention
public static final String HALFPHONELABEXT = "db.hplabExtension";
// pitchmark file dir
public static final String PMDIR = "db.pmDir";
// pitchmark file extension
public static final String PMEXT = "db.pmExtension";
// pitch file dir
public static final String PTCDIR = "db.ptcDir";
// pitch file extension
public static final String PTCEXT = "db.ptcExtension";
// directory for temporary files
public static final String TEMPDIR = "db.tempDir";
// maryxml dir
public static final String MARYXMLDIR = "db.maryxmlDir";
// maryxml extentsion
public static final String MARYXMLEXT = "db.maryxmlExtension";
// Prompt allophones dir
public static final String PROMPTALLOPHONESDIR = "db.promptAllophonesDir";
// Allophones aligned with labels
public static final String ALLOPHONESDIR = "db.allophonesDir";
public static final String MARYSERVERHOST = "db.maryServerHost";
public static final String MARYSERVERPORT = "db.maryServerPort";
public static final String PHONELABDIR = "db.phoneLabDir";
public static final String PHONEFEATUREDIR = "db.phoneFeatureDir";
public static final String HALFPHONELABDIR = "db.halfphoneLabDir";
public static final String HALFPHONEFEATUREDIR = "db.halfphoneFeatureDir";
public static final String VOCALIZATIONSDIR = "db.vocalizationsDir";
// paths used in HMM voice creation
public static final String AWKPATH = "external.awkPath";
public static final String PERLPATH = "external.perlPath";
public static final String BCPATH = "external.bcPath";
public static final String HTSPATH = "external.htsPath";
public static final String HTSENGINEPATH = "external.htsEnginePath";
public static final String SPTKPATH = "external.sptkPath";
public static final String TCLPATH = "external.tclPath";
public static final String SOXPATH = "external.soxPath";
public static final String EHMMPATH = "external.ehmmPath";
private SortedMap props;
private BasenameList bnl;
private SortedMap> localProps;
private SortedMap external; /* paths for external binaries used in HMM voice creation */
private String fileSeparator;
private VoiceImportComponent[] components;
private String[] compNames;
private Map compnames2comps;
private SortedMap */> missingProps;
private String missingPropsHelp;
private boolean initialized;
private Set uneditableProps = new HashSet(Arrays.asList(MARYEXT, CONFIGDIR, FILEDIR, TEMPDIR, WAVEXT));
private Map props2Help;
// Marc, Sept/Oct 2011: The following seem important enough to instantiate directly as objects:
private Locale locale;
private AllophoneSet allophoneSet;
private File voiceDir;
private File configFile;
public DatabaseLayout(File configFile) throws Exception {
this(configFile, new VoiceImportComponent[0]);
}
public DatabaseLayout(VoiceImportComponent comp) throws Exception {
this(new File(System.getProperty("user.dir", "."), "database.config"), comp);
}
public DatabaseLayout(File configFile, VoiceImportComponent comp) throws Exception {
this(configFile, new VoiceImportComponent[] { comp });
}
public DatabaseLayout(File configFile, VoiceImportComponent[] comps) throws Exception {
initialized = false;
initialize(configFile, comps);
}
private void setupHelp() {
props2Help = new TreeMap();
props2Help.put(BASENAMEFILE, "file containing the list of files that are used to build the voice");
props2Help.put(DOMAIN, "general or limited");
props2Help.put(ESTDIR, "directory containing the local installation of the Edinburgh Speech Tools");
props2Help.put(GENDER, "female or male");
props2Help.put(LABDIR, "directory containing the label files. Will be created if it does not exist.");
props2Help.put(LABEXT, "extension of the label files, default: \".lab\"");
props2Help.put(HALFPHONELABEXT, "extension of the halfphone label files, default: \".hplab\"");
props2Help.put(LOCALE, "de, en or en_US");
props2Help.put(MARYBASE, "directory containing the local Mary installation");
props2Help.put(MARYBASEVERSION, "local Mary installation version");
props2Help.put(MARYXMLDIR,
"directory containing maryxml representations of the transcripts. Will be created if it does not exist.");
props2Help.put(MARYXMLEXT, "extension of the maryxml files, default: \".xml\"");
props2Help
.put(ROOTDIR,
"directory in which all the files created during installation will be stored. Will be created if it does not exist.");
props2Help.put(SAMPLINGRATE, "the sampling rate of the wave files, default: \"16000\"");
props2Help.put(TEXTDIR, "directory containing the transcript files. Will be created if it does not exist.");
props2Help.put(TEXTEXT, "extension of the transcript files, default: \".txt\"");
props2Help.put(VOICENAME, "the name of the voice, one word, for example: \"my_voice\"");
props2Help.put(WAVDIR, "directory containing the wave files. If it does not exist, an Error is thrown.");
props2Help.put(PMDIR, "directory containing the pitchmark files. If it does not exist, an Error is thrown.");
props2Help.put(PTCDIR, "directory containing the pitch files. If it does not exist, an Error is thrown.");
props2Help.put(PROMPTALLOPHONESDIR, "directory containing the allophones files predicted by mary");
props2Help.put(ALLOPHONESDIR, "directory containing allophones files aligned with (possibly manually corrected) labels");
props2Help.put(MARYSERVERHOST, "hostname of the MARY TTS server running NLP components for this language");
props2Help.put(MARYSERVERPORT, "port of the MARY TTS server running NLP components for this language");
props2Help.put(PHONEFEATUREDIR, "directory containing the phone features.");
props2Help.put(PHONELABDIR, "directory containing the phone unit labels");
props2Help.put(HALFPHONEFEATUREDIR, "directory containing the half-phone features.");
props2Help.put(HALFPHONELABDIR, "directory containing the half-phone unit labels");
props2Help.put(VOCALIZATIONSDIR, "directory in which all files created during listener vocal behavior creation");
for (int i = 0; i < components.length; i++) {
components[i].setupHelp();
}
}
private void initialize(File configFile, VoiceImportComponent[] theComponents) throws Exception {
System.out.println("Loading database layout:");
this.configFile = configFile;
/* first, handle the components */
this.components = theComponents;
getCompNames();
/* initialize the help texts */
setupHelp();
voiceDir = configFile.getParentFile();
fileSeparator = System.getProperty("file.separator");
/* check if there is a config file */
if (configFile.exists()) {
System.out.println("Reading config file " + configFile.getAbsolutePath());
readConfigFile(configFile);
SortedMap defaultGlobalProps = new TreeMap();
// get the default values for the global props
defaultGlobalProps = initDefaultProps(defaultGlobalProps, true);
/*
* if there is a valid marybase, then check if there is an externalBinaries.config and load the paths the paths will
* be loaded in external
*/
String externalConfigFileName = getProp(MARYBASE) + "/lib/external/externalBinaries.config";
File externalConfigFile = new File(externalConfigFileName);
if (externalConfigFile.exists()) {
System.out.println("Reading external binaries config file " + externalConfigFile);
readExternalBinariesConfigFile(externalConfigFile);
}
// get the local default props from the components
SortedMap> defaultLocalProps = getDefaultPropsFromComps();
// try to get all props and values from config file
if (!checkProps(defaultGlobalProps, defaultLocalProps)) {
// some props are missing
// prompt the user for the missing props
// (user input updates the props via the GUI)
if (!displayProps(missingProps, missingPropsHelp, "The following properties are missing:"))
return;
// check if all dirs have a file separator at the end
checkForFileSeparators();
// save the props
saveProps(configFile);
}
// check if all dirs have a file separator at the end
checkForFileSeparators();
} else {
// we have no values for our props
props = new TreeMap();
// prompt the user for some props
if (!promptUserForBasicProps(props))
return;
// fill in the other props with default values
props = initDefaultProps(props, false);
/*
* if there is a valid marybase, then check if there is an externalBinaries.config and load the paths the paths will
* be load in external
*/
String externalConfigFileName = getProp(MARYBASE) + "/lib/external/externalBinaries.config";
File externalConfigFile = new File(externalConfigFileName);
if (externalConfigFile.exists()) {
System.out.println("Reading external binaries config file " + externalConfigFile);
readExternalBinariesConfigFile(externalConfigFile);
}
// get the local default props from the components
localProps = getDefaultPropsFromComps();
// check if all dirs have a file separator at the end
checkForFileSeparators();
// save the props
saveProps(configFile);
}
assureFileIntegrity();
initInternalResources();
loadBasenameList();
initializeComps();
initialized = true;
}
/**
* Initialise any internal resources required given the content of the configuration file.
*
* @throws MaryConfigurationException
* if the configuration settings and what is available from the classpath does not seem to match.
*/
private void initInternalResources() throws MaryConfigurationException {
locale = MaryUtils.string2locale(getProp(LOCALE));
allophoneSet = MaryConfig.getAllophoneSet(locale);
if (allophoneSet == null) {
throw new MaryConfigurationException("No allophone set available for locale '" + getProp(LOCALE)
+ "' -- check that the corresponding language jar is in the classpath!");
}
}
/**
* Get the names of the components and store them in array
*/
private void getCompNames() {
compnames2comps = new HashMap();
compNames = new String[components.length];
for (int i = 0; i < components.length; i++) {
compNames[i] = components[i].getName();
compnames2comps.put(compNames[i], components[i]);
}
}
/**
* Obtain a voice import component by its name. This can be used to run invidivual functions of a given voice import component
* from another component. Handle with care -- only use this if you know what you are doing!
*
* @param componentName
* componentName
* @return the named voice import component, or null if there is no such component.
*/
public VoiceImportComponent getComponent(String componentName) {
return compnames2comps.get(componentName);
}
/**
* Read the props in the config file
*
* @param configFile
* the config file
* @throws IOException
* IOException
*/
private void readConfigFile(File configFile) throws IOException {
props = new TreeMap();
localProps = new TreeMap>();
try {
// open the file
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith("#") || line.trim().equals(""))
continue;
// System.out.println(line);
// line looks like " "
// looks like "."
String[] lineSplit = line.split(" ", 2);
if (lineSplit.length < 2) {
throw new IOException("Illegal line -- expecting two fields, got " + lineSplit.length + ": '" + line + "'");
}
if (lineSplit[0].startsWith("db.")) {
// global prop
props.put(lineSplit[0], lineSplit[1]);
} else {
// local prop
String compName = lineSplit[0].substring(0, lineSplit[0].indexOf('.'));
if (localProps.containsKey(compName)) {
SortedMap localPropMap = localProps.get(compName);
localPropMap.put(lineSplit[0], lineSplit[1]);
} else {
SortedMap localPropMap = new TreeMap();
localPropMap.put(lineSplit[0], lineSplit[1]);
localProps.put(compName, localPropMap);
}
}
}
in.close();
// add the props that are not editable
SortedMap defaultGlobalProps = new TreeMap();
// get the default values for the global props
defaultGlobalProps = initDefaultProps(defaultGlobalProps, false);
for (Iterator it = uneditableProps.iterator(); it.hasNext();) {
String key = it.next();
if (defaultGlobalProps.containsKey(key)) {
props.put(key, defaultGlobalProps.get(key));
} else {
// this case should never happen
throw new IllegalStateException("Uneditable global prop " + key + " not defined in default props.");
}
}
} catch (IOException e) {
IOException myIOE = new IOException("Error reading config file");
myIOE.initCause(e);
throw myIOE;
}
}
/**
* Read the props in the config file
*
* @param configFile
* the config file
* @throws IOException
* IOException
*/
private void readExternalBinariesConfigFile(File configFile) throws IOException {
external = new TreeMap();
try {
// open the file
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith("#") || line.trim().equals(""))
continue;
// System.out.println(line);
// line looks like " "
// looks like "."
String[] lineSplit = line.split(" ", 2);
if (lineSplit[0].startsWith("external.")) {
// global external
external.put(lineSplit[0], lineSplit[1]);
}
}
in.close();
} catch (IOException e) {
IOException myIOE = new IOException("Error reading config file");
myIOE.initCause(e);
throw myIOE;
}
}
/**
* Check if all props are set
*
* @param defaultGlobalProps
* default global props
* @param defaultLocalProps
* default local props
* @return true if all props are set, false otherwise
*/
private boolean checkProps(SortedMap defaultGlobalProps,
SortedMap> defaultLocalProps) {
boolean allFine = true;
missingProps = new TreeMap();
StringBuilder helpTextBuf = new StringBuilder();
helpTextBuf.append("\n\nSETTINGS HELP \n" + "\n\n\n");
/* check the local props */
Set defaultProps = defaultLocalProps.keySet();
for (Iterator it = defaultProps.iterator(); it.hasNext();) {
String key = it.next();
if (!localProps.containsKey(key)) {
VoiceImportComponent comp = (VoiceImportComponent) compnames2comps.get(key);
SortedMap nextLocalPropMap = defaultLocalProps.get(key);
if (nextLocalPropMap != null && !nextLocalPropMap.isEmpty()) {
missingProps.put(key, nextLocalPropMap);
for (Iterator it2 = nextLocalPropMap.keySet().iterator(); it2.hasNext();) {
String nextKey = it2.next();
helpTextBuf.append("- " + nextKey + "
\n" + "- "
+ comp.getHelpTextForProp(nextKey) + "
\n");
}
allFine = false;
}
} else {
VoiceImportComponent comp = compnames2comps.get(key);
SortedMap nextLocalPropMap = localProps.get(key);
SortedMap nextDefaultLocalPropMap = defaultLocalProps.get(key);
Set nextDefaultLocalProps = nextDefaultLocalPropMap.keySet();
boolean haveAllLocalProps = true;
SortedMap missingLocalPropMap = new TreeMap();
for (Iterator it2 = nextDefaultLocalProps.iterator(); it2.hasNext();) {
String nextKey = it2.next();
if (!nextLocalPropMap.containsKey(nextKey)) {
missingLocalPropMap.put(nextKey, nextDefaultLocalPropMap.get(nextKey));
helpTextBuf.append("- " + nextKey + "
\n" + "- "
+ comp.getHelpTextForProp(nextKey) + "
\n");
haveAllLocalProps = false;
} else {
// make sure all dir names have a / at the end
// TODO verify that this way of deciding whether a key represents a path is really robust,
// also consider unifying the numerous condition blocks like this into one function for maintainability
if (nextKey.endsWith("Dir")) {
String prop = nextLocalPropMap.get(nextKey);
if (!prop.endsWith(fileSeparator)) {
prop = prop + fileSeparator;
nextLocalPropMap.put(nextKey, prop);
}
}
}
}
if (!haveAllLocalProps) {
missingProps.put(key, missingLocalPropMap);
allFine = false;
}
}
}
/* check the global props */
defaultProps = defaultGlobalProps.keySet();
for (Iterator it = defaultProps.iterator(); it.hasNext();) {
String key = it.next();
if (!props.containsKey(key)) {
missingProps.put(key, defaultGlobalProps.get(key));
helpTextBuf.append("- " + key + "
\n" + "- " + props2Help.get(key) + "
\n");
allFine = false;
} else {
// make sure all dir names have a / at the end
if (key.endsWith("Dir")) {
String prop = (String) props.get(key);
if (!prop.endsWith(fileSeparator)) {
prop = prop + fileSeparator;
props.put(key, prop);
}
}
}
}
helpTextBuf.append("
\n\n");
missingPropsHelp = helpTextBuf.toString();
return allFine;
}
private void checkForFileSeparators() {
/* check the global props */
Set propKeys = props.keySet();
for (Iterator it = propKeys.iterator(); it.hasNext();) {
String key = it.next();
// make sure all dir names have a / at the end
if (key.endsWith("Dir")) {
String prop = (String) props.get(key);
char lastChar = prop.charAt(prop.length() - 1);
if (Character.isLetterOrDigit(lastChar)) {
props.put(key, prop + fileSeparator);
}
}
}
/* check the local props */
Set localPropKeys = localProps.keySet();
for (Iterator it = localPropKeys.iterator(); it.hasNext();) {
SortedMap nextLocalPropMap = localProps.get(it.next());
for (Iterator it2 = nextLocalPropMap.keySet().iterator(); it2.hasNext();) {
String nextKey = it2.next();
// make sure all dir names have a / at the end
if (nextKey.endsWith("Dir")) {
String prop = (String) nextLocalPropMap.get(nextKey);
char lastChar = prop.charAt(prop.length() - 1);
if (Character.isLetterOrDigit(lastChar)) {
nextLocalPropMap.put(nextKey, prop + fileSeparator);
}
}
}
}
}
/**
* Save the props and their values in config file
*
* @param configFile
* the config file
*/
private void saveProps(File configFile) {
try {
PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(configFile), "UTF-8"), true);
out.println("# GlobalProperties:");
Set globalPropSet = props.keySet();
for (Iterator it = globalPropSet.iterator(); it.hasNext();) {
String key = it.next();
if (isEditable(key)) {
out.println(key + " " + props.get(key));
}
}
out.println();
for (int i = 0; i < compNames.length; i++) {
String key = compNames[i];
SortedMap nextProps = localProps.get(key);
if (nextProps != null) {
out.println("# Properties for module " + key + ":");
for (String localKey : nextProps.keySet()) {
out.println(localKey + " " + nextProps.get(localKey));
}
out.println();
}
}
out.close();
} catch (Exception e) {
throw new Error("Error writing config file", e);
}
}
/**
* Prompt the user for the basic props (This is called if we don't have any props)
*
* @param basicprops
* the map of props to be filled
*/
private boolean promptUserForBasicProps(SortedMap basicprops) {
initDefaultBasicProps(basicprops);
StringBuilder helpText = new StringBuilder();
helpText.append("\n\nSETTINGS HELP \n" + "\n\n\n");
for (Iterator it = props2Help.keySet().iterator(); it.hasNext();) {
String key = it.next();
String value = (String) props2Help.get(key);
helpText.append("- " + key + "
\n" + "- " + value + "
\n");
}
helpText.append("
\n\n");
return displayProps(basicprops, helpText.toString(), "Please adjust the following settings:");
}
/**
* @param basicprops
* basicprops
*/
private void initDefaultBasicProps(SortedMap basicprops) {
basicprops.put(MARYBASE, System.getProperty("MARYBASE", "/path/to/marybase/"));
basicprops.put(MARYBASEVERSION, Version.specificationVersion());
basicprops.put(VOICENAME, System.getProperty("VOICENAME", "my_voice"));
basicprops.put(GENDER, System.getProperty("GENDER", "female"));
basicprops.put(DOMAIN, "general");
basicprops.put(ESTDIR, System.getProperty("ESTDIR", "/project/mary/Festival/speech_tools/"));
basicprops.put(LOCALE, System.getProperty("LOCALE", "en_US"));
basicprops.put(SAMPLINGRATE, "16000");
String rootDir = voiceDir.getAbsolutePath() + fileSeparator;
basicprops.put(ROOTDIR, rootDir.substring(0, rootDir.length() - 1));
basicprops.put(WAVDIR, rootDir + "wav" + fileSeparator);
basicprops.put(LABDIR, rootDir + "lab" + fileSeparator);
basicprops.put(LABEXT, ".lab");
basicprops.put(HALFPHONELABEXT, ".hplab");
basicprops.put(TEXTDIR, rootDir + "text" + fileSeparator);
basicprops.put(TEXTEXT, ".txt");
basicprops.put(PMDIR, rootDir + "pm" + fileSeparator);
basicprops.put(PMEXT, ".pm");
basicprops.put(PTCDIR, rootDir + "ptc" + fileSeparator);
basicprops.put(PTCEXT, ".ptc");
basicprops.put(MARYSERVERHOST, "localhost");
basicprops.put(MARYSERVERPORT, "59125");
}
/**
* Init the default props of the database layout (the props that are not set during promptUserForBasicProps)
*
* @param someProps
* the map of props to be filled
* @param withBasicProps
* withBasicProps
* @return the map of default props
*/
private SortedMap initDefaultProps(SortedMap someProps, boolean withBasicProps) {
if (withBasicProps) {
initDefaultBasicProps(someProps);
}
String rootDir = getProp(ROOTDIR);
char lastChar = rootDir.charAt(rootDir.length() - 1);
if (Character.isLetterOrDigit(lastChar)) {
rootDir = rootDir + fileSeparator;
someProps.put(ROOTDIR, rootDir);
}
someProps.put(CONFIGDIR, rootDir + "mary" + fileSeparator);
someProps.put(FILEDIR, rootDir + "mary" + fileSeparator);
someProps.put(MARYEXT, ".mry");
someProps.put(BASENAMEFILE, rootDir + "basenames.lst");
someProps.put(TEMPDIR, rootDir + "temp" + fileSeparator);
someProps.put(MARYXMLDIR, rootDir + "rawmaryxml" + fileSeparator);
someProps.put(MARYXMLEXT, ".xml");
someProps.put(PROMPTALLOPHONESDIR, rootDir + "prompt_allophones" + fileSeparator);
someProps.put(ALLOPHONESDIR, rootDir + "allophones" + fileSeparator);
someProps.put(WAVEXT, ".wav");
someProps.put(PHONELABDIR, rootDir + "phonelab" + fileSeparator);
someProps.put(PHONEFEATUREDIR, rootDir + "phonefeatures" + fileSeparator);
someProps.put(HALFPHONELABDIR, rootDir + "halfphonelab" + fileSeparator);
someProps.put(HALFPHONEFEATUREDIR, rootDir + "halfphonefeatures" + fileSeparator);
someProps.put(VOCALIZATIONSDIR, rootDir + "vocalizations" + fileSeparator);
return someProps;
}
/**
* Get the default props+values from the components
*
* @return the default props of the components
*/
private SortedMap> getDefaultPropsFromComps() {
SortedMap> myLocalProps = new TreeMap>();
for (int i = 0; i < components.length; i++) {
VoiceImportComponent nextComp = components[i];
SortedMap nextProps = nextComp.getDefaultProps(this);
// get the name of the component
String name = nextComp.getName();
myLocalProps.put(name, nextProps);
}
return myLocalProps;
}
/**
* Make sure that we have all files and dirs that we will need
*/
private void assureFileIntegrity() {
/* check root dir */
checkDir(ROOTDIR);
/* check file dir */
checkDir(FILEDIR);
/* check config dir */
checkDir(CONFIGDIR);
/* check temp dir */
checkDir(TEMPDIR);
/* check maryxml dir */
checkDir(MARYXMLDIR);
checkDir(PROMPTALLOPHONESDIR);
checkDir(ALLOPHONESDIR);
/* check text dir */
// checkDir(TEXTDIR);
checkDirinCurrentDir(TEXTDIR);
/* check wav dir */
File dir = new File(getProp(WAVDIR));
// System.out.println(System.getProperty("user.dir")+System.getProperty("file.separator")+getProp(WAVDIR));
if (!dir.exists()) {
throw new Error("WAVDIR " + getProp(WAVDIR) + " does not exist!");
}
if (!dir.isDirectory()) {
throw new Error("WAVDIR " + getProp(WAVDIR) + " is not a directory!");
}
/* check lab dir */
// checkDir(LABDIR);
checkDirinCurrentDir(LABDIR);
// dir = new File(getProp(LABDIR));
}
/**
* Test if a directory exists and try to create it if not; throws an error if the dir can not be created
*
* @param propname
* the prop containing the name of the dir
*/
private void checkDir(String propname) {
File dir = new File(getProp(propname));
if (!dir.exists()) {
System.out.print(propname + " " + getProp(propname) + " does not exist; ");
if (!dir.mkdir()) {
throw new Error("Could not create " + propname);
}
System.out.print("Created successfully.\n");
}
if (!dir.isDirectory()) {
throw new Error(propname + " " + getProp(propname) + " is not a directory!");
}
}
/**
* Test if a directory exists and try to create it if not; throws an error if the dir can not be created
*
* @param propname
* the prop containing the name of the dir
*/
private void checkDirinCurrentDir(String propname) {
File dir = new File(getProp(propname));
if (!dir.exists()) {
System.out.print(propname + " " + getProp(propname) + " does not exist; ");
if (!dir.mkdir()) {
throw new Error("Could not create " + propname);
}
System.out.print("Created successfully.\n");
}
if (!dir.isDirectory()) {
throw new Error(propname + " " + getProp(propname) + " is not a directory!");
}
}
/**
* Load the basenamelist
*/
private void loadBasenameList() {
// test if basenamelist file exists
File basenameFile = new File(getProp(BASENAMEFILE));
if (!basenameFile.exists()) {
// make basename list from wav files
System.out.println("Loading basename list from wav files");
// bnl = new BasenameList(getProp(WAVDIR),getProp(WAVEXT));
bnl = new BasenameList(getProp(WAVDIR), getProp(WAVEXT));
} else {
// load basename list from file
try {
System.out.println("Loading basename list from file " + getProp(BASENAMEFILE));
bnl = new BasenameList(getProp(BASENAMEFILE));
} catch (IOException ioe) {
throw new Error("Error loading basenames from file " + getProp(BASENAMEFILE) + ": " + ioe.getMessage());
}
}
System.out.println("Found " + bnl.getLength() + " files in basename list");
}
/**
* Initialize the components
*
* @throws Exception
* Exception
*/
private void initializeComps() throws Exception {
for (int i = 0; i < components.length; i++) {
SortedMap nextProps = localProps.get(compNames[i]);
components[i].initialise(this, bnl, nextProps);
}
}
/**
* Get the value of a property from the voice building DatabaseLayout, or from a VoiceImportComponent.
*
* @param propertyName
* (e.g. "db.MARYBASE" or "VoicePackager.voiceType")
* @return the property value
* @throws NullPointerException
* if propertyName cannot be resolved
*/
public String getProperty(String propertyName) {
String[] propertyNameParts = propertyName.split("\\.");
String component = propertyNameParts[0];
String property = propertyNameParts[1];
String value;
if (component.equals("db")) {
value = this.getProp(propertyName);
} else {
VoiceImportComponent voiceImportComponent = this.getComponent(component);
value = voiceImportComponent.getProp(propertyName);
}
if (value == null) {
throw new NullPointerException(propertyName + " cannot be resolved!");
}
return value;
}
public String getProp(String prop) {
return props.get(prop);
}
public void setProp(String prop, String val) {
props.put(prop, val);
}
public String getExternal(String prop) {
if (external != null)
return external.get(prop);
else
return null;
}
public boolean isEditable(String propname) {
return !uneditableProps.contains(propname);
}
public boolean isInitialized() {
return initialized;
}
/**
* Get all props of all components as an Array representation for displaying with the SettingsGUI. Does not include uneditable
* props.
*
* @return result
*/
public String[][] getAllPropsForDisplay() {
List keys = new ArrayList();
List values = new ArrayList();
for (String key : props.keySet()) {
keys.add(key);
values.add(props.get(key));
}
for (int i = 0; i < compNames.length; i++) {
SortedMap nextProps = localProps.get(compNames[i]);
if (nextProps != null) { // some components don't have any properties
for (String key : nextProps.keySet()) {
keys.add(key);
values.add(nextProps.get(key));
}
}
}
String[][] result = new String[keys.size()][];
for (int i = 0; i < result.length; i++) {
String[] keyAndValue = new String[2];
keyAndValue[0] = (String) keys.get(i);
keyAndValue[1] = (String) values.get(i);
result[i] = keyAndValue;
}
return result;
}
/**
* Update the old props with the given props
*
* @param newprops
* the new props
*/
public void updateProps(String[][] newprops) {
for (int i = 0; i < newprops.length; i++) {
String[] keyAndValue = newprops[i];
String key = keyAndValue[0];
String value = keyAndValue[1];
// find out if this is a global or a local prop
if (key.startsWith("db.")) {
// global prop
if (isEditable(key))
setProp(key, value);
} else {
// local prop: get the name of the component
String compName = key;
try {
compName = key.substring(0, key.indexOf('.'));
} catch (Exception e) {
e.printStackTrace();
System.out.println("Found malformed property key: " + key);
}
// update our representation of local props for this component
if (localProps.containsKey(compName)) {
localProps.get(compName).put(key, value);
} else {
SortedMap keys2values = new TreeMap();
keys2values.put(key, value);
localProps.put(compName, keys2values);
}
// update the representation of props in the component
compnames2comps.get(compName).setProp(key, value);
}
}
// finally, save everything in config file
if (initialized) {
saveProps(configFile);
}
}
public void initialiseComponent(VoiceImportComponent vic) throws Exception {
String name = vic.getName();
SortedMap defaultProps = vic.getDefaultProps(this);
if (!compnames2comps.containsKey(name)) {
System.out.println("comp " + name + " not in db");
vic.setupHelp();
if (!displayProps(defaultProps, vic.getHelpText(), "The following properties are missing:"))
return;
saveProps(configFile);
}
vic.initialise(this, bnl, localProps.get(name));
}
public BasenameList getBasenames() {
return bnl;
}
public String[] getCompNamesForDisplay() {
String[] names = new String[compNames.length + 1];
names[0] = "Global properties";
String[] sortedCompNames = new String[compNames.length];
System.arraycopy(compNames, 0, sortedCompNames, 0, compNames.length);
Arrays.sort(sortedCompNames);
for (int i = 1; i < names.length; i++) {
names[i] = sortedCompNames[i - 1];
}
return names;
}
private boolean displayProps(SortedMap/* > */someProps, String helpText,
String guiText) {
try {
SettingsGUI gui = new SettingsGUI(this, someProps, helpText, guiText);
return gui.wasSaved();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Can not display props");
return false;
}
}
public Map getComps2HelpText() {
Map comps2HelpText = new HashMap();
StringBuilder helpText = new StringBuilder();
helpText.append("\n\nSETTINGS HELP \n" + "\n\n\n");
for (Iterator it = props2Help.keySet().iterator(); it.hasNext();) {
String key = it.next();
String value = (String) props2Help.get(key);
helpText.append("- " + key + "
\n" + "- " + value + "
\n");
}
helpText.append("
\n\n");
comps2HelpText.put("Global properties", helpText.toString());
for (int i = 0; i < components.length; i++) {
comps2HelpText.put(compNames[i], components[i].getHelpText());
}
return comps2HelpText;
}
// ///////// A number of useful getters of general interest /////////////////
public Locale getLocale() {
return locale;
}
public AllophoneSet getAllophoneSet() {
return allophoneSet;
}
public File getVoiceDir() {
return voiceDir;
}
public String getXMLCompatibleLocaleString() {
return MaryUtils.locale2xmllang(locale);
}
public String getVoiceName() {
return getProp(VOICENAME).toLowerCase();
}
public File getVoiceFileDir() {
return new File(getProp(FILEDIR));
}
public String getMaryVersion() {
return getProp(MARYBASEVERSION);
}
public String getGender() {
return getProp(GENDER).toLowerCase();
}
public String getDomain() {
return getProp(DOMAIN).toLowerCase();
}
public int getSamplingRate() {
return Integer.parseInt(getProp(SAMPLINGRATE));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy