upstream version 1.2.2
[debian/freetts] / tools / ArcticToFreeTTS / src / UnitDatabase.java
1 import java.io.BufferedReader;
2 import java.io.File;
3 import java.io.FileInputStream;
4 import java.io.FileOutputStream;
5 import java.io.InputStreamReader;
6 import java.io.IOException;
7 import java.io.PrintStream;
8
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.TreeSet;
13
14 /**
15  * Database containing both the Catalog and the Track Files.
16  */
17 public class UnitDatabase {
18     static float lpcMin;
19     static float lpcRange;
20     static float mcepMin;
21     static float mcepRange;
22
23     UnitCatalog unitCatalog;
24     HashMap sts;
25     HashMap mcep;
26
27     /**
28      * Creates a new UnitDatabase.
29      *
30      * @param unitCatalog the unit unitCatalog
31      * @param sts Track data from individual sts files, indexed by filename
32      * @param mcep Track data from individual mcep files, indexed by filename
33      */
34     public UnitDatabase(UnitCatalog unitCatalog, HashMap sts, HashMap mcep) {
35         this.unitCatalog = unitCatalog;
36         this.sts = sts;
37         this.mcep = mcep;
38     }
39     
40     /**
41      * Dumps Catalog to stdout.
42      */
43     void dumpUnitCatalog(PrintStream out) {
44         /* Sort the keys (which are the unit types)
45          */
46         Iterator keys = new TreeSet(unitCatalog.keySet()).iterator();
47
48         int currentIndex = 0;
49         
50         while (keys.hasNext()) {
51             String key = (String) keys.next();
52             ArrayList units = (ArrayList) unitCatalog.get(key);
53             out.println("UNIT_TYPE " + key
54                         + " " + currentIndex
55                         + " " + units.size());
56             currentIndex += units.size();
57         }
58     }
59     
60     public void dumpUnitCatalog(String filename) throws IOException {
61         PrintStream out = new PrintStream(new FileOutputStream(filename));
62         dumpUnitCatalog(out);
63         out.close();
64     }
65
66     /**
67      * Gets the LPC metadata
68      */
69     static void getLPCParams() throws IOException {
70         BufferedReader reader =
71             new BufferedReader(
72                 new InputStreamReader(
73                     new FileInputStream("lpc/lpc.params")));
74         String line = reader.readLine();
75         while (line != null) {
76             if (line.startsWith("LPC_MIN=")) {
77                 lpcMin = Float.parseFloat(line.substring(8));
78             } else if (line.startsWith("LPC_RANGE=")) {
79                 lpcRange = Float.parseFloat(line.substring(10));
80             }
81             line = reader.readLine();
82         }
83         reader.close();        
84     }
85     
86     /**
87      * Gets the MCEP metadata
88      */
89     static void getMCEPParams() throws IOException {
90         BufferedReader reader =
91             new BufferedReader(
92                 new InputStreamReader(
93                     new FileInputStream("mcep/mcep.params")));
94         String line = reader.readLine();
95         while (line != null) {
96             if (line.startsWith("MCEP_MIN=")) {
97                 mcepMin = Float.parseFloat(line.substring(9));
98             } else if (line.startsWith("MCEP_RANGE=")) {
99                 mcepRange = Float.parseFloat(line.substring(11));
100             }
101             line = reader.readLine();
102         }
103         reader.close();        
104     }
105         
106     /**
107      * Dumps the sts and mcep data.
108      */
109     void dumpVoiceData(PrintStream stsOut, PrintStream mcepOut)
110         throws IOException {
111         int sampleRate = 0;
112         int numLPCChannels = 0;
113         int numMCEPChannels = 0;
114         
115         /* Sort the keys (which are the filenames)
116          */
117         Iterator keys = new TreeSet(sts.keySet()).iterator();
118
119         int numFrames = 0;
120         while (keys.hasNext()) {
121             String filename = (String) keys.next();
122             Track track = (Track) sts.get(filename);
123             sampleRate = track.sampleRate;
124             numLPCChannels = track.numChannels;
125             numFrames += track.numFrames;
126             
127             track = (Track) mcep.get(filename);
128             numMCEPChannels = track.numChannels;
129         }
130
131         /* [[[WDW FIXME: has hardcoded data.]]]
132          */
133         stsOut.println("STS STS " + numFrames
134                        + " " + numLPCChannels
135                        + " " + sampleRate
136                        + " " + lpcMin + " " + lpcRange
137                        + " 0.000000 1"); /* postEmph and residualFold */
138         
139         mcepOut.println("STS MCEP " + numFrames
140                         + " " + numMCEPChannels
141                         + " " + sampleRate
142                         + " " + mcepMin + " " + mcepRange
143                         + " 0.000000 1"); /* postEmph and residualFold */
144
145         keys = new TreeSet(sts.keySet()).iterator();
146         int currentIndex = 0;        
147         while (keys.hasNext()) {
148             String filename = (String) keys.next();
149             
150             Track track = (Track) sts.get(filename);
151             track.startIndex = currentIndex;
152             track.dumpData(stsOut);
153
154             track = (Track) mcep.get(filename);
155             track.startIndex = currentIndex;
156             track.dumpData(mcepOut);
157             
158             currentIndex += track.numFrames;
159         }
160     }
161
162     /**
163      * Dumps the unit index.
164      */
165     public void dumpUnitIndex(PrintStream unitIndexOut,
166                               PrintStream stsOut,
167                               PrintStream mcepOut) throws IOException {
168
169         System.out.println("  Dumping STS and MCEP tracks");        
170         dumpVoiceData(stsOut, mcepOut);
171
172         System.out.println("  Dumping unit index");
173         
174         /* Sort the keys (which are the unit_types)
175          */
176         Iterator keys = new TreeSet(unitCatalog.keySet()).iterator();
177
178         int unitTypeIndex = 0;
179         int phoneNumber = 0; /* just to guarantee some difference */
180         
181         while (keys.hasNext()) {
182             String unitType = (String) keys.next();
183             ArrayList units = (ArrayList) unitCatalog.get(unitType);
184             
185             for (int i = 0; i < units.size(); i++) {
186                 Unit unit = (Unit) units.get(i);
187                 Track track = (Track) sts.get(unit.filename);
188                 int startIndex = track.findTrackFrameIndex(unit.start);
189                 int endIndex = track.findTrackFrameIndex(unit.end);
190                 unitIndexOut.println(
191                     "UNITS " + unitTypeIndex
192                     + " " + phoneNumber
193                     + " " + (startIndex + track.startIndex)
194                     + " " + (endIndex + track.startIndex)
195                     + " "
196                     + ((unit.previous != null) ? unit.previous.index : 65535)
197                     + " "
198                     + ((unit.next != null) ? unit.next.index : 65535));
199
200                 if (false) {
201                     System.out.println(
202                         "  " 
203                         + ((unit.previous != null)
204                            ? unit.previous.toString()
205                            : "CLUNIT_NONE"));
206                     System.out.println(
207                         "  " + unit);
208                     System.out.println(
209                         "  "  
210                         + ((unit.next != null)
211                            ? unit.next.toString()
212                            : "CLUNIT_NONE"));                
213                 }
214                 phoneNumber++;
215             }
216             unitTypeIndex++;
217         }        
218     }
219
220     public void dumpUnitIndex(String unitIndexFilename,
221                               String stsFilename,
222                               String mcepFilename) throws IOException {
223         PrintStream unitIndexOut = new PrintStream(
224             new FileOutputStream(unitIndexFilename));
225         PrintStream stsOut = new PrintStream(
226             new FileOutputStream(stsFilename));
227         PrintStream mcepOut = new PrintStream(
228             new FileOutputStream(mcepFilename));
229         
230         dumpUnitIndex(unitIndexOut, stsOut, mcepOut);
231         
232         unitIndexOut.close();
233         stsOut.close();
234         mcepOut.close();
235     }
236     
237     /**
238      * Testing.  args[0] = *.catalog file
239      *           args[1..n] = * files (no path or suffix - the code
240      *                        will add sts/file.sts and
241      *                        mcep/file.mcep.txt                        
242      */
243     static public void main(String[] args) {
244         try {
245             System.out.println("Reading " + args[0]);
246             UnitCatalog unitCatalog = new UnitCatalog(args[0]);
247
248             /* Store the TrackFile in the sts and mcep HashMaps
249              * indexed by the filename.
250              */
251             System.out.println("Reading STS and MCEP files");
252             getLPCParams();
253             getMCEPParams();
254         
255             HashMap sts = new HashMap();
256             HashMap mcep = new HashMap();
257             for (int i = 1; i < args.length; i++) {
258                 sts.put(
259                     args[i],
260                     new Track("sts/" + args[i] + ".sts",
261                               Track.STS));
262                 mcep.put(
263                     args[i],
264                     new Track("mcep/" + args[i] + ".mcep.txt",
265                               Track.MCEP,
266                               mcepMin,
267                               mcepRange));
268             }
269
270             UnitDatabase database = new UnitDatabase(unitCatalog, sts, mcep);
271
272             System.out.println("Creating FreeTTS/unit_catalog");
273             database.dumpUnitCatalog("FreeTTS/unit_catalog.txt");
274
275             System.out.println(
276                 "Creating FreeTTS/unit_index.txt, FreeTTS/sts.txt, and "
277                 + "FreeTTS/mcep.txt");
278             
279             database.dumpUnitIndex("FreeTTS/unit_index.txt",
280                                    "FreeTTS/sts.txt",
281                                    "FreeTTS/mcep.txt");
282
283             System.out.println("Done!");
284         } catch (Exception e) {
285             e.printStackTrace();
286         }
287     }
288 }