Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

java - Saving audio byte[] to a wav file

Been having a bit of trouble over the last few days trying to get this to work. But what I want is we have an application that sends raw data over the network. I then read this binary data in and want to save it to a wav(any audio) file. Might look at compression later.

So the problematic code:

byte[] allBytes = ...
InputStream b_in = new ByteArrayInputStream(allBytes);

try
{
     AudioFormat format = new AudioFormat(8000f, 16, 1, true, true);
     AudioInputStream stream = new AudioInputStream(b_in, format, allBytes.length);
     //AudioInputStream stream = AudioSystem.getAudioInputStream(b_in);                

Have tried to use the above statement as well but i get the exception: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from stream. So what I think is happening is that because my stream is raw audio data and does not have a wave header this is throwing an exception?

File newPath = new File(SystemConfiguration.getLatest().voiceNetworkPathDirectory + currentPhoneCall.fileName);
if (!AudioSystem.isFileTypeSupported(Type.WAVE, stream))
{
    Logger.error("Audio System file type not supported");
}

AudioSystem.write(stream, Type.WAVE, newPath);

The file does successfully write but it is all static, Do I need to create a wave header on the output using the something like this. When I look at the outputted wav file in notepad and it does seem to have a header as it starts with 'RIFF'.

Do I need to add a fake header into my input stream? Should i just create my own output header and just save it with a binary writer?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So I ended up getting it working, not really sure why but this is the code that is working:

InputStream b_in = new ByteArrayInputStream(resultArray);
try {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                "C:\filename.bin"));
        dos.write(resultArray);
        AudioFormat format = new AudioFormat(8000f, 16, 1, true, false);
        AudioInputStream stream = new AudioInputStream(b_in, format,
                resultArray.length);
        File file = new File("C:\file.wav");
        AudioSystem.write(stream, Type.WAVE, file);
        Logger.info("File saved: " + file.getName() + ", bytes: "
                + resultArray.length)

So it must have been my signed/unsigned/ little endian settings. What I ended up doing was saving the data to a binary file. Then importing that file as raw data in audacity. This told me everything except the rate which I already new. The only issue I have now is to do with the header calculation. I save the binary data which generates a 4 second wav but it only ever has 2 seconds of sound. Its as if it is calculating my header wrong. I'm not sure if it is to do with the frame-length that LiuYan mentioned.

If I have an array length of 160. Does this mean I have a framelength of 10? 160 / 1 / 16. If I do this then I only store 10 bytes of data into my binary file.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...