Java:从音频文件中提取字节

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6933920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:56:45  来源:igfitidea点击:

Java: Extracting bytes from audio file

javaaudiowavspectrogram

提问by Samer Makary

What is the difference between the following two implementations in extracting the bytes of data from an audio file ?

从音频文件中提取数据字节的以下两种实现有什么区别?

The file is a .wavfile and i want to extract only the data, without headers or any other thing.

该文件是一个.wav文件,我只想提取数据,没有标题或任何其他内容。

Implementation 1:

实施1:

public byte[] extractAudioFromFile(String filePath) {
    try {
        // Get an input stream on the byte array
        // containing the data
        File file = new File(filePath);
        final AudioInputStream audioInputStream = AudioSystem
                .getAudioInputStream(file);

        byte[] buffer = new byte[4096];
        int counter;
        while ((counter = audioInputStream.read(buffer, 0, buffer.length)) != -1) {
            if (counter > 0) {
                byteOut.write(buffer, 0, counter);
            }
        }
        audioInputStream.close();
        byteOut.close();
    } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
    }// end catch

    return ((ByteArrayOutputStream) byteOut).toByteArray();
}

Implementation 2:

实施2:

public byte[] readAudioFileData(String filePath) throws IOException,
        UnsupportedAudioFileException {
    final AudioInputStream audioInputStream = AudioSystem
            .getAudioInputStream(new File(filePath));
    AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, byteOut);
    audioInputStream.close();
    byteOut.close();

    return ((ByteArrayOutputStream) byteOut).toByteArray();
}

Every implementation returns a different size of bytes. The first one return byte[]with length less than second implementation.

每个实现都返回不同大小的字节。第一个返回byte[]长度小于第二个实现。

I trying to extract the bytes of data to visualize the Spectrogram of the file.

我试图提取数据字节以可视化文件的频谱图。

Any explanation appreciated.

任何解释表示赞赏。

Thanks,

谢谢,

Samer

萨默

回答by alphazero

The 2nd impl is writing the full WAVE 'file format'. Is 2nd buffer 44 byteslarger than the first?

第二个实现正在编写完整的 WAVE“文件格式”。第二个缓冲区比第一个大44 个字节吗?

[edit: curious enough to actually try it - the above is correct]

[编辑:好奇到实际尝试 - 以上是正确的]

package so_6933920;

import java.io.ByteArrayOutputStream;
import java.io.File;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

public class AudioFiles {
    public static void main(String[] args) {
        String file = "clarinet.wav";
        AudioFiles afiles = new AudioFiles();
        byte[] data1 = afiles.readAudioFileData(file);
        byte[] data2 = afiles.readWAVAudioFileData(file);
        System.out.format("data len: %d\n", data1.length);
        System.out.format("data len: %d\n", data2.length);
        System.out.format("diff len: %d\n", data2.length - data1.length);
    }
    public byte[] readAudioFileData(final String filePath) {
        byte[] data = null;
        try {
            final ByteArrayOutputStream baout = new ByteArrayOutputStream();
            final File file = new File(filePath);
            final AudioInputStream audioInputStream = AudioSystem
            .getAudioInputStream(file);

            byte[] buffer = new byte[4096];
            int c;
            while ((c = audioInputStream.read(buffer, 0, buffer.length)) != -1) {
                baout.write(buffer, 0, c);
            }
            audioInputStream.close();
            baout.close();
            data = baout.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }
    public byte[] readWAVAudioFileData(final String filePath){
        byte[] data = null;
        try {
            final ByteArrayOutputStream baout = new ByteArrayOutputStream();
            final AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(filePath));

            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, baout);
            audioInputStream.close();
            baout.close();
            data = baout.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }
}

I tried this with this sample WAV file.

我用这个示例 WAV 文件尝试了这个

Results:

结果:

data len: 489708
data len: 489752
diff len: 44

Note: I took some liberties with your snippet to clean it up.

注意:我对你的代码片段进行了一些自由清理。

  1. That System.exit(0)is a definite no-no.
  2. if(counter > 0)isn't really necessary since counter must be greater than 0if return value of the read method is not -1.
  1. System.exit(0)是一个明确的禁忌。
  2. if(counter > 0)不是真的有必要,因为 counter 必须大于0如果 read 方法的返回值不是-1