【发布时间】:2014-01-02 14:28:40
【问题描述】:
我正在尝试通过 UDP 传输麦克风,但我的输出噪音太大,无法理解输入音频。这是我的代码:
服务器端:
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;
import javax.sound.sampled.TargetDataLine;
public class MicPlayer {
private static final String IP_TO_STREAM_TO = "localhost" ;
private static final int PORT_TO_STREAM_TO = 8888 ;
/** Creates a new instance of MicPlayer */
public MicPlayer() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Mixer.Info minfo[] = AudioSystem.getMixerInfo() ;
for( int i = 0 ; i < minfo.length ; i++ )
{
System.out.println( minfo[i] ) ;
}
if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
try {
DataLine.Info dataLineInfo = new DataLine.Info(
TargetDataLine.class , getAudioFormat() ) ;
final TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine( dataLineInfo ) ;
targetDataLine.open( getAudioFormat() );
targetDataLine.start();
byte tempBuffer[] = new byte[targetDataLine.getBufferSize() / 5] ;
int cnt = 0 ;
while( true )
{
targetDataLine.read( tempBuffer , 0 , tempBuffer.length );
sendThruUDP( tempBuffer ) ;
}
}
catch(Exception e )
{
System.out.println(" not correct " ) ;
System.exit(0) ;
}
}
}
public static AudioFormat getAudioFormat(){
float sampleRate = 8000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed = true;
//true,false
boolean bigEndian = false;
//true,false
return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian );
}
public static void sendThruUDP( byte soundpacket[] )
{
try
{
DatagramSocket sock = new DatagramSocket() ;
sock.send( new DatagramPacket( soundpacket , soundpacket.length , InetAddress.getByName( IP_TO_STREAM_TO ) , PORT_TO_STREAM_TO ) ) ;
sock.close() ;
}
catch( Exception e )
{
e.printStackTrace() ;
System.out.println(" Unable to send soundpacket using UDP " ) ;
}
}
}
我不认为客户端有问题,但这里是代码;
客户端:
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class RadioReceiver extends Thread {
private static final String IP_TO_STREAM_TO = "localhost" ;
private static final int PORT_TO_STREAM_TO = 8888 ;
/** Creates a new instance of RadioReceiver */
public RadioReceiver() {
}
public void run()
{
byte b[] = null ;
while( true )
{
b = receiveThruUDP() ;
toSpeaker( b ) ;
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
RadioReceiver r = new RadioReceiver() ;
r.start() ;
}
public static byte[] receiveThruUDP()
{
try
{
DatagramSocket sock = new DatagramSocket(PORT_TO_STREAM_TO) ;
byte soundpacket[] = new byte[1230] ;
DatagramPacket datagram = new DatagramPacket( soundpacket , soundpacket.length , InetAddress.getByName( IP_TO_STREAM_TO ) , PORT_TO_STREAM_TO ) ;
sock.receive( datagram ) ;
sock.close() ; return datagram.getData() ; // soundpacket ;
}
catch( Exception e )
{
System.out.println(" Unable to send soundpacket using UDP " ) ;
return null ;
}
}
public static void toSpeaker( byte soundbytes[] )
{
try{
DataLine.Info dataLineInfo = new DataLine.Info( SourceDataLine.class , getAudioFormat() ) ;
SourceDataLine sourceDataLine = (SourceDataLine)AudioSystem.getLine( dataLineInfo );
sourceDataLine.open( getAudioFormat() ) ;
sourceDataLine.start();
int cnt = 0;
sourceDataLine.write( soundbytes , 0, soundbytes.length );
sourceDataLine.drain() ;
sourceDataLine.close() ;
}
catch(Exception e )
{
System.out.println("not working in speakers " ) ;
}
}
public static AudioFormat getAudioFormat()
{
float sampleRate = 8000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed = true;
//true,false
boolean bigEndian = false;
//true,false
return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian );
}
}
我确定我的连接正常,但我不知道为什么我的输出如此嘈杂。这让我发疯了,我一直在努力工作到 1 周,请帮助我。谢谢。
【问题讨论】:
-
你为什么使用UDP?恕我直言,您应该将 TCP 用于此类应用程序。
-
您能告诉我您使用的是哪一种 API 吗?
-
@user2336315,我不知道如何使用 tcp :( 如果你知道,你能帮我吗?
-
@Touregsys:我建议在这里使用 UDP。如果您想学习 TCP,请在此处阅读我的答案:stackoverflow.com/questions/4615958/…
-
@MartijnCourteaux 虽然 UPD 更快,但 TCP 保证数据包按顺序到达应用层且没有错误。此外,许多防火墙和路由器未配置为允许 UDP 数据包。但是@ Touregsys 可以同时尝试两者,看看哪种最合适。