001/**
002 * Copyright 2001 Sun Microsystems, Inc.
003 * 
004 * See the file "license.terms" for information on usage and
005 * redistribution of this file, and for a DISCLAIMER OF ALL 
006 * WARRANTIES.
007 */
008package com.sun.speech.freetts.audio;
009
010import java.util.logging.Level;
011import java.util.logging.Logger;
012
013import javax.sound.sampled.AudioFormat;
014
015import com.sun.speech.freetts.util.BulkTimer;
016
017
018/**
019 * Provides an implementation of <code>AudioPlayer</code> that sends
020 * all audio data to the bit bucket. The <code>NullAudioPlayer</code>
021 * is instrumented to provide timing metrics.
022 */
023public class NullAudioPlayer implements AudioPlayer {
024    /** Logger instance. */
025    private static final Logger LOGGER =
026        Logger.getLogger(NullAudioPlayer.class.getName());
027
028    private float volume = 1.0f;
029    private AudioFormat audioFormat;
030    private boolean firstSound = true;
031    private int totalBytes = 0;
032    private int totalWrites = 0;
033    private BulkTimer timer = new BulkTimer();
034
035
036    /**
037     * Constructs a NullAudioPlayer
038     */
039    public NullAudioPlayer() {
040    }
041    
042
043    /**
044     * Sets the audio format for this player
045     *
046     * @param format the audio format
047     */
048    public void setAudioFormat(AudioFormat format) {
049        this.audioFormat = format;
050    }
051
052    /**
053     * Retrieves the audio format for this player
054     *
055     * @return the current audio format.
056     */
057    public AudioFormat getAudioFormat() {
058        return audioFormat;
059    }
060
061    /**
062     * Cancels all queued output. Current 'write' call will return
063     * false
064     *
065     */
066    public void cancel() {
067    }
068
069
070    /**
071     * Pauses the audio output
072     */
073    public void pause() {
074    }
075
076
077    /**
078     * Prepares for another batch of output. Larger groups of output
079     * (such as all output associated with a single FreeTTSSpeakable)
080     * should be grouped between a reset/drain pair.
081     */
082    public void reset() {
083        timer.start("AudioOutput");
084    }
085
086
087    /**
088     * Resumes audio output
089     */
090    public void resume() {
091    }
092        
093
094
095
096    /**
097     * Waits for all audio playback to stop, and closes this AudioPlayer.
098     */
099    public void close() {
100    }
101        
102
103    /**
104     * Returns the current volume.
105     *
106     * @return the current volume (between 0 and 1)
107     */
108    public float getVolume() {
109        return volume;
110    }         
111
112    /**
113     * Sets the current volume.
114     *
115     * @param volume  the current volume (between 0 and 1)
116     */
117    public void setVolume(float volume) {
118        this.volume = volume;
119    }         
120
121
122    /**
123     * Writes the given bytes to the audio stream
124     *
125     * @param audioData array of audio data
126     *
127     * @return <code>true</code> of the write completed successfully, 
128     *          <code> false </code>if the write was cancelled.
129     */
130    public boolean write(byte[] audioData) {
131        return write(audioData, 0, audioData.length);
132    }
133
134
135    /**
136     *  Starts the output of a set of data
137     *
138     * @param size the size of data between now and the end
139     *
140     */
141    public void begin(int size) {
142    }
143
144    /**
145     *  Marks the end of a set of data
146     *
147     */
148    public boolean  end()  {
149        return true;
150    }
151
152    /**
153     * Writes the given bytes to the audio stream
154     *
155     * @param bytes audio data to write to the device
156     * @param offset the offset into the buffer
157     * @param size the size into the buffer
158     *
159     * @return <code>true</code> of the write completed successfully, 
160     *          <code> false </code>if the write was cancelled.
161     */
162    public boolean write(byte[] bytes, int offset, int size) {
163        totalBytes += size;
164        totalWrites ++;
165        if (firstSound) {
166            timer.stop("AudioFirstSound");
167            firstSound = false;
168            if (LOGGER.isLoggable(Level.FINER)) {
169                timer.show("Null Trace");
170            }
171        }
172        if (LOGGER.isLoggable(Level.FINER)) {
173            LOGGER.fine("NullAudio: write " + size + " bytes.");
174        }
175        return true;
176    }
177
178    /**
179     * Starts the first sample timer
180     */
181    public void startFirstSampleTimer() {
182        firstSound = true;
183        timer.start("AudioFirstSound");
184    }
185
186    /**
187     * Waits for all queued audio to be played
188     *
189     * @return <code>true</code> if the audio played to completion,
190     *          <code> false </code>if the audio was stopped
191     */
192    public boolean drain()  {
193        timer.stop("AudioOutput");
194        return true;
195    }
196
197    /**
198     * Gets the amount of played since the last resetTime
199     * Currently not supported.
200     *
201     * @return the amount of audio in milliseconds
202     */
203    public long getTime()  {
204        return -1L;
205    }
206
207
208    /**
209     * Resets the audio clock
210     */
211    public void resetTime() {
212    }
213
214    /**
215     * Shows metrics for this audio player
216     */
217    public void showMetrics() {
218        timer.show("NullAudioPlayer");
219    }
220}