I'm trying to convert ulaw PCM to Linear PCM in Java

94 Views Asked by At

Created code to change the PCM file encoded in java to ulaw to Linear PCM in a normal way. Because it's a test code, it's simple to configure, and when you run it, the ulaw PCM is converted to a specific folder as Linear PCM. So I got the file and ran it on a program called Ocean Audio, and the noise gets mixed up too much. I converted it, but as a result, I couldn't get the song I wanted. There seems to be no problem with Buffered InputStream, making Buffer, converting it to ByteArray Why did this happen?

The code I tried is as follows.

public static void main(String args[]) throws IOException {

        String fileName = "ulaw.pcm";
        File file = new File("/home/user/" + fileName);
        FileInputStream fis = new FileInputStream(file);
        int read = 0;
        byte[] buff = new byte[3200];
        byte[] audioBytes;
        byte[] cvtAudioBytes;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        BufferedInputStream in = new BufferedInputStream(fis);
        while ((read = in.read(buff)) > 0) {
            out.write(buff, 0, read);
        }

        audioBytes = out.toByteArray();
        cvtAudioBytes = Converter.ulaw2Linear(audioBytes);
        
        Path path = Paths.get("/home/user/convert.pcm");

        Files.write(path, cvtAudioBytes);

        out.close();
        in.close();

}

Below is Converter Class.

public class Converter {
    public static byte[] ulaw2Linear(byte[] ulawBuffer) {
        int ulawSampleSize = ulawBuffer.length;
        int linearSampleSize = ulawSampleSize * 2;
        System.out.println("ulawSampleSize : " + ulawSampleSize);
        System.out.println("linearSampleSize : " + linearSampleSize);

        byte[] linearBuffer = new byte[linearSampleSize];

        for (int i = 0; i < ulawSampleSize; i++) {
            short sampleValue = ulaw2LinearSample(ulawBuffer[i]);
            //System.out.println(sampleValue);
            linearBuffer[i * 2] = (byte) (sampleValue & 0xFF);
            linearBuffer[i * 2 + 1] = (byte) ((sampleValue >> 8) & 0xFF);
        }

        for(int i=0; i<linearBuffer.length; i++) {
            System.out.println(linearBuffer[i]);
        }
        return linearBuffer;
    }

    private static short ulaw2LinearSample(byte ulawSample) {
        int ulawValue = ulawSample & 0xFF;
        ulawValue = ulawValue ^ 0xFF; 
        int sign = (ulawValue & 0x80) == 0 ? 1 : -1;
        int exponent = (ulawValue >> 4) & 0x07;
        int mantissa = ulawValue & 0x0F;
        int sampleValue = ((1 << exponent) | (mantissa << (exponent - 4)) | (1 << (exponent - 3))) - 33;
        return (short) (sampleValue * sign);
    }

}

The Converter class does not feel wrong because it is a universally converted code. However, the problem with the code used for the main is that I couldn't find it. Is there anything lacking in the code?

Thank you.

0

There are 0 best solutions below