/**
* Copyright 1998-2001 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*/
package com.sun.speech.engine.synthesis;
import java.util.List;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
/**
* Maintains a list of JSAPI 1.0 <code>Voices</code>.
*/
public class VoiceList {
/**
* The list of <code>Voices</code>.
*/
protected final List voiceList;
/**
* Class constructor.
*/
public VoiceList() {
voiceList = new java.util.ArrayList();
}
/**
* Constructs from the voice list in <code>desc</code>.
* Requires that all voices in mode desc be instances of
* <code>BaseVoice</code>.
*
* @param desc the <code>SynthesizerModeDesc</code> to get voices from
*/
public VoiceList(SynthesizerModeDesc desc) {
voiceList = new java.util.ArrayList();
Voice[] v = desc.getVoices();
if (v != null) {
for (int i = 0; i < v.length; i++) {
addVoice((BaseVoice)(v[i]));
}
}
}
/**
* Adds a voice to the list.
*
* @param voice the voice to add
*
* @see #removeVoice
*/
public void addVoice(BaseVoice voice) {
if (!voiceList.contains(voice)) {
voiceList.add(voice);
}
}
/**
* Removes a voice from the list.
*
* @param voice the voice to remove
*
* @see #addVoice
*/
public void removeVoice(BaseVoice voice) {
voiceList.remove(voice);
}
/**
* Gets a voice by its identifier.
*
* @param id the voice id
*
* @return the voice if it exists; otherwise <code>null</code>
*
* @see BaseVoice#getId
*/
public BaseVoice getVoiceById(String id) {
for (int i = 0; i < voiceList.size(); i++) {
BaseVoice bv = (BaseVoice)(voiceList.get(i));
if (bv.getId().equals(id)) {
return bv;
}
}
return null;
}
/**
* Gets the id of a voice.
*
* @param voice the voice
* @param variant the voice variant
*
* @return the id of the voice
*/
public String getVoiceId(Voice voice, int variant) {
// If voice is a BaseVoice simply return its id.
//
if (voice instanceof BaseVoice) {
BaseVoice bv = (BaseVoice)voice;
String id = bv.getId();
if (id != null && id.length() > 0) {
return id;
}
}
// Build a list of indicies of all matching voices.
// If variant is <= 0 return with first match
//
int indexes[] = new int[voiceList.size()];
int count = 0;
for (int i=0; i<voiceList.size(); i++) {
BaseVoice bv = (BaseVoice)(voiceList.get(i));
if (bv.match(voice)) {
if (variant <= 0) {
return bv.getId();
}
indexes[count++] = i;
}
}
// If no matches, return "".
if (count == 0) {
return "";
}
// Apply modulo to select variant in list
variant = (variant - 1) % count;
// Return the selected voice id.
BaseVoice bv = (BaseVoice)(voiceList.get(indexes[variant]));
return bv.getId();
}
/**
* Gets id for voice based on parameters provided in JSML.
* Priority to voice name. Then try to match age and gender plus
* variant.
*
* @param name the voice name
* @param gender the gender
* @param age the age
* @param variant the variant
*
* @return the voice id
*
* @see BaseVoice
* @see Voice
*/
public String getVoiceId(String name, int gender, int age, int variant) {
String id;
// Is there a match by voice name? If yes, return it.
// Otherwise, ignore name.
if (name != null && name.length() > 0) {
id = getVoiceId(new Voice(name,
Voice.GENDER_DONT_CARE,
Voice.AGE_DONT_CARE,
null),
0);
if (id != null && id.length() > 0) {
return id;
}
}
// Try to match gender and age
id = getVoiceId(new Voice(null,
gender,
age,
null),
variant);
if (id != null && id.length() > 0) {
return id;
}
// Try to match gender and adjoining ages
int looseAge = age | (age << 1) | (age >> 1);
id = getVoiceId(new Voice(null,
gender,
looseAge,
null),
variant);
if (id != null && id.length() > 0) {
return id;
}
// Try to match just gender
id = getVoiceId(new Voice(null,
gender,
Voice.AGE_DONT_CARE,
null),
variant);
if (id != null && id.length() > 0) {
return id;
}
// Failed match
return "";
}
}