// Open Mbrola
Process process;
try {
process = Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
throw new ProcessException("Cannot start mbrola program: " + cmd);
}
PrintWriter toMbrola = new PrintWriter(process.getOutputStream());
BufferedInputStream fromMbrola =
new BufferedInputStream(process.getInputStream());
while (segment != null) {
String name = segment.getFeatures().getString("name");
// Individual duration of segment, in milliseconds:
int dur = segment.getFeatures().getInt("mbr_dur");
// List of time-f0 targets. In each target, the first value
// indicates where on the time axis the target is reached,
// expressed in percent of segment duration; the second value in
// each pair is f0, in Hz.
String targets = segment.getFeatures().getString("mbr_targets");
String output = (name + " " + dur + " " + targets);
// System.out.println(output);
toMbrola.println(output);
segment = segment.getNext();
}
toMbrola.flush();
// BUG:
// There is a bug that causes the final 'close' on a stream
// going to a sub-process to not be seen by the sub-process on
// occasion. This seems to occur mainly when the close occurs
// very soon after the creation and writing of data to the
// sub-process. This delay can help work around the problem
// If we delay before the close by
// a small amount (100ms), the hang is averted. This is a WORKAROUND
// only and should be removed once the bug in the 'exec' is
// fixed. We get the delay from the property:
//
// de.dfki.lt.freetts.mbrola.MbrolaCaller.closeDelay,
//
if (closeDelay > 0l) {
try {
Thread.sleep(closeDelay);
} catch (InterruptedException ie) {
}
}
toMbrola.close();
// reading the audio output
byte[] buffer = new byte[1024];
// In order to avoid resizing a large array, we save the audio data
// in the chunks in which we read it.
List audioData = new java.util.ArrayList();
int totalSize = 0;
int nrRead = -1; // -1 means end of file
try {
while ((nrRead = fromMbrola.read(buffer)) != -1) {
if (nrRead < buffer.length) {
byte[] slice = new byte[nrRead];
System.arraycopy(buffer, 0, slice, 0, nrRead);
audioData.add(slice);
} else {
audioData.add(buffer);
buffer = new byte[buffer.length];
}
totalSize += nrRead;
}
fromMbrola.close();
} catch (IOException e) {
throw new ProcessException("Cannot read from mbrola");
}
if (totalSize == 0) {
throw new ProcessException("No audio data read");
}
utterance.setObject("mbrolaAudio", audioData);
utterance.setInt("mbrolaAudioLength", totalSize);
}