奇怪的语音流和通过UDP接收音频



我在Java中实现了两个程序,一个通过UDP发送输出音频,另一个接收并播放。

奇怪的行为:

在执行这两个程序(它们通过环回地址进行通信(时,您有时(每 10 秒(唯一能听到的是一个声音(显然是一个女人(说"ciao"。

我第一次听到它时我很害怕,但现在我真的很好奇,想知道这些音频字节是从什么时候来的。

接收器代码

public static void main(String args[]) throws Exception {
System.out.println("connect to " + Inet4Address.getLocalHost().toString() + " on port " + port);
DatagramSocket serverSocket = new DatagramSocket(port);
byte[] receiveData = new byte[1280];  //1280!!!!!!
// ( 1280 for 16 000Hz and 3584 for 44 100Hz (use AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) to get the correct size)
format = new AudioFormat(sampleRate, 16, 1, true, false);
while (status == true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
ByteArrayInputStream baiss = new ByteArrayInputStream(
receivePacket.getData());
ais = new AudioInputStream(baiss, format, receivePacket.getLength());
// A thread solve the problem of chunky audio 
new Thread(() -> {
toSpeaker(receivePacket.getData());
}).start();
}
}
public static void toSpeaker(byte soundbytes[]) {
try {
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(format);
FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
volumeControl.setValue(6.0f);
sourceDataLine.start();
sourceDataLine.open(format);
sourceDataLine.start();
System.out.println("format? :" + sourceDataLine.getFormat());
sourceDataLine.write(soundbytes, 0, soundbytes.length);
//     System.out.println(soundbytes.toString());
sourceDataLine.drain();
sourceDataLine.close();
} catch (Exception e) {
System.out.println("Not working in speakers...");
e.printStackTrace();
}
}

流代码

public static void main(String[] args) throws IOException {
try {
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
float rate = 16000.0f;
int channels = 1;
int sampleSize = 16;
boolean bigEndian = false;
InetAddress addr;
AudioFormat format = new AudioFormat(rate, sampleSize, channels, true, bigEndian);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Line matching " + info + " not supported.");
return;
}
tdl = (TargetDataLine) AudioSystem.getLine(info);
tdl.open(format);
tdl.start();
socket = new DatagramSocket();
buffer = new byte[tdl.getBufferSize() / 5];
socket = new DatagramSocket();
//   hostAddress = InetAddress.getByName("192.168.43.1");
hostAddress = InetAddress.getByName("172.19.0.238");
} catch (SocketException ex) {
Logger.getLogger(AudioSender.class.getName()).log(Level.SEVERE, null, ex);
} catch (LineUnavailableException ex) {
Logger.getLogger(AudioSender.class.getName()).log(Level.SEVERE, null, ex);
}
(new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
int s = tdl.read(buffer, 0, buffer.length);
DatagramPacket sendPacket
= new DatagramPacket(buffer, buffer.length, hostAddress, port);
socket.send(sendPacket);
System.out.println(">>>" + sendPacket.getData());
}
} catch (IOException ex) {
Logger.getLogger(AudioSender.class.getName()).log(Level.SEVERE, null, ex);
}
}
})).start();
}
DatagramPacket sendPacket
= new DatagramPacket(buffer, buffer.length, hostAddress, port);

第一个问题就在这里。你忽略了长度。它应该是:

DatagramPacket sendPacket
= new DatagramPacket(buffer, s, hostAddress, port);

您也忽略了流的结束。如果s是 -1,你应该脱离循环。然后:

ByteArrayInputStream baiss = new ByteArrayInputStream(
receivePacket.getData());

第二个问题就在这里。你忽略了长度。它应该是:

ByteArrayInputStream baiss = new ByteArrayInputStream(
receivePacket.getData(), receivePacket.getOffset(), receivePacket.getLength());

最新更新