我正在尝试播放由服务器通过UDP返回给我的音频流。服务器使用DPCM对音频进行编码,因此每个字节包含两个音频样本。当我用8位/样本播放音频时,一切正常,但是当我尝试使用16进行AudioFormat DPCM = new AudioFormat(8000,16,1,true,false);
时,剪辑会更短并且不那么清晰。我做错了什么?
ByteArrayOutputStream sound_buffer = new ByteArrayOutputStream();
clientRequest = new DatagramPacket( sound_request_buffer, sound_request_buffer.length );
server.send(clientRequest);
for(int i=0;i<100;i++){
buffer = new byte[128];
serverResponse = new DatagramPacket( buffer, buffer.length);
client.receive(serverResponse);
sound_buffer.write(buffer);
}
byte[] encoded_sound = sound_buffer.toByteArray();
byte[] decoded_sound = new byte[2*encoded_sound.length];
byte msnibble = (byte)((encoded_sound[0]>>4) & 0x000F);
decoded_sound[0] = (byte)(msnibble - 8);
byte lsnibble = (byte)(encoded_sound[0] & 0x000F );
decoded_sound[1] = (byte) (decoded_sound[0] + lsnibble - 8);
for(int i=1;i<encoded_sound.length;i++){
msnibble = (byte)((encoded_sound[i] >> 4) & 0x000F);
decoded_sound[2*i] = (byte)(decoded_sound[2*i-1] + msnibble - 8);
lsnibble = (byte)(encoded_sound[i] & 0x000F );
decoded_sound[2*i+1] = (byte)(decoded_sound[2*i] + lsnibble - 8);
}
AudioFormat DPCM = new AudioFormat(8000,8,1,true,false);
SourceDataLine lineOut=AudioSystem.getSourceDataLine(DPCM);
lineOut.open(DPCM,decoded_sound.length);
lineOut.start();
lineOut.write(decoded_sound,0,decoded_sound.length);
答案 0 :(得分:1)
问题在于,您正在提供SourceDataLine
8位音频并告诉它播放它,就像它是16位音频一样。这将使播放时间减半(因为它使用每个样本的两倍位数)。它对于声音使用的实际数字也有奇怪的东西,但我不确定是什么(我没有测试过你的例子。)
AudioFormat
不会格式化音频,它会告诉SourceDataLine
您的音频当前是如何格式化的,以便正确播放。
我不确定你想做什么,我想这将取决于你想要16位音频的原因。您可能需要从服务器而不是8位请求16位音频,或者您甚至可能不需要音频为16位。