我正在尝试从DataLine
文档示例中获取的这段代码。据我了解,在播放声音时,它应该显示一个振幅电平计,但事实并非如此。它会打开声音文件并正确播放,并在一个小窗口中显示有关该文件的一些数据,但没有仪表。
也许我不了解它的工作方式。你能帮我理解吗?
DataLineInfoGUI
类:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.sound.sampled.*;
public class DataLineInfoGUI extends JPanel {
PCMFilePlayer player;
JButton startButton;
public DataLineInfoGUI (File f) {
super();
try {
player = new PCMFilePlayer (f);
} catch (Exception ioe) {
add (new JLabel ("Error: " +
ioe.getMessage()));
return;
}
DataLine line = player.getLine();
// layout
// line 1: name
setLayout (new BoxLayout (this, BoxLayout.Y_AXIS));
add (new JLabel ("File: " +
player.getFile().getName()));
// line 2: levels
add (new DataLineLevelMeter (line));
// line 3: format info as textarea
AudioFormat format = line.getFormat();
JTextArea ta = new JTextArea();
ta.setBorder (new TitledBorder ("Format"));
ta.append ("Encoding: " +
format.getEncoding().toString() + "\n");
ta.append ("Bits/sample: " +
format.getSampleSizeInBits() + "\n");
ta.append ("Channels: " +
format.getChannels() + "\n");
ta.append ("Endianness: " +
(format.isBigEndian() ? " big " : "little") + "\n");
ta.append ("Frame size: " +
format.getFrameSize() + "\n");
ta.append ("Frame rate: " +
format.getFrameRate() + "\n");
add (ta);
// now start playing
player.start();
}
public static void main (String[] args) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
File file = chooser.getSelectedFile();
DataLineInfoGUI demo =
new DataLineInfoGUI (file);
JFrame f = new JFrame ("JavaSound info");
f.getContentPane().add (demo);
f.pack();
f.setVisible(true);
}
class DataLineLevelMeter extends JPanel {
DataLine line;
float level = 0.0f;
public DataLineLevelMeter (DataLine l) {
line = l;
Timer timer =
new Timer (50,
new ActionListener (){
public void actionPerformed (ActionEvent e)
{
level = line.getLevel();
repaint();
}
});
timer.start();
}
public void paint (Graphics g) {
Dimension d = getSize();
g.setColor (Color.green);
int meterWidth = (int) (level * (float) d.width);
g.fillRect (0, 0, meterWidth, d.height);
}
}
}
PCMFilePlayer
类:
import javax.sound.sampled.*;
import java.io.*;
public class PCMFilePlayer implements Runnable {
File file;
AudioInputStream in;
SourceDataLine line;
int frameSize;
byte[] buffer = new byte [32 * 1024]; // 32k is arbitrary
Thread playThread;
boolean playing;
boolean notYetEOF;
public PCMFilePlayer (File f)
throws IOException,
UnsupportedAudioFileException,
LineUnavailableException {
file = f;
in = AudioSystem.getAudioInputStream (f);
AudioFormat format = in.getFormat();
AudioFormat.Encoding formatEncoding = format.getEncoding();
if (! (formatEncoding.equals (AudioFormat.Encoding.PCM_SIGNED) ||
formatEncoding.equals (AudioFormat.Encoding.PCM_UNSIGNED)))
throw new UnsupportedAudioFileException (
file.getName() + " is not
PCM audio");
System.out.println ("got PCM format");
frameSize = format.getFrameSize();
DataLine.Info info =
new DataLine.Info (SourceDataLine.class, format);
System.out.println ("got info");
line = (SourceDataLine) AudioSystem.getLine (info);
System.out.println ("got line");
line.open();
System.out.println ("opened line");
playThread = new Thread (this);
playing = false;
notYetEOF = true;
playThread.start();
}
public void run() {
int readPoint = 0;
int bytesRead = 0;
try {
while (notYetEOF) {
if (playing) {
bytesRead = in.read (buffer,
readPoint,
buffer.length - readPoint);
if (bytesRead == -1) {
notYetEOF = false;
break;
}
// how many frames did we get,
// and how many are left over?
int frames = bytesRead / frameSize;
int leftover = bytesRead % frameSize;
// send to line
line.write (buffer, readPoint, bytesRead-leftover);
// save the leftover bytes
System.arraycopy (buffer, bytesRead,
buffer, 0,
leftover);
readPoint = leftover;
} else {
// if not playing
// Thread.yield();
try { Thread.sleep (10);}
catch (InterruptedException ie) {}
}
} // while notYetEOF
System.out.println ("reached eof");
line.drain();
line.stop();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
// line.close();
}
} // run
public void start() {
playing = true;
if (! playThread.isAlive())
playThread.start();
line.start();
}
public void stop() {
playing = false;
line.stop();
}
public SourceDataLine getLine() {
return line;
}
public File getFile() {
return file;
}
}