2 * Copyright 2002 DFKI GmbH.
3 * All Rights Reserved. Use is subject to license terms.
5 * See the file "license.terms" for information on usage and
6 * redistribution of this file, and for a DISCLAIMER OF ALL
9 package de.dfki.lt.freetts.mbrola;
11 import java.nio.ByteOrder;
12 import java.util.Iterator;
13 import java.util.List;
14 import java.util.logging.Level;
15 import java.util.logging.Logger;
17 import javax.sound.sampled.AudioFormat;
19 import com.sun.speech.freetts.ProcessException;
20 import com.sun.speech.freetts.Utterance;
21 import com.sun.speech.freetts.UtteranceProcessor;
22 import com.sun.speech.freetts.audio.AudioPlayer;
25 * Supports generating audio output from an MBROLA-synthesized utterance. This
26 * is an utterance processor. The primary method, <code> processUtterance
27 * </code> takes an utterance containing an open BufferedInputStream, from
28 * which to read raw audio data provided by the external MBROLA binary. The
29 * audio data is read and sent to the proper audio player.
32 public class MbrolaAudioOutput implements UtteranceProcessor {
33 /** Logger instance. */
34 private static final Logger LOGGER =
35 Logger.getLogger(MbrolaAudioOutput.class.getName());
38 * The raw audio data coming out of MBROLA is in native byte order,
39 * 16 kHz, 16 bit, mono
41 private final static AudioFormat MBROLA_AUDIO =
42 new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
43 16000, // samples per second
44 16, // bits per sample
46 2, // nr. of bytes per frame
47 16000, // nr. of frames per second
48 ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN);
51 * Reads audio data generated by the external MBROLA binary for the given
52 * Utterance. The data is read from the open BufferedInputStream associated
53 * with the Utterance, and written into the AudioPlayer.
55 * @param utterance the utterance to generate waves
57 * @throws ProcessException if an IOException is thrown during the
58 * processing of the utterance
60 public void processUtterance(Utterance utterance) throws ProcessException {
61 if (LOGGER.isLoggable(Level.FINE)) {
63 utterance.getString("input_text"));
66 AudioPlayer audioPlayer = utterance.getVoice().getAudioPlayer();
68 audioPlayer.setAudioFormat(MBROLA_AUDIO);
69 audioPlayer.setVolume(utterance.getVoice().getVolume());
71 // The AudioPlayer interface currently does not allow streaming audio.
72 // We need to know the total number of samples that will be written
73 // before we can start writing them. Therefore, we need to load all
74 // audio data for this utterance into RAM.
76 List audioData = (List) utterance.getObject("mbrolaAudio");
77 if (audioData == null) {
78 throw new ProcessException
79 ("No \"mbrolaAudio\" object is associated with utterance");
82 // total number of audio bytes
86 totalSize = utterance.getInt("mbrolaAudioLength");
87 } catch (NullPointerException npe) {
91 audioPlayer.begin(totalSize);
93 for (Iterator it = audioData.iterator(); it.hasNext();) {
94 byte[] bytes = (byte[]) it.next();
95 if (!audioPlayer.write(bytes)) {
96 throw new ProcessException
97 ("Cannot write audio data to audio player");
101 if (!audioPlayer.end()) {
102 throw new ProcessException("audio player reports problem");
109 * Returns the string form of this object
111 * @return the string form of this object
113 public String toString() {
114 return "MbrolaAudioOutput";