Audio WAV文件头格式
来源:互联网 发布:winscp是什么软件 编辑:程序博客网 时间:2024/05/16 16:57
最近需要对多个WAV文件进行拼接,这就涉及到WAV文件头的创建和修改更新。之前的方式是利用第一个WAV的文件头,在最后全部拼接完后再修改文件头中的文件长度及音频数据长度。这个长度如果不修改,最后拼接的文件虽然大小是各WAV文件大小之和,但播放的时候只播放第一段的WAV文件,因为WAV文件头中的大小就是第一段WAV的大小,播放器读取文件头会根据这个大小来显示时长和播放。
现在需求有变,第一段文件可能是静音空数据,这就导致第一段没有文件头,其实也可以从WAV文件中拷贝头44字节出来,但为搞清楚文件头各字节含义,以及便于统一程序控制(拼装各WAV文件,不用判断该WAV是否需要跳过44字节头)。看代码:
/** * @param sampleRate 采样率,如44100 * @param channels 通道数,如立体声为2 * @param bitsPerSample 采样精度,即每个采样所占数据位数,如16,表示每个采样16bit数据,即2个字节 * @param bytePerSecond 音频数据传送速率, 单位是字节。其值为采样率×每次采样大小。播放软件利用此值可以估计缓冲区的大小。 * bytePerSecond = sampleRate * (bitsPerSample / 8) * channels * @param fileLenIncludeHeader wav文件总数据大小,包括44字节wave文件头大小 * @return wavHeader */ private byte[] getWaveFileHeader(int sampleRate, int channels, int bitsPerSample, int bytePerSecond, long fileLenIncludeHeader) { byte[] wavHeader = new byte[44]; long totalDataLen = fileLenIncludeHeader - 8; long audioDataLen = totalDataLen - 36; //ckid:4字节 RIFF 标志,大写 wavHeader[0] = 'R'; wavHeader[1] = 'I'; wavHeader[2] = 'F'; wavHeader[3] = 'F'; //cksize:4字节文件长度,这个长度不包括"RIFF"标志(4字节)和文件长度本身所占字节(4字节),即该长度等于整个文件长度 - 8 wavHeader[4] = (byte)(totalDataLen & 0xff); wavHeader[5] = (byte)((totalDataLen >> 8) & 0xff); wavHeader[6] = (byte)((totalDataLen >> 16) & 0xff); wavHeader[7] = (byte)((totalDataLen >> 24) & 0xff); //fcc type:4字节 "WAVE" 类型块标识, 大写 wavHeader[8] = 'W'; wavHeader[9] = 'A'; wavHeader[10] = 'V'; wavHeader[11] = 'E'; //ckid:4字节 表示"fmt" chunk的开始,此块中包括文件内部格式信息,小写, 最后一个字符是空格 wavHeader[12] = 'f'; wavHeader[13] = 'm'; wavHeader[14] = 't'; wavHeader[15] = ' '; //cksize:4字节,文件内部格式信息数据的大小,过滤字节(一般为00000010H) wavHeader[16] = 0x10; wavHeader[17] = 0; wavHeader[18] = 0; wavHeader[19] = 0; //FormatTag:2字节,音频数据的编码方式,1:表示是PCM 编码 wavHeader[20] = 1; wavHeader[21] = 0; //Channels:2字节,声道数,单声道为1,双声道为2 wavHeader[22] = (byte) channels; wavHeader[23] = 0; //SamplesPerSec:4字节,采样率,如44100 wavHeader[24] = (byte)(sampleRate & 0xff); wavHeader[25] = (byte)((sampleRate >> 8) & 0xff); wavHeader[26] = (byte)((sampleRate >> 16) & 0xff); wavHeader[27] = (byte)((sampleRate >> 24) & 0xff); //BytesPerSec:4字节,音频数据传送速率, 单位是字节。其值为采样率×每次采样大小。播放软件利用此值可以估计缓冲区的大小; //bytePerSecond = sampleRate * (bitsPerSample / 8) * channels wavHeader[28] = (byte)(bytePerSecond & 0xff); wavHeader[29] = (byte)((bytePerSecond >> 8) & 0xff); wavHeader[30] = (byte)((bytePerSecond >> 16) & 0xff); wavHeader[31] = (byte)((bytePerSecond >> 24) & 0xff); //BlockAlign:2字节,每次采样的大小 = 采样精度*声道数/8(单位是字节); 这也是字节对齐的最小单位, 譬如 16bit 立体声在这里的值是 4 字节。 //播放软件需要一次处理多个该值大小的字节数据,以便将其值用于缓冲区的调整 wavHeader[32] = (byte)(bitsPerSample * channels / 8); wavHeader[33] = 0; //BitsPerSample:2字节,每个声道的采样精度; 譬如 16bit 在这里的值就是16。如果有多个声道,则每个声道的采样精度大小都一样的; wavHeader[34] = (byte) bitsPerSample; wavHeader[35] = 0; //ckid:4字节,数据标志符(data),表示 "data" chunk的开始。此块中包含音频数据,小写; wavHeader[36] = 'd'; wavHeader[37] = 'a'; wavHeader[38] = 't'; wavHeader[39] = 'a'; //cksize:音频数据的长度,4字节,audioDataLen = totalDataLen - 36 = fileLenIncludeHeader - 44 wavHeader[40] = (byte)(audioDataLen & 0xff); wavHeader[41] = (byte)((audioDataLen >> 8) & 0xff); wavHeader[42] = (byte)((audioDataLen >> 16) & 0xff); wavHeader[43] = (byte)((audioDataLen >> 24) & 0xff); return wavHeader; }
修改文件头中的文件长度及音频PCM数据长度:
/** * 更新wav文件头 * * @param totalFileLen 包含44字节wav头及所有PCM数据总和 */ private void updateWavFileHeader(String finalVoiceFilePath, long totalFileLen) { Log.e(TAG, "updateWavFileHeader()--->>totalFileLen = " + totalFileLen); try { RandomAccessFile randomAccessFile = new RandomAccessFile(finalVoiceFilePath, "rw"); //更新wav文件头04H— 08H的数据长度:该长度 = 文件总长 - 8 randomAccessFile.seek(4); randomAccessFile.write(long2bytes(totalFileLen - 8)); //更新wav文件头28H— 2CH,实际PCM采样数据长度 randomAccessFile.seek(40); randomAccessFile.write(long2bytes(totalFileLen - 44)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
参考文章:
1、http://www.cnblogs.com/cheney23reg/archive/2010/08/08/1795067.html
0 0
- Audio WAV文件头格式
- wav文件头格式详解
- 一、各种WAV文件头格式
- 一、各种WAV文件头格式
- WAV文件的头信息(文件头格式)
- WAV头格式分析
- wav头格式
- 根据要求填充,ACM波形.wav格式的文件头
- WAV文件头信息
- wav 文件头解析
- 读取wav文件头
- .wav文件头分析
- WAV文件头信息
- wav 文件头解析
- wave文件 wav格式
- wav文件的文件头
- wav文件的文件头
- 使用Audio Player来播放wav文件
- 不仅仅是SLAM而是真正的机器视觉
- 为input中的date设置日期
- JDBC API getTables()、getColumns() 中,通配符进行转义的问题
- Unit 3-Lecture3: Counting with Bijections
- linux 基础学习之 磁盘,分区,MBR与GPT
- Audio WAV文件头格式
- iOS
- 怎么在oracle中手建一个数据库表?
- Spring底层创建对象的几种方式
- Java final变量与final类的内存模型
- 2016中国大数据市场研究报告
- VMware Workstation删除虚拟机
- 冒泡排序
- selinux(案例) recovery删除data目录下的文件