001package ca.bc.webarts.tools;
002
003import java.awt.*;
004import java.awt.event.*;
005import java.io.*;
006import javax.sound.sampled.*;
007import javax.swing.*;
008
009
010/**
011 *  Description of the Class
012 *
013 */
014public class SoundCapture extends JFrame
015{
016
017  /**  Description of the Field */
018  protected boolean running;
019  /**  Description of the Field */
020  ByteArrayOutputStream out;
021
022
023  /**  Constructor for the SoundCapture object */
024  public SoundCapture()
025  {
026    super("Capture Sound Demo");
027    setDefaultCloseOperation(EXIT_ON_CLOSE);
028    Container content = getContentPane();
029
030    final JButton capture = new JButton("Capture");
031    final JButton stop = new JButton("Stop");
032    final JButton play = new JButton("Play");
033
034    capture.setEnabled(true);
035    stop.setEnabled(false);
036    play.setEnabled(false);
037
038    ActionListener captureListener =
039      new ActionListener()
040      {
041        public void actionPerformed(ActionEvent e)
042        {
043          capture.setEnabled(false);
044          stop.setEnabled(true);
045          play.setEnabled(false);
046          captureAudio();
047        }
048      };
049    capture.addActionListener(captureListener);
050    content.add(capture, BorderLayout.NORTH);
051
052    ActionListener stopListener =
053      new ActionListener()
054      {
055        public void actionPerformed(ActionEvent e)
056        {
057          capture.setEnabled(true);
058          stop.setEnabled(false);
059          play.setEnabled(true);
060          running = false;
061        }
062      };
063    stop.addActionListener(stopListener);
064    content.add(stop, BorderLayout.CENTER);
065
066    ActionListener playListener =
067      new ActionListener()
068      {
069        public void actionPerformed(ActionEvent e)
070        {
071          playAudio();
072        }
073      };
074    play.addActionListener(playListener);
075    content.add(play, BorderLayout.SOUTH);
076  }
077
078
079  /**
080   *  Description of the Method
081   *
082   * @param  args  Description of the Parameter
083   */
084  public static void main(String args[])
085  {
086    JFrame frame = new SoundCapture();
087    frame.pack();
088    frame.show();
089  }
090
091
092  /**  Description of the Method */
093  private void captureAudio()
094  {
095    try
096    {
097      final AudioFormat format = getFormat();
098      DataLine.Info info = new DataLine.Info(
099          TargetDataLine.class, format);
100      final TargetDataLine line = (TargetDataLine)
101          AudioSystem.getLine(info);
102      line.open(format);
103      line.start();
104      Runnable runner =
105        new Runnable()
106        {
107          int bufferSize = (int) format.getSampleRate()
108               * format.getFrameSize();
109          byte buffer[] = new byte[bufferSize];
110
111
112          public void run()
113          {
114            out = new ByteArrayOutputStream();
115            running = true;
116            try
117            {
118              while (running)
119              {
120                int count =
121                    line.read(buffer, 0, buffer.length);
122                if (count > 0)
123                {
124                  out.write(buffer, 0, count);
125                }
126              }
127              out.close();
128            }
129            catch (IOException e)
130            {
131              System.err.println("I/O problems: " + e);
132              System.exit(-1);
133            }
134          }
135        };
136      Thread captureThread = new Thread(runner);
137      captureThread.start();
138    }
139    catch (LineUnavailableException e)
140    {
141      System.err.println("Line unavailable: " + e);
142      System.exit(-2);
143    }
144  }
145
146
147  /**  Description of the Method */
148  private void playAudio()
149  {
150    try
151    {
152      byte audio[] = out.toByteArray();
153      InputStream input =
154          new ByteArrayInputStream(audio);
155      final AudioFormat format = getFormat();
156      final AudioInputStream ais =
157          new AudioInputStream(input, format,
158          audio.length / format.getFrameSize());
159      DataLine.Info info = new DataLine.Info(
160          SourceDataLine.class, format);
161      final SourceDataLine line = (SourceDataLine)
162          AudioSystem.getLine(info);
163      line.open(format);
164      line.start();
165
166      Runnable runner =
167        new Runnable()
168        {
169          int bufferSize = (int) format.getSampleRate()
170               * format.getFrameSize();
171          byte buffer[] = new byte[bufferSize];
172
173
174          public void run()
175          {
176            try
177            {
178              int count;
179              while ((count = ais.read(
180                  buffer, 0, buffer.length)) != -1)
181              {
182                if (count > 0)
183                {
184                  line.write(buffer, 0, count);
185                }
186              }
187              line.drain();
188              line.close();
189            }
190            catch (IOException e)
191            {
192              System.err.println("I/O problems: " + e);
193              System.exit(-3);
194            }
195          }
196        };
197      Thread playThread = new Thread(runner);
198      playThread.start();
199    }
200    catch (LineUnavailableException e)
201    {
202      System.err.println("Line unavailable: " + e);
203      System.exit(-4);
204    }
205  }
206
207
208  /**
209   *  Gets the format attribute of the SoundCapture object
210   *
211   * @return    The format value
212   */
213  private AudioFormat getFormat()
214  {
215    float sampleRate = 48000; // 8000
216    int sampleSizeInBits = 16; // 8
217    int channels = 2; //1
218    boolean signed = true;
219    boolean bigEndian = true;
220    return new AudioFormat(sampleRate,
221        sampleSizeInBits, channels, signed, bigEndian);
222  }
223}
224