Java AudioFormat 当每个样本的位数发生变化时的奇怪行为

Weird behaviout of Java AudioFormat when bits per sample change

我正在尝试播放服务器通过 UDP 返回给我的音频流。服务器使用 DPCM 对音频进行编码,因此每个字节包含两个音频样本。当我用 8 bits/sample 播放音频时,一切正常,但是当我尝试用 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);

问题是您给 SourceDataLine 8 位音频并告诉它像 16 位音频一样播放。这将使播放时间减半(因为每个样本使用两倍的位数)。它还使用用于声音的实际数字做一些奇怪的事情,但我不确定是什么(我没有测试你的例子。)

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

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