wave文件格式解析
-
wave的头文件详细
-
注意事项
- 在第13个字节开始,不一定是fmt(0x666d7420)需要定位fmt的位置
- 在fmt结束后有可能有一段文件描述,需要定位data位置
-
wave格式实体类
package io.renren.modules.scl.util;
import lombok.Data;
/**
* WAVE文件格式
*
* @author 大兵
* @date 2018-08-03 11:27
**/
@Data
public class WaveFormat {
/**
* data标识结束位置
*/
private Long dataFlag;
/**
* fmt标识结束位置
*/
private Long fmtFlag;
/**
* 数据类型是否为浮点数
*/
private boolean floatFlag;
//需要读取的参数
/**
* 采样率
*/
private long samplingRate;
/**
* 通道数
*/
private int channelNumber;
/**
* 采样位数
*/
private int bitsPer;
/**
* 每秒数据量
*/
private long byteRate;
/**
* 块大小
*/
private int blockAlign;
/**
* 头文件长度
*/
private long headerLength;
/**
* 帧长
*/
private long frameLength;
/**
* 原始信号大小
*/
private long fileSize;
/**
* 时长(精确到毫秒数)
*/
private long duration;
/**
* 数据大小
*/
private long dataSize;
}
- wave转换工具类
package io.renren.modules.scl.util;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.Objects;
/**
* Wave工具类(重构)
*
* @author 大兵
* @date 2018-08-03 11:38
**/
public class WaveUtil {
/**
* fmt标识
*/
private static final long FMT_MAGIC = 0x666D7420;
/**
* data标识
*/
private static final long DATA_MAGIC = 0x64617461;
/**
* riff标识
*/
private static final long RIFF_MAGIC = 0x52494646;
/**
* wav类型
*/
private static final long WAVE_MAGIC = 0x57415645;
/**
* 读取wave头文件
* 不关闭流
*/
public static WaveFormat readFormat(RandomAccessFile raf) throws IOException {
WaveFormat waveFormat = new WaveFormat();
//判断是否是wave文件
if (isWave(raf)) {
throw new RuntimeException("这不是个wave文件");
}
//查找fmt标识位置
waveFormat.setFmtFlag(findFmtFlag(raf));
if (waveFormat.getFmtFlag() == null) {
throw new RuntimeException("未找到fmt标识符");
}
//查找data标识位置
waveFormat.setDataFlag(findDataFlag(raf));
if (waveFormat.getDataFlag() == null) {
throw new RuntimeException("未找到data标识符");
}
raf.seek(waveFormat.getFmtFlag() + 4);
waveFormat.setFloatFlag(Unsigned.shortToLittle(raf.readShort()) == 3);
waveFormat.setChannelNumber(Unsigned.shortToLittle(raf.readShort()));
waveFormat.setSamplingRate(Unsigned.intToLittle(raf.readInt()));
waveFormat.setByteRate(Unsigned.intToLittle(raf.readInt()));
waveFormat.setBlockAlign(Unsigned.shortToLittle(raf.readShort()));
waveFormat.setBitsPer(Unsigned.shortToLittle(raf.readShort()));
waveFormat.setFileSize(raf.length());
waveFormat.setHeaderLength(waveFormat.getDataFlag() + 4);
waveFormat.setDataSize(raf.length() - waveFormat.getHeaderLength());
waveFormat.setFrameLength(waveFormat.getDataSize() / waveFormat.getBlockAlign());
waveFormat.setDuration((long) ((float) waveFormat.getFrameLength() * 1000 / (float) waveFormat.getSamplingRate()));
return waveFormat;
}
/**
* wave格式化为64位Double浮点数
*
* @param formFile 源文件
* @param toFile 转换后文件
*/
public static void waveTo64BitDouble(File formFile, File