Talker
__________
import java.io.*;
import java.util.*;
import java.net.*;
import javax.sound.sampled.*;public class Talker
{
   private SourceDataLine line=null;
   public static void main(String args[])
   {
      Talker player=new Talker();
      if(args.length>0)
      {
         for(int i=0;i<args.length;i++)
         {
            player.sayPhoneWord(args[i]);
         }
      }
      else
      {
         player.sayPhoneSentence("h|e|l|oo");
      }
      System.exit(0);
   }
   public void sayPhoneSentence(String sentence)
   {
      StringTokenizer st=new StringTokenizer(sentence," ",false);
      while(st.hasMoreTokens())
      {
         String word=st.nextToken();
         sayPhoneWord(word);
      }
   }
   public void sayPhoneWord(String word)
   {
      byte[] previousSound=null;
      StringTokenizer st=new StringTokenizer(word,"|",false);
      while (st.hasMoreTokens())
      {
         String thisPhoneFile=st.nextToken();
         thisPhoneFile="/allophones/"+thisPhoneFile+".au";
         byte[] thisSound=getSound(thisPhoneFile);
         if(previousSound!=null)
         {
            int mergeCount=0;
            if (previousSound.length>=500 && thisSound.length>=500)
            {
               mergeCount=500;
            }
            for(int i=0; i<mergeCount;i++)
            {
               previousSound[previousSound.length-mergeCount+i]=(byte)((previousSound[previousSound.length-mergeCount+i]+thisSound[i])/2);
            }
            playSound(previousSound);
            byte[] newSound=new byte[thisSound.length-mergeCount];
            for (int ii=0; ii<newSound.length; ii++)
            {
               newSound[ii]=thisSound[ii+mergeCount];
            }
            previousSound=newSound; 
         }
         else
         {
            previousSound=thisSound;
         }
      }
      playSound(previousSound);
      drain();
   }
   private void drain()
   {
      if (line!=null) line.drain();
      try {Thread.sleep(100);}catch(Exception e){}
   }
   private void playSound(byte[] data)
   {
      if (data.length>0) line.write(data, 0, data.length);
   }
   private byte[] getSound(String fileName)
   {
      try
      {
         URL url=Talker.class.getResource(fileName);
         AudioInputStream stream = AudioSystem.getAudioInputStream(url);
         AudioFormat format = stream.getFormat();
         if ((format.getEncoding() == AudioFormat.Encoding.ULAW) || (format.getEncoding() == AudioFormat.Encoding.ALAW)) 
         {
            AudioFormat tmpFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,format.getSampleRate(),format.getSampleSizeInBits()*2,format.getChannels(),format.getFrameSize()*2,format.getFrameRate(),true);
            stream = AudioSystem.getAudioInputStream(tmpFormat, stream);
            format = tmpFormat;
         }
         DataLine.Info info = new DataLine.Info(Clip.class,format,((int) stream.getFrameLength() * format.getFrameSize()));
         if(line==null)
         {
            DataLine.Info outInfo = new DataLine.Info(SourceDataLine.class,format);
            if (!AudioSystem.isLineSupported(outInfo))
            {
               System.out.println("Line matching " + outInfo + " not supported.");
               throw new Exception("Line matching " + outInfo + " not supported.");
            }
            line = (SourceDataLine) AudioSystem.getLine(outInfo);
            line.open(format, 50000);
            line.start();
         }
         int frameSizeInBytes = format.getFrameSize();
         int bufferLengthInFrames = line.getBufferSize() / 8;
         int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
         byte[] data=new byte[bufferLengthInBytes];
         int numBytesRead = 0;
         if ((numBytesRead = stream.read(data)) != -1)
         {
            int numBytesRemaining = numBytesRead;
         }
         byte maxByte=0;
         byte[] newData=new byte[numBytesRead];
         for (int i=0; i<numBytesRead;i++)
         {
            newData[i]=data[i];
            if (newData[i]>maxByte)
            {
               maxByte=newData[i];
            }
         }
         return newData;
      }
      catch (Exception e)
      {
      return new byte[0];
      }
   }
}
.au文件为字母读音文件。将单词分解,按字母一一读出。不一定精准。