您好我一直在编写聊天客户端,并希望测试Java Sound API。我已经设法通过UDP从麦克风到不同计算机上的扬声器工作。然而声音不是很清楚。为了检查这是否是因为UDP协议中丢失的数据包等,我写了一个小测试,声音转到与麦克风在同一台机器上的扬声器。声音没有任何不同,这让我觉得我在读取或写入声音方面有些错误。任何人都可以查看我的代码并告诉我如何让声音更清晰吗?
package test;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.sound.sampled.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class VoiceTest extends JFrame {
private JButton chat = new JButton("Voice");
private GUIListener gl = new GUIListener();
private IncomingSoundListener isl = new IncomingSoundListener();
private OutgoingSoundListener osl = new OutgoingSoundListener();
private boolean inVoice = true;
private boolean outVoice = false;
AudioFormat format = getAudioFormat();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
public VoiceTest() throws IOException {
super ("Test");
//new Thread(tl).start();
new Thread(isl).start();
Container contentPane = this.getContentPane();
this.setSize(200,100);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
chat.setBounds(10,10,80,30);
chat.addActionListener(gl);
contentPane.add(chat);
this.setVisible(true);
}
private AudioFormat getAudioFormat() {
float sampleRate = 8000.0F;
int sampleSizeBits = 16;
int channels = 1;
boolean signed = true;
boolean bigEndian = false;
//AudioFormat.Encoding.ULAW
return new AudioFormat(sampleRate, sampleSizeBits, channels, signed, bigEndian);
}
class GUIListener implements ActionListener {
public void actionPerformed(ActionEvent actionevent) {
String action = actionevent.getActionCommand();
switch (action) {
case "Mute":
outVoice = false;
chat.setText("Voice");
break;
case "Voice":
new Thread(osl).start();
outVoice = true;
chat.setText("Mute");
break;
}
}
}
class IncomingSoundListener implements Runnable {
@Override
public void run() {
try {
System.out.println("Listening for incoming sound");
DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine speaker = (SourceDataLine) AudioSystem.getLine(speakerInfo);
speaker.open(format);
speaker.start();
while(inVoice) {
byte[] data = baos.toByteArray();
baos.reset();
ByteArrayInputStream bais = new ByteArrayInputStream(data);
AudioInputStream ais = new AudioInputStream(bais,format,data.length);
int numBytesRead = 0;
if ((numBytesRead = ais.read(data)) != -1) speaker.write(data, 0, numBytesRead);
ais.close();
bais.close();
}
speaker.drain();
speaker.close();
System.out.println("Stopped listening for incoming sound");
} catch (Exception e) {
e.printStackTrace();
}
}
}
class OutgoingSoundListener implements Runnable {
@Override
public void run() {
try {
System.out.println("Listening for outgoing sound");
DataLine.Info micInfo = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine mic = (TargetDataLine) AudioSystem.getLine(micInfo);
mic.open(format);
byte tmpBuff[] = new byte[mic.getBufferSize()/5];
mic.start();
while(outVoice) {
int count = mic.read(tmpBuff,0,tmpBuff.length);
if (count > 0) baos.write(tmpBuff, 0, count);
}
mic.drain();
mic.close();
System.out.println("Stopped listening for outgoing sound");
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
new VoiceTest();
}
}
答案 0 :(得分:2)
您应该尝试更高的sampling rate并尝试为音频流找到可接受的质量/尺寸比率。
检查AudioFormat参考也是获得想法的良好开端。
尝试将getAudioFormat()
方法中的局部变量更改为:
private AudioFormat getAudioFormat() {
float sampleRate = 16000.0F;
int sampleSizeBits = 16;
int channels = 1;
...
}
这相当于一个256 kbps的Mono音频文件。