Java Tutorial/Development/Audio — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 15:28, 31 мая 2010
Содержание
- 1 A simple player for sampled sound files.
- 2 Capturing Audio with Java Sound API
- 3 Determining the Duration of a Sampled Audio File
- 4 Determining the Encoding of a Sampled Audio File
- 5 Determining the File Format of a Sampled Audio File
- 6 Determining the Position of a Sampled Audio Player
- 7 Determining When a Sampled Audio Player Has Finished Playing
- 8 Float Control Component
- 9 Load image and sound from Jar file
- 10 Loading and Playing Sampled Audio
- 11 Make your own Java Media Player to play media files
- 12 Play an audio file from a JAR file
- 13 Playing Streaming Sampled Audio
- 14 Setting the Volume of a Sampled Audio Player
- 15 This is a simple program to record sounds and play them back
A simple player for sampled sound files.
/*
*
* Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free,
* license to use, modify and redistribute this software in
* source and binary code form, provided that i) this copyright
* notice and license appear on all copies of the software; and
* ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty
* of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS
* AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
* HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT
* WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
* OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS
* OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY
* TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
This software is not designed or intended for use in on-line
control of aircraft, air traffic, aircraft navigation or
aircraft communications; or in the design, construction,
operation or maintenance of any nuclear facility. Licensee
represents and warrants that it will not use or redistribute
the Software for such purposes.
*/
/* The above copyright statement is included because this
* program uses several methods from the JavaSoundDemo
* distributed by SUN. In some cases, the sound processing methods
* unmodified or only slightly modified.
* All other methods copyright Steve Potts, 2002
*/
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Vector;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
/**
* A simple player for sampled sound files.
*
*
* @author Steve Potts
*/
public class SimpleSoundPlayer implements Runnable, LineListener, MetaEventListener {
final int bufSize = 16384;
Vector sounds = new Vector();
Thread thread;
Sequencer sequencer;
boolean midiEOM, audioEOM;
Synthesizer synthesizer;
MidiChannel channels[];
Object currentSound;
String currentName;
double duration;
int num;
boolean bump;
boolean paused = false;
String errStr;
public void open() {
try {
sequencer = MidiSystem.getSequencer();
if (sequencer instanceof Synthesizer) {
synthesizer = (Synthesizer) sequencer;
channels = synthesizer.getChannels();
}
} catch (Exception ex) {
ex.printStackTrace();
return;
}
sequencer.addMetaEventListener(this);
}
public void close() {
if (sequencer != null) {
sequencer.close();
}
}
private void addSound(File file) {
sounds.add(file);
}
public boolean loadSound(Object object) {
duration = 0.0;
currentName = ((File) object).getName();
try {
currentSound = AudioSystem.getAudioInputStream((File) object);
} catch (Exception e1) {
try {
FileInputStream is = new FileInputStream((File) object);
currentSound = new BufferedInputStream(is, 1024);
} catch (Exception e3) {
e3.printStackTrace();
currentSound = null;
return false;
}
// }
}
// user pressed stop or changed tabs while loading
if (sequencer == null) {
currentSound = null;
return false;
}
if (currentSound instanceof AudioInputStream) {
try {
AudioInputStream stream = (AudioInputStream) currentSound;
AudioFormat format = stream.getFormat();
/**
* we can"t yet open the device for ALAW/ULAW playback, convert
* ALAW/ULAW to PCM
*/
if ((format.getEncoding() == AudioFormat.Encoding.ULAW)
|| (format.getEncoding() == AudioFormat.Encoding.ALAW)) {
AudioFormat tmp = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(), format.getSampleSizeInBits() * 2, format.getChannels(),
format.getFrameSize() * 2, format.getFrameRate(), true);
stream = AudioSystem.getAudioInputStream(tmp, stream);
format = tmp;
}
DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(), ((int) stream
.getFrameLength() * format.getFrameSize()));
Clip clip = (Clip) AudioSystem.getLine(info);
clip.addLineListener(this);
clip.open(stream);
currentSound = clip;
// seekSlider.setMaximum((int) stream.getFrameLength());
} catch (Exception ex) {
ex.printStackTrace();
currentSound = null;
return false;
}
} else if (currentSound instanceof Sequence || currentSound instanceof BufferedInputStream) {
try {
sequencer.open();
if (currentSound instanceof Sequence) {
sequencer.setSequence((Sequence) currentSound);
} else {
sequencer.setSequence((BufferedInputStream) currentSound);
}
} catch (InvalidMidiDataException imde) {
System.out.println("Unsupported audio file.");
currentSound = null;
return false;
} catch (Exception ex) {
ex.printStackTrace();
currentSound = null;
return false;
}
}
duration = getDuration();
return true;
}
public void playSound() {
midiEOM = audioEOM = bump = false;
if (currentSound instanceof Sequence || currentSound instanceof BufferedInputStream
&& thread != null) {
sequencer.start();
while (!midiEOM && thread != null && !bump) {
try {
thread.sleep(99);
} catch (Exception e) {
break;
}
}
sequencer.stop();
sequencer.close();
} else if (currentSound instanceof Clip) {
Clip clip = (Clip) currentSound;
clip.start();
try {
thread.sleep(99);
} catch (Exception e) {
}
while ((paused || clip.isActive()) && thread != null && !bump) {
try {
thread.sleep(99);
} catch (Exception e) {
break;
}
}
clip.stop();
clip.close();
}
currentSound = null;
}
public double getDuration() {
double duration = 0.0;
if (currentSound instanceof Sequence) {
duration = ((Sequence) currentSound).getMicrosecondLength() / 1000000.0;
} else if (currentSound instanceof BufferedInputStream) {
duration = sequencer.getMicrosecondLength() / 1000000.0;
} else if (currentSound instanceof Clip) {
Clip clip = (Clip) currentSound;
duration = clip.getBufferSize()
/ (clip.getFormat().getFrameSize() * clip.getFormat().getFrameRate());
}
return duration;
}
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP && !paused) {
audioEOM = true;
}
}
public void meta(MetaMessage message) {
if (message.getType() == 47) { // 47 is end of track
midiEOM = true;
}
}
private void reportStatus(String msg) {
if ((errStr = msg) != null) {
System.out.println(errStr);
}
}
public Thread getThread() {
return thread;
}
public void start() {
thread = new Thread(this);
thread.setName("SimpleSamplePlayer");
thread.start();
}
public void stop() {
if (thread != null) {
thread.interrupt();
}
thread = null;
}
public void run() {
for (; num < sounds.size() && thread != null; num++) {
if (loadSound(sounds.get(num)) == true) {
playSound();
}
// take a little break between sounds
try {
thread.sleep(222);
} catch (Exception e) {
break;
}
}
num = 0;
thread = null;
currentName = null;
currentSound = null;
System.out.println("Press <ctrl-c> to exit");
}
public void loadSounds(String name) {
try {
File file = new File(name);
if (file != null && file.isDirectory()) {
String files[] = file.list();
for (int i = 0; i < files.length; i++) {
File leafFile = new File(file.getAbsolutePath(), files[i]);
addSound(leafFile);
}
}
} catch (Exception e) {
System.out.println("Exception " + e);
}
}
public static void main(String args[]) {
// every file in this directory will be played
String media = "c:/unleashed/ch18/sounds";
final SimpleSoundPlayer ssp = new SimpleSoundPlayer();
ssp.open();
// we first load the sound file names in a vector
ssp.loadSounds(media);
// Then we start a thread to play the sounds
ssp.start();
// We have to wait for a while so that the process doesn"t
// terminate, killing the playing thread
try {
Thread.sleep(500000);
} catch (Exception e) {
System.out.println("Interrupted");
}
// close and exit
ssp.close();
System.exit(0);
}
}
Capturing Audio with Java Sound API
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
public class Main {
public static void main(String args[]) throws Exception {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
float sampleRate = 8000;
int sampleSizeInBits = 8;
int channels = 1;
boolean signed = true;
boolean bigEndian = true;
final AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
bigEndian);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
final TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
Runnable runner = new Runnable() {
int bufferSize = (int) format.getSampleRate() * format.getFrameSize();
byte buffer[] = new byte[bufferSize];
public void run() {
try {
int count = line.read(buffer, 0, buffer.length);
if (count > 0) {
out.write(buffer, 0, count);
}
out.close();
} catch (IOException e) {
System.err.println("I/O problems: " + e);
System.exit(-1);
}
}
};
Thread captureThread = new Thread(runner);
captureThread.start();
byte audio[] = out.toByteArray();
InputStream input = new ByteArrayInputStream(audio);
final SourceDataLine line1 = (SourceDataLine) AudioSystem.getLine(info);
final AudioInputStream ais = new AudioInputStream(input, format, audio.length
/ format.getFrameSize());
line1.open(format);
line1.start();
runner = new Runnable() {
int bufferSize = (int) format.getSampleRate() * format.getFrameSize();
byte buffer[] = new byte[bufferSize];
public void run() {
try {
int count;
while ((count = ais.read(buffer, 0, buffer.length)) != -1) {
if (count > 0) {
line1.write(buffer, 0, count);
}
}
line1.drain();
line1.close();
} catch (IOException e) {
System.err.println("I/O problems: " + e);
System.exit(-3);
}
}
};
Thread playThread = new Thread(runner);
playThread.start();
}
}
Determining the Duration of a Sampled Audio File
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
public class Main {
public static void main(String[] argv) throws Exception {
DataLine.Info info = null;
Clip clip = (Clip) AudioSystem.getLine(info);
double durationInSecs = clip.getBufferSize()
/ (clip.getFormat().getFrameSize() * clip.getFormat().getFrameRate());
}
}
Determining the Encoding of a Sampled Audio File
import java.io.File;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class Main {
public static void main(String[] argv) throws Exception {
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
"audiofile"));
}
}
Determining the File Format of a Sampled Audio File
import java.io.File;
import java.net.URL;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;
public class Main {
public static void main(String[] argv) throws Exception {
AudioFileFormat fformat = AudioSystem.getAudioFileFormat(new File(
"audiofile"));
fformat = AudioSystem.getAudioFileFormat(new URL(
"http://hostname/audiofile"));
if (fformat.getType() == AudioFileFormat.Type.AIFC) {
} else if (fformat.getType() == AudioFileFormat.Type.AIFF) {
} else if (fformat.getType() == AudioFileFormat.Type.AU) {
} else if (fformat.getType() == AudioFileFormat.Type.WAVE) {
}
}
}
Determining the Position of a Sampled Audio Player
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
public class Main {
public static void main(String[] argv) throws Exception {
DataLine.Info info = null;
Clip clip = (Clip) AudioSystem.getLine(info);
double timeInSeconds = clip.getMicrosecondPosition() / 1000000.0d;
}
}
Determining When a Sampled Audio Player Has Finished Playing
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
public class Main {
public static void main(String[] argv) throws Exception {
DataLine.Info info = null;
Clip clip = (Clip) AudioSystem.getLine(info);
clip.addLineListener(new LineListener() {
public void update(LineEvent evt) {
if (evt.getType() == LineEvent.Type.STOP) {
}
}
});
}
}
Float Control Component
import javax.sound.sampled.FloatControl;
public class Main {
FloatControl control;
public Main(FloatControl c) {
control = c;
control.setValue(3);
}
}
Load image and sound from Jar file
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Line;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main extends JFrame {
JButton button;
ImageIcon buttonIcon;
Clip buhClip;
public Main() throws Exception {
URL imageURL = getClass().getClassLoader().getResource("images/k.jpeg");
buttonIcon = new ImageIcon(imageURL);
button = new JButton("Click to Buh!", buttonIcon);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (buhClip != null) {
buhClip.setFramePosition(0);
buhClip.start();
} else
System.out.println("Couldn"t load sound");
}
});
getContentPane().add(button);
URL soundURL = getClass().getClassLoader().getResource("sounds/b.aiff");
Line.Info linfo = new Line.Info(Clip.class);
Line line = AudioSystem.getLine(linfo);
buhClip = (Clip) line;
AudioInputStream ais = AudioSystem.getAudioInputStream(soundURL);
buhClip.open(ais);
}
public static final void main(String[] args) throws Exception {
JFrame frame = new Main();
frame.pack();
frame.setVisible(true);
}
}
Loading and Playing Sampled Audio
import java.io.File;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
public class Main {
public static void main(String[] argv) throws Exception {
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
"audiofile"));
// From URL
// stream = AudioSystem.getAudioInputStream(new URL(
// "http://hostname/audiofile"));
AudioFormat format = stream.getFormat();
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format
.getSampleRate(), format.getSampleSizeInBits() * 2, format
.getChannels(), format.getFrameSize() * 2, format.getFrameRate(),
true); // big endian
stream = AudioSystem.getAudioInputStream(format, stream);
}
DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(),
((int) stream.getFrameLength() * format.getFrameSize()));
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(stream);
clip.start();
}
}
Make your own Java Media Player to play media files
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.media.*;
public class MediaPlayerDemo extends JFrame {
public static void main(String args[]) {
Player player;
File file = new File("yourFile");
player = Manager.createPlayer(file.toURI().toURL());
// player.addControllerListener(new EventHandler());
player.start(); // start player
player.close();
Component visual = player.getVisualComponent();
Component control = player.getControlPanelComponent();
}
}
Play an audio file from a JAR file
import java.io.InputStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Main {
public static void main(String args[]) throws Throwable {
InputStream in = Main.class.getResourceAsStream(args[0]);
AudioStream as = new AudioStream(in);
AudioPlayer.player.start(as);
Thread.sleep(5000);
}
}
Playing Streaming Sampled Audio
import java.io.File;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class Main {
public static void main(String[] argv) throws Exception {
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(
"audiofile"));
// stream = AudioSystem.getAudioInputStream(new URL(
// "http://hostname/audiofile"));
AudioFormat format = stream.getFormat();
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format
.getSampleRate(), format.getSampleSizeInBits() * 2, format
.getChannels(), format.getFrameSize() * 2, format.getFrameRate(),
true); // big endian
stream = AudioSystem.getAudioInputStream(format, stream);
}
SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, stream
.getFormat(), ((int) stream.getFrameLength() * format.getFrameSize()));
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(stream.getFormat());
line.start();
int numRead = 0;
byte[] buf = new byte[line.getBufferSize()];
while ((numRead = stream.read(buf, 0, buf.length)) >= 0) {
int offset = 0;
while (offset < numRead) {
offset += line.write(buf, offset, numRead - offset);
}
}
line.drain();
line.stop();
}
}
Setting the Volume of a Sampled Audio Player
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
public class Main {
public static void main(String[] argv) throws Exception {
DataLine.Info info = null;
Clip clip = (Clip) AudioSystem.getLine(info);
FloatControl gainControl = (FloatControl) clip
.getControl(FloatControl.Type.MASTER_GAIN);
double gain = .5D; // number between 0 and 1 (loudest)
float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
gainControl.setValue(dB);
BooleanControl muteControl = (BooleanControl) clip
.getControl(BooleanControl.Type.MUTE);
muteControl.setValue(true);
muteControl.setValue(false);
}
}
This is a simple program to record sounds and play them back
/*
*
* Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free,
* license to use, modify and redistribute this software in
* source and binary code form, provided that i) this copyright
* notice and license appear on all copies of the software; and
* ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty
* of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS
* AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
* HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT
* WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
* OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS
* OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY
* TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
This software is not designed or intended for use in on-line
control of aircraft, air traffic, aircraft navigation or
aircraft communications; or in the design, construction,
operation or maintenance of any nuclear facility. Licensee
represents and warrants that it will not use or redistribute
the Software for such purposes.
*/
/* The above copyright statement is included because this
* program uses several methods from the JavaSoundDemo
* distributed by SUN. In some cases, the sound processing methods
* unmodified or only slightly modified.
* All other methods copyright Steve Potts, 2002
*/
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.border.SoftBevelBorder;
/**
* SimpleSoundCapture Example. This is a simple program to record sounds and
* play them back. It uses some methods from the CapturePlayback program in the
* JavaSoundDemo. For licensizing reasons the disclaimer above is included.
*
* @author Steve Potts
*/
public class SimpleSoundCapture extends JPanel implements ActionListener {
final int bufSize = 16384;
Capture capture = new Capture();
Playback playback = new Playback();
AudioInputStream audioInputStream;
JButton playB, captB;
JTextField textField;
String errStr;
double duration, seconds;
File file;
public SimpleSoundCapture() {
setLayout(new BorderLayout());
EmptyBorder eb = new EmptyBorder(5, 5, 5, 5);
SoftBevelBorder sbb = new SoftBevelBorder(SoftBevelBorder.LOWERED);
setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel p1 = new JPanel();
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
JPanel p2 = new JPanel();
p2.setBorder(sbb);
p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
JPanel buttonsPanel = new JPanel();
buttonsPanel.setBorder(new EmptyBorder(10, 0, 5, 0));
playB = addButton("Play", buttonsPanel, false);
captB = addButton("Record", buttonsPanel, true);
p2.add(buttonsPanel);
p1.add(p2);
add(p1);
}
public void open() {
}
public void close() {
if (playback.thread != null) {
playB.doClick(0);
}
if (capture.thread != null) {
captB.doClick(0);
}
}
private JButton addButton(String name, JPanel p, boolean state) {
JButton b = new JButton(name);
b.addActionListener(this);
b.setEnabled(state);
p.add(b);
return b;
}
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj.equals(playB)) {
if (playB.getText().startsWith("Play")) {
playback.start();
captB.setEnabled(false);
playB.setText("Stop");
} else {
playback.stop();
captB.setEnabled(true);
playB.setText("Play");
}
} else if (obj.equals(captB)) {
if (captB.getText().startsWith("Record")) {
capture.start();
playB.setEnabled(false);
captB.setText("Stop");
} else {
capture.stop();
playB.setEnabled(true);
}
}
}
/**
* Write data to the OutputChannel.
*/
public class Playback implements Runnable {
SourceDataLine line;
Thread thread;
public void start() {
errStr = null;
thread = new Thread(this);
thread.setName("Playback");
thread.start();
}
public void stop() {
thread = null;
}
private void shutDown(String message) {
if ((errStr = message) != null) {
System.err.println(errStr);
}
if (thread != null) {
thread = null;
captB.setEnabled(true);
playB.setText("Play");
}
}
public void run() {
// make sure we have something to play
if (audioInputStream == null) {
shutDown("No loaded audio to play back");
return;
}
// reset to the beginnning of the stream
try {
audioInputStream.reset();
} catch (Exception e) {
shutDown("Unable to reset the stream\n" + e);
return;
}
// get an AudioInputStream of the desired format for playback
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
float rate = 44100.0f;
int channels = 2;
int frameSize = 4;
int sampleSize = 16;
boolean bigEndian = true;
AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8)
* channels, rate, bigEndian);
AudioInputStream playbackInputStream = AudioSystem.getAudioInputStream(format,
audioInputStream);
if (playbackInputStream == null) {
shutDown("Unable to convert stream of format " + audioInputStream + " to format " + format);
return;
}
// define the required attributes for our line,
// and make sure a compatible line is supported.
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
shutDown("Line matching " + info + " not supported.");
return;
}
// get and open the source data line for playback.
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format, bufSize);
} catch (LineUnavailableException ex) {
shutDown("Unable to open the line: " + ex);
return;
}
// play back the captured audio data
int frameSizeInBytes = format.getFrameSize();
int bufferLengthInFrames = line.getBufferSize() / 8;
int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
byte[] data = new byte[bufferLengthInBytes];
int numBytesRead = 0;
// start the source data line
line.start();
while (thread != null) {
try {
if ((numBytesRead = playbackInputStream.read(data)) == -1) {
break;
}
int numBytesRemaining = numBytesRead;
while (numBytesRemaining > 0) {
numBytesRemaining -= line.write(data, 0, numBytesRemaining);
}
} catch (Exception e) {
shutDown("Error during playback: " + e);
break;
}
}
// we reached the end of the stream.
// let the data play out, then
// stop and close the line.
if (thread != null) {
line.drain();
}
line.stop();
line.close();
line = null;
shutDown(null);
}
} // End class Playback
/**
* Reads data from the input channel and writes to the output stream
*/
class Capture implements Runnable {
TargetDataLine line;
Thread thread;
public void start() {
errStr = null;
thread = new Thread(this);
thread.setName("Capture");
thread.start();
}
public void stop() {
thread = null;
}
private void shutDown(String message) {
if ((errStr = message) != null && thread != null) {
thread = null;
playB.setEnabled(true);
captB.setText("Record");
System.err.println(errStr);
}
}
public void run() {
duration = 0;
audioInputStream = null;
// define the required attributes for our line,
// and make sure a compatible line is supported.
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
float rate = 44100.0f;
int channels = 2;
int frameSize = 4;
int sampleSize = 16;
boolean bigEndian = true;
AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8)
* channels, rate, bigEndian);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
shutDown("Line matching " + info + " not supported.");
return;
}
// get and open the target data line for capture.
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format, line.getBufferSize());
} catch (LineUnavailableException ex) {
shutDown("Unable to open the line: " + ex);
return;
} catch (SecurityException ex) {
shutDown(ex.toString());
//JavaSound.showInfoDialog();
return;
} catch (Exception ex) {
shutDown(ex.toString());
return;
}
// play back the captured audio data
ByteArrayOutputStream out = new ByteArrayOutputStream();
int frameSizeInBytes = format.getFrameSize();
int bufferLengthInFrames = line.getBufferSize() / 8;
int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
byte[] data = new byte[bufferLengthInBytes];
int numBytesRead;
line.start();
while (thread != null) {
if ((numBytesRead = line.read(data, 0, bufferLengthInBytes)) == -1) {
break;
}
out.write(data, 0, numBytesRead);
}
// we reached the end of the stream.
// stop and close the line.
line.stop();
line.close();
line = null;
// stop and close the output stream
try {
out.flush();
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
// load bytes into the audio input stream for playback
byte audioBytes[] = out.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
audioInputStream = new AudioInputStream(bais, format, audioBytes.length / frameSizeInBytes);
long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000) / format
.getFrameRate());
duration = milliseconds / 1000.0;
try {
audioInputStream.reset();
} catch (Exception ex) {
ex.printStackTrace();
return;
}
}
} // End class Capture
public static void main(String s[]) {
SimpleSoundCapture ssc = new SimpleSoundCapture();
ssc.open();
JFrame f = new JFrame("Capture/Playback");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add("Center", ssc);
f.pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int w = 360;
int h = 170;
f.setLocation(screenSize.width / 2 - w / 2, screenSize.height / 2 - h / 2);
f.setSize(w, h);
f.show();
}
}