0

I am Writing a web based Voice Recorder with a Javascript/HTML5/JSF frontend, and a Glassfish (Java) backend.

I need to save the recorded .WAV file with ULAW encoding. However as far as I can tell the only way to record audio in HTML5/Javascript (with getUserMedia()) is in PCM encoding. I would love a simple way to capture the client side recording in ULAW, but have been unable to find any way to do this.

So for now what I've been trying to do is:

Record in PCM wav (client side)
Upload to server using JSP
Pass the received FileItem into a JAVA converter method that returns a byte array in ULAW

I found the following article of someone trying to do this in Android:

Android PCM to Ulaw encoding wav file

However the class this article references is either not working or I am not using it properly.

My current convertPCMtoULAW(FileItem file) Java method:

//read the FileItem's InputStream into a byte[]
InputStream uploadedStream = file.getInputStream();
byte[] pcmBytes = new byte[(int) file.getSize()];
uploadedStream.read(pcmBytes);

//extract the number of PCM Samples from the header
int offset =40;
int length =4;
int pcmSamples = 0;
for (int i = 0; i < length; i++)
{
   pcmSamples += ((int) pcmBytes[offset+i] & 0xffL) << (8 * i);
}

//create the UlawEncoderInputStream (class in link above)
is = new UlawEncoderInputStream(
         file.getInputStream(),
         UlawEncoderInputStream.maxAbsPcm(pcmBytes, 44, pcmSamples/2)
         );

//read from the created InputStream into another byte[]
byteLength =  is.read(ulawBytes);

//I then add the ULAW header to the beginning of the byte[] 
//and pass the entire byte[] through a pre-existing Wav Verifier method
//which serializes the byte[] later on

(all code compiles, the above is simplified to include the necessary parts)

I am consistently getting back only 512 bytes read in the variable byteLength.

I know I'm uploading a correct PCM WAV to Glassfish, because I can download and listen to my recording directly from the Javascript side.

I get an error when opening the file on the Server side after I have attempted to encode it.

My main question is: Has/Can anyone successfully use the class in the linked page to encode from PCM to ULAW?

Community
  • 1
  • 1

1 Answers1

1

I believe the problem you are facing doesn't have anything to do with transcoding, but rather with the contract of Java's InputStream.read. From the documentation:

Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is detected, or an exception is thrown.

In other words, the number returned by this function is how many bytes were actually read in this particular call of the method. The contract doesn't guarantee that it will read all bytes until the stream is closed, only as many bytes as available at the time it was called.

You will either have to call its overload read(byte[] b, int off, int len) in a loop until the stream is closed, or wrap the stream into a DataInputStream and use readFully.

Zoltán
  • 21,321
  • 14
  • 93
  • 134