Java - convert 16 bit signed pcm audio data array to double array

I am working on a project related to audio processing.

I take a piece of audio from a file, and then I would like to process it. The problem is that I get the audio data as an array of bytes, and my processing is in a double array (and later in a complex array ...).

My question is, how can I correctly convert the byte array that I get for a double array?

Here is my input code:

AudioFormat format = new AudioFormat(8000, 16, 1, true, true);
AudioInputStream in = AudioSystem.getAudioInputStream(WAVfile);
AudioInputStream din = null;
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
                        8000,
                        16,
                        1,
                        2,
                        8000,
                        true);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
TargetDataLine fileLine = AudioSystem.getTargetDataLine(decodedFormat);
fileLine .open(format);
fileLine .start();

int numBytesRead;
byte[] targetData = new byte[256]; // (samplingRate / 1000) * 32ms

while (true) {
    numBytesRead = din.read(targetData, 0, targetData.length);

    if (numBytesRead == -1) {
        break;
    }

    double[] convertedData;
    // Conversion code goes here...

    processAudio(convertedData);
}

So far, I have studied different answers to different questions around this site and others. I tried using ByteBuffer and bit conversion, but both of them did not give me results that seem correct (the other member in my team did the same in a single Python file, so I have a link that the results should be approximately ...

? ? targetData 32 , TargerData? convertData?

.

+4
2

NIO . , , 16 , [-1.0…1.0].

, , :

AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
                                            8000, 16, 1, 2, 8000, true);
try(AudioInputStream in  = AudioSystem.getAudioInputStream(WAVfile);
    AudioInputStream din = AudioSystem.getAudioInputStream(decodedFormat, in);
    ReadableByteChannel inCh = Channels.newChannel(din)) {

    ByteBuffer inBuf=ByteBuffer.allocate(256);
    final double factor=2.0/(1<<16);
    while(inCh.read(inBuf) != -1) {
        inBuf.flip();
        double[] convertedData=new double[inBuf.remaining()/2];
        DoubleBuffer outBuf=DoubleBuffer.wrap(convertedData);
        while(inBuf.remaining()>=2) {
            outBuf.put(inBuf.getShort()*factor);
        }
        assert !outBuf.hasRemaining();
        inBuf.compact();
        processAudio(convertedData);
    }
}

…/(double)0x8000. , processAudio , . , , . /.

+4

, AudioFormat.Encoding.PCM_SIGNED BigEndian, java int ( ). >> << ( 8 - - , , , Endian, Big Endian , , , , 8 ), + | int, int, , . , -1... + 1, , 32768.

, . , .

, , :

AudioFormat format = new AudioFormat(8000, 16, 2, true, false);

:

   int l = (short) ((readedData[i*4+1]<<8)|readedData[i*4+0]);
   int r = (short) ((readedData[i*4+3]<<8)|readedData[i*4+2]);

:

   double scaledL = l/32768d;
   double scaledR = r/32768d;
0

All Articles