我通过使用类框架选择.wav,我有:
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
InputStream in = null;
try {
in = new FileInputStream(chooser.getSelectedFile().getAbsolutePath());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
as = new AudioStream(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
接下来,我想运行下面的方法。此方法应该播放.wav并将声音写入字节数组,但我有错误:
java.io.IOException: cannot read a single byte if frame size > 1
AudioInputStream stream;
stream = AudioSystem.getAudioInputStream(Frame.as);
// Get Audio Format information
AudioFormat audioFormat = stream.getFormat();
// Handle opening the line
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class,audioFormat);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
// Start playing the sound
line.start();
// Write the sound to an array of bytes
int nBytesRead = 0;
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
while (nBytesRead != -1) {
try {
nBytesRead = stream.read(abData, 0, abData.length);
} catch (IOException e) {
e.printStackTrace();
}
if (nBytesRead >= 0) {
int nBytesWritten = line.write(abData, 0, nBytesRead);
}
}
// close the line
line.drain();
line.close();
代码有什么问题?
如果您查看 AudioInputStream#read 和 SourceDataLine#write 的文档,您会发现要读取/写入的字节数必须是样本帧的整数。在您的情况下,它看起来像 EXTERNAL_BUFFER_SIZE
是 1,并且音频格式必须大于 8 位。
由于整数规则,不要像您正在做的那样基于静态常量创建缓冲区。通过将nBytesRead
传递给write
,您几乎是正确的,但您需要考虑音频的样本大小。相反,使用如下所示的内容创建字节缓冲区:
byte[] abData = new byte[
audioFormat.getFrameSize() * EXTERNAL_BUFFER_SIZE
];
现在,缓冲区表示整数样本帧中的大小。