001/** 002 * Portions Copyright 2001 Sun Microsystems, Inc. 003 * Portions Copyright 1999-2001 Language Technologies Institute, 004 * Carnegie Mellon University. 005 * All Rights Reserved. Use is subject to license terms. 006 * 007 * See the file "license.terms" for information on usage and 008 * redistribution of this file, and for a DISCLAIMER OF ALL 009 * WARRANTIES. 010 */ 011package com.sun.speech.freetts.relp; 012 013import java.io.IOException; 014import java.util.logging.Level; 015import java.util.logging.Logger; 016 017import javax.sound.sampled.AudioFormat; 018 019import com.sun.speech.freetts.ProcessException; 020import com.sun.speech.freetts.Utterance; 021import com.sun.speech.freetts.UtteranceProcessor; 022import com.sun.speech.freetts.audio.AudioPlayer; 023 024/** 025 * Supports generating audio output from an utterance. This is an 026 * utterance processor. The primary method, <code> procesUtterance </code> 027 * takes an utterance and hands it off to the LPCResult to be sent to the 028 * proper audio player. 029 * 030 * @see LPCResult 031 */ 032public class AudioOutput implements UtteranceProcessor { 033 /** Logger instance. */ 034 private static final Logger LOGGER = 035 Logger.getLogger(AudioOutput.class.getName()); 036 037 private final static AudioFormat AUDIO_8KHZ = 038 new AudioFormat(8000.0f, 16, 1, true, true); 039 private final static AudioFormat AUDIO_16KHZ = 040 new AudioFormat(16000.0f, 16, 1, true, true); 041 042 /** 043 * Generates audio waves for the given Utterance. The audio data 044 * is decoded using the Linear Predictive Decoder 045 * 046 * @param utterance the utterance to generate waves 047 * 048 * @see LPCResult 049 * 050 * @throws ProcessException if an IOException is thrown during the 051 * processing of the utterance 052 */ 053 public void processUtterance(Utterance utterance) throws ProcessException { 054 LPCResult lpcResult = (LPCResult) utterance.getObject("target_lpcres"); 055 SampleInfo sampleInfo = 056 (SampleInfo) utterance.getObject(SampleInfo.UTT_NAME); 057 AudioPlayer audioPlayer = utterance.getVoice().getAudioPlayer(); 058 059 audioPlayer.setAudioFormat(getAudioFormat(sampleInfo)); 060 audioPlayer.setVolume(utterance.getVoice().getVolume()); 061 062 if (LOGGER.isLoggable(Level.FINE)) { 063 LOGGER.fine("=== " + 064 utterance.getString("input_text")); 065 } 066 try { 067 if (!lpcResult.playWave(audioPlayer, utterance)) { 068 throw new ProcessException("Output Cancelled"); 069 } 070 } catch (IOException e) { 071 throw new ProcessException(e.getMessage(), e); 072 } 073 } 074 075 076 /** 077 * Gets the current audio format. 078 * Given a sample info return an appropriate audio format. A cache 079 * of common audio formats is used to reduce unnecessary object 080 * creation. Note that this method always returns an AudioFormat 081 * that uses 16-bit samples. 082 * 083 * @param sampleInfo the sample info 084 * 085 * @return an audio format 086 */ 087 private AudioFormat getAudioFormat(SampleInfo sampleInfo) { 088 if (sampleInfo.getSampleRate() == 8000) { 089 return AUDIO_8KHZ; 090 } else if (sampleInfo.getSampleRate() == 16000) { 091 return AUDIO_16KHZ; 092 } else { 093 return new AudioFormat(sampleInfo.getSampleRate(), 094 16, 1, true, true); 095 } 096 } 097 098 /** 099 * 100 * Returns the string form of this object 101 * 102 * @return the string form of this object 103 */ 104 public String toString() { 105 return "AudioOutput"; 106 } 107} 108