简体   繁体   中英

Weird behaviout of Java AudioFormat when bits per sample change

I am trying to play a audio stream that is returned to me by a server via UDP. The server uses DPCM to encode the audio, thus every byte contains two audio samples. When I play the audio with 8 bits/sample everything works fine, but when I try with 16 doing AudioFormat DPCM = new AudioFormat(8000,16,1,true,false); the clip is shorter and not so clear. What am I doing wrong?

    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);

The problem is that you are giving the SourceDataLine 8-bit audio and telling it to play it as if it were 16-bit audio. This will make it halve the playback time (because it uses twice the number of bits per sample). It also does weird stuff with the actual numbers that are used for the sound, but I'm not exactly sure what (I haven't tested your example.)

The AudioFormat doesn't format the audio, it tells the SourceDataLine how your audio is currently formatted so that it plays it correctly.

I'm not really sure what you want to do, and I guess it would depend on why you want 16-bit audio. You might need to request 16-bit audio from the server instead of 8-bit, or you might not even need the audio to be 16-bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM