marytts.client.MaryFormData 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.client;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFileFormat.Type;
import marytts.util.MaryUtils;
import marytts.util.data.audio.MaryAudioUtils;
import marytts.util.http.Address;
import marytts.util.math.MathUtils;
import marytts.util.string.StringUtils;
/**
*
* This class nests all the information and functions that a Mary client needs to receive/send data from/to server. To be able to
* use the functionality provided by this class, all Mary clients should either: (i) extend this class (Example: MaryHttpClient,
* MaryWebHttpClient) (ii) use an object of type MaryHttpForm or of a derived class (Example: MaryGUIClient)
*
* @author Oytun Türk
*/
public class MaryFormData {
// Default values which can be overridden from the command line.
private final String DEFAULT_HOST = "localhost";
private final int DEFAULT_PORT = 59125;
public Address hostAddress = null;
public String serverVersionInfo = null;
public String serverVersionNo = "unknown";
public boolean serverCanStream = false;
public Vector allVoices;
public Map> voicesByLocaleMap;
public Map> limitedDomainVoices;
public Set locales;
public Vector allDataTypes;
public Vector inputDataTypes;
public Vector outputDataTypes;
public Map serverExampleTexts;
public String currentExampleText;
public Map> voiceExampleTextsLimitedDomain;
public Map voiceExampleTextsGeneralDomain;
public Map audioEffectHelpTextsMap;
public Vector audioFileFormatTypes;
public Vector audioOutTypes;
public String inputText;
public String outputText;
public String errorMessage;
public boolean isOutputText;
public int voiceSelected;
public int inputTypeSelected;
public int outputTypeSelected;
public int audioFormatSelected;
public int audioOutSelected;
public int limitedDomainExampleTextSelected;
public String audioEffects;
public String audioEffectsHelpTextLineBreak;
public AudioEffectsBoxData effectsBoxData;
public Vector limitedDomainExampleTexts;
public Map keyValuePairs; // Key-Value pairs for communication with server
public String outputAudioResponseID; // output audio file for web browser client
public String mimeType; // MIME type for output audio (web browser clients)
public MaryFormData() {
String serverHost = System.getProperty("server.host", DEFAULT_HOST);
int serverPort = 0;
String helperString = System.getProperty("server.port");
if (helperString != null)
serverPort = Integer.decode(helperString).intValue();
else
serverPort = DEFAULT_PORT;
Address serverAddress = new Address(serverHost, serverPort);
init(serverAddress, null, null, null, null, null, null, null, null);
}
public MaryFormData(Address serverAddress) {
init(serverAddress, null, null, null, null, null, null, null, null);
}
public MaryFormData(Address serverAddress, String versionIn, String voicesIn, String dataTypesIn,
String audioFileFormatTypesIn, String audioEffectHelpTextLineBreakIn, String defaultAudioEffects,
Vector defaultVoiceExampleTexts) {
this(serverAddress, null, versionIn, voicesIn, dataTypesIn, audioFileFormatTypesIn, audioEffectHelpTextLineBreakIn,
defaultAudioEffects, defaultVoiceExampleTexts);
}
public MaryFormData(Address serverAddress, Map keyValuePairsIn, String versionIn, String voicesIn,
String dataTypesIn, String audioFileFormatTypesIn, String audioEffectHelpTextLineBreakIn, String defaultAudioEffects,
Vector defaultVoiceExampleTexts) {
init(serverAddress, keyValuePairsIn, versionIn, voicesIn, dataTypesIn, audioFileFormatTypesIn,
audioEffectHelpTextLineBreakIn, defaultAudioEffects, defaultVoiceExampleTexts);
}
public void init(Address serverAddress, Map keyValuePairsIn, String versionIn, String voicesIn,
String dataTypesIn, String audioFileFormatTypesIn, String audioEffectHelpTextLineBreakIn, String defaultAudioEffects,
Vector defaultVoiceExampleTexts) {
outputAudioResponseID = "";
mimeType = "";
hostAddress = null;
serverVersionInfo = null;
serverVersionNo = "unknown";
serverCanStream = false;
allVoices = null;
voicesByLocaleMap = null;
limitedDomainVoices = new HashMap>();
allDataTypes = null;
inputDataTypes = null;
outputDataTypes = null;
serverExampleTexts = new HashMap();
currentExampleText = "";
voiceExampleTextsLimitedDomain = new HashMap>();
voiceExampleTextsGeneralDomain = new HashMap();
audioEffectHelpTextsMap = new HashMap();
audioFileFormatTypes = null;
audioOutTypes = null;
inputText = "";
outputText = "";
isOutputText = false;
voiceSelected = 0;
inputTypeSelected = 0;
outputTypeSelected = 0;
audioFormatSelected = 0;
audioOutSelected = 0;
limitedDomainExampleTextSelected = 0;
audioEffects = "";
audioEffectsHelpTextLineBreak = "";
effectsBoxData = null;
keyValuePairs = new HashMap();
limitedDomainExampleTexts = null;
hostAddress = serverAddress;
toServerVersionInfo(versionIn);
toVoices(voicesIn);
toDataTypes(dataTypesIn);
toAudioFileFormatAndOutTypes(audioFileFormatTypesIn);
toAudioEffectsHelpTextLineBreak(audioEffectHelpTextLineBreakIn);
toAudioEffects(defaultAudioEffects);
if (keyValuePairsIn != null) {
toSelections(keyValuePairsIn, defaultVoiceExampleTexts);
}
}
public void toServerVersionInfo(String info) {
serverVersionInfo = info;
serverVersionNo = "unknown";
if (serverVersionInfo != null) {
String[] parts = serverVersionInfo.split(" ");
if (parts[0].equals("Mary") && parts[1].equals("TTS") && parts[2].equals("server") && parts.length >= 4) {
// then parts[3] is the version number
serverVersionNo = parts[3];
}
}
if (serverVersionNo.equals("unknown") || serverVersionNo.compareTo("3.0.1") < 0) {
serverCanStream = false;
} else {
serverCanStream = true;
}
}
public void toVoices(String info) {
allVoices = null;
voicesByLocaleMap = null;
limitedDomainVoices = null;
if (info != null && info.length() > 0) {
allVoices = new Vector();
voicesByLocaleMap = new HashMap>();
limitedDomainVoices = new HashMap>();
String[] voiceStrings = info.split("\n");
for (int i = 0; i < voiceStrings.length; i++) {
StringTokenizer st = new StringTokenizer(voiceStrings[i]);
if (!st.hasMoreTokens())
continue; // ignore entry
String name = st.nextToken();
if (!st.hasMoreTokens())
continue; // ignore entry
String localeString = st.nextToken();
Locale locale = string2locale(localeString);
assert locale != null;
if (!st.hasMoreTokens())
continue; // ignore entry
String gender = st.nextToken();
MaryClient.Voice voice = null;
if (isServerVersionAtLeast("3.5.0")) {
String synthesizerType;
if (!st.hasMoreTokens())
synthesizerType = "non-specified";
else
synthesizerType = st.nextToken();
if (!st.hasMoreTokens()) {
// assume domain is general
voice = new MaryClient.Voice(name, locale, gender, "general");
} else {
// read in the domain
String domain = st.nextToken();
voice = new MaryClient.Voice(name, locale, gender, domain);
}
voice.setSynthesizerType(synthesizerType);
} else {
if (!st.hasMoreTokens()) {
// assume domain is general
voice = new MaryClient.Voice(name, locale, gender, "general");
} else {
// read in the domain
String domain = st.nextToken();
voice = new MaryClient.Voice(name, locale, gender, domain);
}
}
allVoices.add(voice);
Vector localeVoices = null;
if (voicesByLocaleMap.containsKey(locale)) {
localeVoices = voicesByLocaleMap.get(locale);
} else {
localeVoices = new Vector();
voicesByLocaleMap.put(locale, localeVoices);
}
localeVoices.add(voice);
}
}
}
public void toDataTypes(String info) {
allDataTypes = null;
inputDataTypes = null;
outputDataTypes = null;
if (info != null && info.length() > 0) {
allDataTypes = new Vector();
inputDataTypes = new Vector();
outputDataTypes = new Vector();
String[] typeStrings = info.split("\n");
for (int i = 0; i < typeStrings.length; i++) {
StringTokenizer st = new StringTokenizer(typeStrings[i]);
if (!st.hasMoreTokens())
continue; // ignore this type
String name = st.nextToken();
boolean isInputType = false;
boolean isOutputType = false;
Locale locale = null;
while (st.hasMoreTokens()) {
String t = st.nextToken();
if (t.equals("INPUT")) {
isInputType = true;
} else if (t.equals("OUTPUT")) {
isOutputType = true;
}
}
MaryClient.DataType dt = new MaryClient.DataType(name, isInputType, isOutputType);
allDataTypes.add(dt);
if (dt.isInputType()) {
inputDataTypes.add(dt);
}
if (dt.isOutputType()) {
outputDataTypes.add(dt);
}
}
}
}
public void toLocales(String info) {
locales = new HashSet();
for (String localeName : StringUtils.toStringArray(info)) {
locales.add(MaryUtils.string2locale(localeName));
}
}
public void toAudioFileFormatAndOutTypes(String info) {
// TODO: this method uses code which is meaningful only
// in the server (MaryAudioUtils.canCreateMP3() etc.).
// It should be moved into the server code.
audioFileFormatTypes = null;
audioOutTypes = null;
String[] allTypes = null;
int spaceInd;
if (info != null && info.length() > 0)
allTypes = StringUtils.toStringArray(info);
if (allTypes != null) {
for (int i = 0; i < allTypes.length; i++) {
spaceInd = allTypes[i].indexOf(' ');
String typeName = allTypes[i].substring(spaceInd + 1);
Type audioType = null;
boolean isSupported = true;
if (typeName.equals("MP3"))
isSupported = false; // MaryServerUtils.canCreateMP3();
else if (typeName.equals("Vorbis"))
isSupported = false; // MaryServerUtils.canCreateOgg();
try {
audioType = MaryAudioUtils.getAudioFileFormatType(typeName);
} catch (Exception e) {
isSupported = false;
}
if (isSupported && audioType != null && AudioSystem.isFileTypeSupported(audioType)) {
if (audioFileFormatTypes == null)
audioFileFormatTypes = new Vector();
audioFileFormatTypes.add(allTypes[i]);
if (audioOutTypes == null)
audioOutTypes = new Vector();
audioOutTypes.add(typeName + "_FILE");
if (typeName.compareTo("MP3") == 0)
audioOutTypes.add(typeName + "_STREAM");
}
}
}
}
public void toAudioEffectsHelpTextLineBreak(String strLineBreak) {
if (strLineBreak != null && strLineBreak.length() > 0)
audioEffectsHelpTextLineBreak = strLineBreak;
else
audioEffectsHelpTextLineBreak = null;
}
public void toAudioEffects(String availableAudioEffects) {
if (availableAudioEffects != null && availableAudioEffects.length() > 0)
audioEffects = availableAudioEffects;
else
audioEffects = null;
if (audioEffects != null && audioEffects.length() > 0)
effectsBoxData = new AudioEffectsBoxData(audioEffects);
else
effectsBoxData = null;
}
// Parse fullParamaters which is of the form key1=value1&key2=value2...
private void toSelections(Map keyValuePairsIn, Vector defaultVoiceExampleTexts) {
assert keyValuePairsIn != null;
keyValuePairs = keyValuePairsIn;
inputTypeSelected = 0;
inputText = "";
if (outputDataTypes != null && outputDataTypes.size() > 0)
outputTypeSelected = outputDataTypes.size() - 1;
else
outputTypeSelected = 0;
isOutputText = false;
outputText = "";
audioFormatSelected = 0;
voiceSelected = 0;
limitedDomainExampleTextSelected = 0;
if (effectsBoxData == null) {
/*
* if (audioEffectsHelpTextLineBreak==null) getAudioEffectHelpTextLineBreak(); if (audioEffects==null)
* getAudioEffects();
*/
effectsBoxData = new AudioEffectsBoxData(audioEffects);
}
int i;
String selected;
// Input type selected
selected = keyValuePairs.get("INPUT_TYPE");
if (selected != null) {
for (i = 0; i < inputDataTypes.size(); i++) {
if (inputDataTypes.get(i).name().compareTo(selected) == 0) {
inputTypeSelected = i;
break;
}
}
}
// Output type selected
selected = keyValuePairs.get("OUTPUT_TYPE");
if (selected != null) {
for (i = 0; i < outputDataTypes.size(); i++) {
if (outputDataTypes.get(i).name().compareTo(selected) == 0) {
outputTypeSelected = i;
break;
}
}
// Check if output type contains AUDIO
if (outputDataTypes.get(outputTypeSelected).name().contains("AUDIO"))
isOutputText = false;
else
isOutputText = true;
}
//
// Voice selected
selected = keyValuePairs.get("VOICE");
if (selected != null) {
for (i = 0; i < allVoices.size(); i++) {
if (allVoices.get(i).name().compareTo(selected) == 0) {
voiceSelected = i;
break;
}
}
}
//
// Limited domain example texts
if (allVoices != null && allVoices.size() > 0) {
if (allVoices.elementAt(voiceSelected).isLimitedDomain()) {
limitedDomainExampleTexts = defaultVoiceExampleTexts;
selected = keyValuePairs.get("exampletext");
if (limitedDomainExampleTexts != null && selected != null) {
for (i = 0; i < limitedDomainExampleTexts.size(); i++) {
if (limitedDomainExampleTexts.get(i).compareTo(selected) == 0) {
limitedDomainExampleTextSelected = i;
break;
}
}
} else {
limitedDomainExampleTextSelected = 0;
}
}
}
// Input text
selected = keyValuePairs.get("INPUT_TEXT");
if (selected != null)
inputText = selected;
else {
if (allVoices != null && allVoices.size() > 0 && inputDataTypes != null && inputDataTypes.size() > 0) {
if (allVoices.elementAt(voiceSelected).isLimitedDomain() && limitedDomainExampleTexts != null)
inputText = limitedDomainExampleTexts.get(limitedDomainExampleTextSelected);
else if (serverExampleTexts != null)
inputText = serverExampleTexts.get(inputDataTypes.get(inputTypeSelected).name() + " "
+ allVoices.elementAt(voiceSelected).getLocale().toString());
}
}
//
// Output text if non-audio output
if (isOutputText) {
selected = keyValuePairs.get("OUTPUT_TEXT");
if (selected != null)
outputText = selected;
}
//
// Audio out format selected:
// The clients can send audio format in two ways:
selected = keyValuePairs.get("AUDIO_OUT");
int spaceInd;
int scoreInd;
if (selected != null) {
scoreInd = selected.indexOf('_');
String selectedTypeName = selected.substring(scoreInd + 1);
for (i = 0; i < audioFileFormatTypes.size(); i++) {
spaceInd = audioFileFormatTypes.get(i).indexOf(' ');
String typeName = audioFileFormatTypes.get(i).substring(spaceInd + 1);
if (typeName.compareTo(selected) == 0) {
audioFormatSelected = i;
break;
}
}
for (i = 0; i < audioOutTypes.size(); i++) {
String typeName = audioOutTypes.get(i);
if (typeName.compareTo(selected) == 0) {
audioOutSelected = i;
break;
}
}
}
//
// Audio effects
String currentEffectName;
for (i = 0; i < effectsBoxData.getTotalEffects(); i++) {
currentEffectName = effectsBoxData.getControlData(i).getEffectName();
// Check box
selected = keyValuePairs.get("effect_" + currentEffectName + "_selected");
if (selected != null && selected.compareTo("on") == 0) // Effect is selected
effectsBoxData.getControlData(i).setSelected(true);
else
// If not found, effect is not selected
effectsBoxData.getControlData(i).setSelected(false);
//
// Parameters
selected = keyValuePairs.get("effect_" + currentEffectName + "_parameters");
if (selected != null) // Effect paramaters is there
effectsBoxData.getControlData(i).setParams(selected);
else
// If not found, something is wrong, set parameters to default
effectsBoxData.getControlData(i).setEffectParamsToExample();
//
}
}
public boolean isServerVersionAtLeast(String serverVersionToCompare) {
if (serverVersionNo.equals("unknown"))
return false;
int tmp = serverVersionNo.compareToIgnoreCase(serverVersionToCompare);
return tmp >= 0;
}
// Check if all selections are appropriately made, i.e. no array bounds exceeded etc
public void checkAndCorrectSelections() {
audioFormatSelected = MathUtils.CheckLimits(audioFormatSelected, 0, audioFileFormatTypes.size() - 1);
audioOutSelected = MathUtils.CheckLimits(audioOutSelected, 0, audioOutTypes.size() - 1);
inputTypeSelected = MathUtils.CheckLimits(inputTypeSelected, 0, inputDataTypes.size() - 1);
outputTypeSelected = MathUtils.CheckLimits(outputTypeSelected, 0, outputDataTypes.size() - 1);
voiceSelected = MathUtils.CheckLimits(voiceSelected, 0, allVoices.size() - 1);
}
/**
* This helper method converts a string (e.g., "en_US") into a proper Locale object.
*
* @param localeString
* a string representation of the locale
* @return a Locale object.
*/
public static Locale string2locale(String localeString) {
Locale locale = null;
StringTokenizer localeST = new StringTokenizer(localeString, "_");
String language = localeST.nextToken();
String country = "";
String variant = "";
if (localeST.hasMoreTokens()) {
country = localeST.nextToken();
if (localeST.hasMoreTokens()) {
variant = localeST.nextToken();
}
}
locale = new Locale(language, country, variant);
return locale;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy