upstream version 1.2.2
[debian/freetts] / com / sun / speech / engine / synthesis / VoiceList.java
1 /**
2  * Copyright 1998-2001 Sun Microsystems, Inc.
3  * 
4  * See the file "license.terms" for information on usage and
5  * redistribution of this file, and for a DISCLAIMER OF ALL 
6  * WARRANTIES.
7  */
8 package com.sun.speech.engine.synthesis;
9
10 import java.util.List;
11
12 import javax.speech.synthesis.SynthesizerModeDesc;
13 import javax.speech.synthesis.Voice;
14
15 /**
16  * Maintains a list of JSAPI 1.0 <code>Voices</code>.
17  */
18 public class VoiceList {
19
20     /**
21      * The list of <code>Voices</code>.
22      */
23     protected final List voiceList;
24     
25     /**
26      * Class constructor.
27      */
28     public VoiceList() {
29         voiceList = new java.util.ArrayList();
30     }
31     
32     /**
33      * Constructs from the voice list in <code>desc</code>.
34      * Requires that all voices in mode desc be instances of
35      * <code>BaseVoice</code>.
36      *
37      * @param desc the <code>SynthesizerModeDesc</code> to get voices from
38      */
39     public VoiceList(SynthesizerModeDesc desc) {
40         voiceList = new java.util.ArrayList();
41         
42         Voice[] v = desc.getVoices();
43         
44         if (v != null) {
45             for (int i = 0; i < v.length; i++) {
46                 addVoice((BaseVoice)(v[i]));
47             }
48         }
49     }
50
51     /**
52      * Adds a voice to the list.
53      *
54      * @param voice the voice to add
55      *
56      * @see #removeVoice
57      */
58     public void addVoice(BaseVoice voice) {
59         if (!voiceList.contains(voice)) {
60             voiceList.add(voice);
61         }
62     }
63
64     /**
65      * Removes a voice from the list.
66      *
67      * @param voice the voice to remove
68      *
69      * @see #addVoice
70      */
71     public void removeVoice(BaseVoice voice) {
72         voiceList.remove(voice);
73     }
74
75     /**
76      * Gets a voice by its identifier.
77      *
78      * @param id the voice id
79      *
80      * @return the voice if it exists; otherwise <code>null</code>
81      *
82      * @see BaseVoice#getId
83      */
84     public BaseVoice getVoiceById(String id) {
85         for (int i = 0; i < voiceList.size(); i++) {
86             BaseVoice bv = (BaseVoice)(voiceList.get(i));
87             if (bv.getId().equals(id)) {
88                 return bv;
89             }
90         }   
91         return null;
92     }
93
94     /**
95      * Gets the id of a voice.
96      *
97      * @param voice the voice
98      * @param variant the voice variant
99      *
100      * @return the id of the voice
101      */
102     public String getVoiceId(Voice voice, int variant) {
103         // If voice is a BaseVoice simply return its id.
104         //
105         if (voice instanceof BaseVoice) {
106             BaseVoice bv = (BaseVoice)voice;
107             String id = bv.getId();
108             if (id != null && id.length() > 0) {
109                 return id;
110             }
111         }
112         
113         // Build a list of indicies of all matching voices.
114         // If variant is <= 0 return with first match
115         //
116         int indexes[] = new int[voiceList.size()];
117         int count = 0;
118         
119         for (int i=0; i<voiceList.size(); i++) {
120             BaseVoice bv = (BaseVoice)(voiceList.get(i));
121             if (bv.match(voice)) {
122                 if (variant <= 0) {
123                     return bv.getId();
124                 }
125                 indexes[count++] = i;
126             }
127         }
128         
129         // If no matches, return "".
130         if (count == 0) {
131             return "";
132         }
133             
134         // Apply modulo to select variant in list
135         variant = (variant - 1) % count;
136         
137         // Return the selected voice id.
138         BaseVoice bv = (BaseVoice)(voiceList.get(indexes[variant]));
139         return bv.getId();
140     }    
141
142     /**
143      * Gets id for voice based on parameters provided in JSML.
144      * Priority to voice name.  Then try to match age and gender plus
145      * variant.
146      *
147      * @param name the voice name
148      * @param gender the gender
149      * @param age the age
150      * @param variant the variant
151      *
152      * @return the voice id
153      *
154      * @see BaseVoice
155      * @see Voice
156      */
157     public String getVoiceId(String name, int gender, int age, int variant) {
158         String id;
159         
160         // Is there a match by voice name?  If yes, return it.
161         // Otherwise, ignore name.
162         if (name != null && name.length() > 0) {
163             id = getVoiceId(new Voice(name,
164                                       Voice.GENDER_DONT_CARE,
165                                       Voice.AGE_DONT_CARE,
166                                       null),
167                             0);
168             if (id != null && id.length() > 0) {
169                 return id;
170             }
171         }
172         
173
174         // Try to match gender and age
175         id = getVoiceId(new Voice(null,
176                                   gender,
177                                   age,
178                                   null),
179                         variant);
180         if (id != null && id.length() > 0) {
181             return id;
182         }
183
184         // Try to match gender and adjoining ages
185         int looseAge = age | (age << 1) | (age >> 1);
186         id = getVoiceId(new Voice(null,
187                                   gender,
188                                   looseAge,
189                                   null),
190                         variant);
191         if (id != null && id.length() > 0) {
192             return id;
193         }
194
195         // Try to match just gender
196         id = getVoiceId(new Voice(null,
197                                   gender,
198                                   Voice.AGE_DONT_CARE,
199                                   null),
200                         variant);
201         if (id != null && id.length() > 0) {
202             return id;
203         }
204
205         // Failed match
206         return "";
207     }    
208 }