I am currently using this code:
File wavFile=new File("tmp"+File.separator+"recordings"+File.separator+uuid.toString()+".wav");
try{
FileInputStream pcmInputStream=new FileInputStream(file);
FileOutputStream wavOutputStream=new FileOutputStream(wavFile);
AudioSystem.write(new AudioInputStream(new ByteArrayInputStream(IOUtils.toByteArray(pcmInputStream)),
new AudioFormat(48000,16,2,true,
true),IOUtils.toByteArray(pcmInputStream).length/4),
AudioFileFormat.Type.WAVE,wavOutputStream);
wavOutputStream.flush();
wavOutputStream.close();
pcmInputStream.close();
fileOutputStream.close();
}catch(IOException e){
e.printStackTrace();
}
Having checked, I can confirm that the PCM has 30 seconds of data and is approximately 4.7MB. This writes the .wav file however it is only 44 bytes and not playable, I reckon that this 44 bytes is the RIFF header but am unsure of how to solve it. I have tried using different lengths and different combinations of File/ByteArray OutputStreams.
When creating the AudioInputStream
, you call IOUtils.toByteArray(pcmInputStream)
twice, and on the second call, the input stream is already advanced to the end, so toByteArray
returns an empty array. This results in 0 getting passed as the argument to the AudioInputStream
constructor's length.
new AudioInputStream(
new ByteArrayInputStream( IOUtils.toByteArray(pcmInputStream) ),
new AudioFormat(48000,16,2,true,true),
( IOUtils.toByteArray(pcmInputStream) ).length/4
)
You should save the byte array to a temporary variable instead of trying to call toByteArray
twice on the same input stream.