每个样本的位更改时,Java AudioFormat的奇怪行为

时间:2015-04-04 14:48:17

标签: java audio

我正在尝试播放由服务器通过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);

1 个答案:

答案 0 :(得分:1)

问题在于,您正在提供SourceDataLine 8位音频并告诉它播放它,就像它是16位音频一样。这将使播放时间减半(因为它使用每个样本的两倍位数)。它对于声音使用的实际数字也有奇怪的东西,但我不确定是什么(我没有测试过你的例子。)

AudioFormat不会格式化音频,它会告诉SourceDataLine您的音频当前是如何格式化的,以便正确播放。

我不确定你想做什么,我想这将取决于你想要16位音频的原因。您可能需要从服务器而不是8位请求16位音频,或者您甚至可能不需要音频为16位。