All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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