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;
}
}`