java中Wav文件到字节数组的转换

java中Wav文件到字节数组的转换,java,arrays,audio,javasound,wave,Java,Arrays,Audio,Javasound,Wave,我的项目是“阿塞拜疆语的语音识别”。我必须编写一个程序,将wav文件转换为字节数组 如何将音频文件转换为字节[]?将此文件写入ByteArrayOutputStream ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedInputStream in = new BufferedInputStream(new FileInputStream(WAV_FILE)); int read; byte[] buff = ne

我的项目是“阿塞拜疆语的语音识别”。我必须编写一个程序,将
wav
文件转换为字节数组


如何将音频文件转换为字节[]?

将此文件写入
ByteArrayOutputStream

ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(WAV_FILE));

int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0)
{
    out.write(buff, 0, read);
}
out.flush();
byte[] audioBytes = out.toByteArray();

基本上如第一个答案中的代码片段所述,但不是使用
BufferedInputStream
获取
InputStream

使用从
AudioSystem
获得的音频流将确保去除标题,并将输入文件解码为表示实际声音帧/样本的字节[],然后可用于FFT等。

导入java.io.*;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.LinkedHashMap;
import javax.sound.sampled.*;

/**
 * This class reads a .wav file and converts it to a bunch of byte arrays.
 * 
 * The info represented by these byte arrays is then printed out.
 * 
 * An example of playing these byte arrays with the speakers is used.
 * 
 * It also converts the byte arrays to a .wav file.
 * 
 * An extension of this concept can record from a microphone.
 * In this case, some values like sampling rate would need to be assumed.
 * 
 * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ for .wav file spec
 * 
 * @author sizu
 */
public class WavFileHelper {    

    public static void main(String[] args) {
        final String NEWLINE = "\n";
        int recordingSampleRate = 22050;
        short recordingBitsPerSample = 16;
        short recordingNumChannels = 2;
        String inputFile = "/input.wav"; // Place the wav file in the top level directory, ie S:/input.wav
        String outputFile = "/output.wav";
        String recordedFile = "/capture.wav";

        System.out.println("START");
        try {
            WavData wavInputData = new WavData();
            WavData wavRecordData = new WavData();
            wavRecordData.put(WaveSection.SAMPLE_RATE, recordingSampleRate);
            wavRecordData.put(WaveSection.BITS_PER_SAMPLE, recordingBitsPerSample);
            wavRecordData.put(WaveSection.NUM_CHANNELS, recordingNumChannels);

            System.out.println(NEWLINE+"CONVERT WAV FILE TO BYTE ARRAY");
            wavInputData.read(inputFile);

            System.out.println(NEWLINE+"CONVERT BYTE ARRAY TO WAV FILE");
            wavInputData.write(outputFile);

            System.out.println(NEWLINE+"DISPLAY BYTE ARRAY INFORMATION FOR INPUT FILE");
            wavInputData.printByteInfo();

            System.out.println(NEWLINE+"START RECORDING - You can connect the microphone to the speakers");
            WavAudioRecorder recorder = new WavFileHelper.WavAudioRecorder(wavRecordData);
            recorder.startRecording();

            System.out.println(NEWLINE+"PLAY BYTE ARRAY (THIS WILL BE RECORDED)");
            WavAudioPlayer player = new WavFileHelper.WavAudioPlayer(wavInputData);
            player.playAudio();

            System.out.println(NEWLINE+"STOP RECORDING FOR RECORDING");
            recorder.stopRecording();

            System.out.println(NEWLINE+"DISPLAY BYTE ARRAY INFORMATION");
            wavRecordData.printByteInfo();

            System.out.println(NEWLINE+"SAVE RECORDING IN WAV FILE");
            wavRecordData.write(recordedFile);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("FINISH");
    }

    public static enum WaveSection {
        // 12 Bytes
        CHUNK_ID(4, ByteOrder.BIG_ENDIAN),
        CHUNK_SIZE(4, ByteOrder.LITTLE_ENDIAN),
        FORMAT(4, ByteOrder.BIG_ENDIAN),

        // 24 Bytes
        SUBCHUNK1_ID(4, ByteOrder.BIG_ENDIAN),
        SUBCHUNK1_SIZE(4, ByteOrder.LITTLE_ENDIAN),
        AUDIO_FORMAT(2, ByteOrder.LITTLE_ENDIAN),
        NUM_CHANNELS(2, ByteOrder.LITTLE_ENDIAN),
        SAMPLE_RATE(4, ByteOrder.LITTLE_ENDIAN),
        BYTE_RATE(4, ByteOrder.LITTLE_ENDIAN),
        BLOCK_ALIGN(2, ByteOrder.LITTLE_ENDIAN),
        BITS_PER_SAMPLE(2, ByteOrder.LITTLE_ENDIAN),

        // 8 Bytes
        SUBCHUNK2_ID(4, ByteOrder.BIG_ENDIAN),
        SUBCHUNK2_SIZE(4, ByteOrder.LITTLE_ENDIAN),
        DATA(0, ByteOrder.LITTLE_ENDIAN),
        ;

        private Integer numBytes;
        private ByteOrder endian;
        WaveSection(Integer numBytes, ByteOrder endian){
            this.numBytes = numBytes;
            this.endian = endian;
        }
    }

    public static class WavData extends LinkedHashMap<WaveSection, byte[]>{
        static int HEADER_SIZE = 44; // There are 44 bits before the data section
        static int DEFAULT_SUBCHUNK1_SIZE = 16;
        static short DEFAULT_AUDIO_FORMAT = 1;
        static short DEFAULT_BLOCK_ALIGN = 4;
        static String DEFAULT_CHUNK_ID = "RIFF";
        static String DEFAULT_FORMAT = "WAVE";
        static String DEFAULT_SUBCHUNK1_ID = "fmt ";
        static String DEFAULT_SUBCHUNK2_ID = "data";

        public WavData(){
            this.put(WaveSection.CHUNK_ID, DEFAULT_CHUNK_ID);
            this.put(WaveSection.FORMAT, DEFAULT_FORMAT);
            this.put(WaveSection.SUBCHUNK1_ID, DEFAULT_SUBCHUNK1_ID);
            this.put(WaveSection.SUBCHUNK1_SIZE, DEFAULT_SUBCHUNK1_SIZE);
            this.put(WaveSection.AUDIO_FORMAT, DEFAULT_AUDIO_FORMAT);
            this.put(WaveSection.BLOCK_ALIGN, DEFAULT_BLOCK_ALIGN);
            this.put(WaveSection.SUBCHUNK2_ID, DEFAULT_SUBCHUNK2_ID);

            this.put(WaveSection.CHUNK_SIZE, 0);
            this.put(WaveSection.SUBCHUNK2_SIZE, 0);
            this.put(WaveSection.BYTE_RATE, 0);
        }

        public void put(WaveSection waveSection, String value){
            byte[] bytes = value.getBytes();
            this.put(waveSection, bytes);
        }

        public void put(WaveSection waveSection, int value) {
            byte[] bytes = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array();
            this.put(waveSection, bytes);
        }

        public void put(WaveSection waveSection, short value) {
            byte[] bytes = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
            this.put(waveSection, bytes);
        }

        public byte[] getBytes(WaveSection waveSection) {
            return this.get(waveSection);
        }

        public String getString(WaveSection waveSection) {
            byte[] bytes = this.get(waveSection);
            return new String(bytes);
        }

        public int getInt(WaveSection waveSection) {
            byte[] bytes = this.get(waveSection);
            return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt();
        }

        public short getShort(WaveSection waveSection) {
            byte[] bytes = this.get(waveSection);
            return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
        }

        public void printByteInfo() {
            for (WaveSection waveSection : WaveSection.values()) {
                if (waveSection.numBytes == 4
                        && waveSection.endian == ByteOrder.BIG_ENDIAN) {
                    System.out.println("SECTION:" + waveSection + ":STRING:"
                            + this.getString(waveSection));
                } else if (waveSection.numBytes == 4
                        && waveSection.endian == ByteOrder.LITTLE_ENDIAN) {
                    System.out.println("SECTION:" + waveSection + ":INTEGER:"
                            + this.getInt(waveSection));
                } else if (waveSection.numBytes == 2
                        && waveSection.endian == ByteOrder.LITTLE_ENDIAN) {
                    System.out.println("SECTION:" + waveSection + ":SHORT:"
                            + this.getShort(waveSection));
                } else {
                    // Data Section
                }
            }
        }

        public void read(String inputPath) throws Exception {
            // Analyze redundant info
            int dataSize = (int) new File(inputPath).length() - HEADER_SIZE;
            WaveSection.DATA.numBytes  = dataSize; // Can't have two threads using this at the same time

            // Read from File
            DataInputStream inFile = new DataInputStream(new FileInputStream(inputPath));

            for (WaveSection waveSection : WaveSection.values()) {
                byte[] readBytes = new byte[waveSection.numBytes];
                for (int i = 0; i < waveSection.numBytes; i++) {
                    readBytes[i] = inFile.readByte();
                }
                this.put(waveSection, readBytes);
            }

            inFile.close();
        }

        public void write(String outputPath) throws Exception {
            // Analyze redundant info
            int dataSize = this.get(WaveSection.DATA).length;
            this.put(WaveSection.CHUNK_SIZE, dataSize+36);
            this.put(WaveSection.SUBCHUNK2_SIZE, dataSize);

            int byteRate = this.getInt(WaveSection.SAMPLE_RATE)*this.getShort(WaveSection.BLOCK_ALIGN);
            this.put(WaveSection.BYTE_RATE, byteRate);

            // Write to File
            DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(outputPath));

            for (WaveSection waveSection : WaveSection.values()) {
                dataOutputStream.write(this.getBytes(waveSection));
            }

            dataOutputStream.close();
        }

        public AudioFormat createAudioFormat() {
            boolean audioSignedSamples = true; // Samples are signed
            boolean audioBigEndian = false;
            float sampleRate = (float) this.getInt(WaveSection.SAMPLE_RATE);
            int bitsPerSample = (int) this.getShort(WaveSection.BITS_PER_SAMPLE);
            int numChannels = (int) this.getShort(WaveSection.NUM_CHANNELS);
            return new AudioFormat(sampleRate, bitsPerSample,
                    numChannels, audioSignedSamples, audioBigEndian);
        }
    }

    public static class WavAudioPlayer {
        WavData waveData = new WavData();

        public WavAudioPlayer(WavData waveData){
            this.waveData = waveData;
        }

        public void playAudio() throws Exception {
            byte[] data = waveData.getBytes(WaveSection.DATA);

            // Create an audio input stream from byte array
            AudioFormat audioFormat = waveData.createAudioFormat();
            InputStream byteArrayInputStream = new ByteArrayInputStream(data);
            AudioInputStream audioInputStream = new AudioInputStream(byteArrayInputStream,
                    audioFormat, data.length / audioFormat.getFrameSize());

            // Write audio input stream to speaker source data line
            DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,
                    audioFormat);
            SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
            sourceDataLine.open(audioFormat);
            sourceDataLine.start();

            // Loop through input stream to write to source data line
            byte[] tempBuffer = new byte[10000];
            int cnt;
            while ((cnt = audioInputStream.read(tempBuffer, 0, tempBuffer.length)) != -1) {
                sourceDataLine.write(tempBuffer, 0, cnt);
            }

            // Cleanup
            sourceDataLine.drain();
            sourceDataLine.close();
            byteArrayInputStream.close();
        }
    }

    public static class WavAudioRecorder implements Runnable {
        WavData waveData = new WavData();
        boolean recording = true;
        Thread runningThread;
        ByteArrayOutputStream byteArrayOutputStream;

        public WavAudioRecorder(WavData waveData){
            this.waveData = waveData;
        }

        public void startRecording(){
            this.recording = true;
            this.runningThread = new Thread(this);
            runningThread.start();  
        }

        public WavData stopRecording() throws Exception{
            this.recording = false;
            runningThread.stop();

            waveData.put(WaveSection.DATA, byteArrayOutputStream.toByteArray());

            return waveData;
        }

        public void run() {
            try {
                // Create an audio output stream for byte array
                byteArrayOutputStream  = new ByteArrayOutputStream();

                // Write audio input stream to speaker source data line
                AudioFormat audioFormat = waveData.createAudioFormat();
                DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
                TargetDataLine targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
                targetDataLine.open(audioFormat);
                targetDataLine.start();

                // Loop through target data line to write to output stream
                int numBytesRead;
                byte[] data = new byte[targetDataLine.getBufferSize() / 5];
                while(recording) {
                    numBytesRead =  targetDataLine.read(data, 0, data.length);
                    byteArrayOutputStream.write(data, 0, numBytesRead);
                }

                // Cleanup
                targetDataLine.stop();
                targetDataLine.close();
                byteArrayOutputStream.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
导入java.nio.ByteBuffer; 导入java.nio.ByteOrder; 导入java.util.LinkedHashMap; 导入javax.sound.sampled.*; /** *此类读取.wav文件并将其转换为一组字节数组。 * *然后打印出这些字节数组表示的信息。 * *使用扬声器播放这些字节数组的示例。 * *它还将字节数组转换为.wav文件。 * *这一概念的扩展可以通过麦克风录音。 *在这种情况下,需要假设一些值,如采样率。 * *看https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ 对于.wav文件规范 * *@author sizu */ 公共类WavFileHelper{ 公共静态void main(字符串[]args){ 最后一个字符串换行符=“\n”; int记录样本=22050; 短记录BITSPERSAMPLE=16; 短记录numchannels=2; String inputFile=“/input.wav”;//将wav文件放在顶级目录中,即S:/input.wav 字符串outputFile=“/output.wav”; String recordedFile=“/capture.wav”; 系统输出打印项次(“开始”); 试一试{ WavData wavInputData=新的WavData(); WavData wavRecordData=新的WavData(); wavRecordData.put(WaveSection.SAMPLE_RATE,recordingSampleRate); wavRecordData.put(WaveSection.BITS_/样本,RecordingBitsPer样本); wavRecordData.put(WaveSection.NUM_通道,recordingNumChannels); System.out.println(换行符+“将WAV文件转换为字节数组”); wavInputData.read(inputFile); System.out.println(换行符+“将字节数组转换为WAV文件”); wavInputData.write(输出文件); System.out.println(换行符+“显示输入文件的字节数组信息”); wavInputData.printByteInfo(); System.out.println(NEWLINE+“开始录制-您可以将麦克风连接到扬声器”); WavAudioRecorder recorder=新的WavFileHelper.WavAudioRecorder(wavRecordData); 记录器。开始记录(); System.out.println(换行符+“播放字节数组(这将被记录)”); WavAudioPlayer=新的WavFileHelper.WavAudioPlayer(wavInputData); player.playAudio(); System.out.println(换行符+“停止录制以进行录制”); recorder.stopRecording(); System.out.println(换行符+“显示字节数组信息”); wavRecordData.printByteInfo(); System.out.println(换行符+“在WAV文件中保存录制”); wavRecordData.write(recordedFile); }捕获(例外情况除外){ 例如printStackTrace(); } 系统输出打印(“完成”); } 公共静态枚举波段{ //12字节 CHUNK_ID(4,字节顺序。BIG_ENDIAN), 块大小(4,字节顺序,小字节), 格式(4,字节顺序。BIG_ENDIAN), //24字节 SUBCHUNK1_ID(4,字节顺序。BIG_ENDIAN), 子chunk1_大小(4,字节顺序。小字节), 音频格式(2,字节顺序。小字节), NUM_通道(2,字节顺序,小字节), 采样率(4,字节顺序,小字节), 字节速率(4,字节顺序,小字节), 块对齐(2,字节顺序。小字节), 每个样本的位(2,字节顺序。小字节), //8字节 SUBCHUNK2_ID(4,字节顺序。BIG_ENDIAN), 子chunk2_大小(4,字节顺序。小字节), 数据(0,字节顺序,小字节), ; 私有整数单位; 私有字节顺序; 波段(整数字节,字节顺序endian){ this.numBytes=numBytes; this.endian=endian; } } 公共静态类WavData扩展LinkedHashMap{ static int HEADER_SIZE=44;//数据段前有44位 静态int默认值_SUBCHUNK1_SIZE=16; 静态短默认_音频_格式=1; 静态短默认块对齐=4; 静态字符串默认值\u CHUNK\u ID=“RIFF”; 静态字符串默认值\u FORMAT=“WAVE”; 静态字符串默认值\u SUBCHUNK1\u ID=“fmt”; 静态字符串默认值\u SUBCHUNK2\u ID=“数据”; 公共数据(){ this.put(WaveSection.CHUNK\u ID,默认\u CHUNK\u ID); this.put(WaveSection.FORMAT,默认_格式); this.put(WaveSection.SUBCHUNK1\u ID,默认的SUBCHUNK1\u ID); this.put(WaveSection.SUBCHUNK1\u大小,默认的SUBCHUNK1\u大小); this.put(WaveSection.AUDIO\u格式,默认\u AUDIO\u格式); this.put(WaveSection.BLOCK\u ALIGN,默认\u BLOCK\u ALIGN); this.put(WaveSection.SUBCHUNK2\u ID,默认的SUBCHUNK2\u ID); this.put(WaveSection.CHUNK_SIZE,0); 此.put(WaveSection.SUBCHUNK2_大小,0); 此.put(WaveSection.BYTE_速率,0); } 公共作废put(WaveSection WaveSection,字符串值){ byte[]bytes=value.getBytes(); this.put(waveSection,字节); } 公共作废put(WaveSection WaveSection,int值){ byte[]bytes=ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putin(value.array(); this.put(waveSection,字节); } 公开作废认沽权证
`public static byte[] fileToByteArray(String name){
    Path path = Paths.get(name);
    try {
        return Files.readAllBytes(path);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}`