Android PCM for Uaw encoding wav file

I am trying to encode pcm raw data as uLaw in order to preserve the bandwidth needed for voice data transmission.

I met the UlawEncoderInputStream class on this page , but no documentation !: (

The constructor accepts the input stream and the maximum pcm value (whatever that is).

/** * Create an InputStream which takes 16 bit pcm data and produces ulaw data. * @param in InputStream containing 16 bit pcm data. * @param max pcm value corresponding to maximum ulaw value. */ public UlawEncoderInputStream(InputStream in, int max) { 

After looking at the code, I suspect that I should calculate this "max" value using the supplied function: maxAbsPcm . The problem is that I really don't understand what I have to pass into it! I write my raw pcm to a file on the SD card, so I don't have one resident continuous memory data array to transfer this.

  /** * Compute the maximum of the absolute value of the pcm samples. * The return value can be used to set ulaw encoder scaling. * @param pcmBuf array containing 16 bit pcm data. * @param offset offset of start of 16 bit pcm data. * @param length number of pcm samples (not number of input bytes) * @return maximum abs of pcm data values */ public static int maxAbsPcm(byte[] pcmBuf, int offset, int length) { 

Another problem I use with this code: I'm not sure what values ​​to write for the header for the uLaw data. How to determine how much less byte data after encoding with uLaw?

I listened to one of the (potentially) ULaw encoded files that I created in the VLC media player (the only player I have that will try to read the file) and its sounds are disgusting, broken and ticklish, but can still make out the voice.

I am writing my wave header using code similar to the class I found called WaveHeader, which can be found here !

If anyone has thoughts on this, I would be very grateful to hear them! :)

Thanks a lot dexter

+6
source share
2 answers

max in the constructor is the maximum amplitude in the PCM data. It is used to scale input before generating output. If the input is very loud, you need a higher value, if it is quiet, you need a lower one. If you go to 0 , by default the encoder will use 8192 , which can be good enough.

length in another method is the number of 16-bit samples from which you want to find the maximum amplitude. This class assumes that PCM input is always encoded with 16-bit patterns, which means that each pattern spans two bytes: if your input is 2000 bytes long, you have 1000 patterns.

The encoder in this class creates one 8-bit ΞΌ-law pattern for each 16-bit PCM pattern, so the size in bytes is halved.

+4
source

This is the opposite of what you are trying to do, but I thought it might be useful to someone. Here is an exmple example that converts an 8-bit uLaw-encoded binary to a 16-bit WAV file using Java built-in methods.

 public static void convertULawFileToWav(String filename) { File file = new File(filename); if (!file.exists()) return; try { long fileSize = file.length(); int frameSize = 160; long numFrames = fileSize / frameSize; AudioFormat audioFormat = new AudioFormat(Encoding.ULAW, 8000, 8, 1, frameSize, 50, true); AudioInputStream audioInputStream = new AudioInputStream(new FileInputStream(file), audioFormat, numFrames); AudioSystem.write(audioInputStream, Type.WAVE, new File("C:\\file.wav")); } catch (IOException e) { e.printStackTrace(); } } 
0
source

Source: https://habr.com/ru/post/900684/


All Articles