Android音频开发(4):如何存储和解析wav文件
2016-10-20 00:00
711 查看
无论是文字、图像还是声音,都必须以一定的格式来组织和存储起来,这样播放器才知道以怎样的方式去解析这一段数据,例如,对于原始的图像数据,我们常见的格式有YUV、Bitmap,而对于音频来说,最简单常见的格式就是wav格式了。
wav格式,与bitmap一样,都是微软开发的一种文件格式规范,它们都有一个相似之处,就是整个文件分为两部分,第一部分是“文件头”,记录重要的参数信息,对于音频而言,就包括:采样率、通道数、位宽等等,对于图像而言,就包括:图像的宽高、色彩位数等等;第二部分是“数据块”,即一帧一帧的二进制数据,对于音频而言,就是原始的PCM数据;对于图像而言,就是RGB数据。
前面几篇文章讲了如何利用Android平台的API完成原始音频信号的采集和播放,而本文则重点关注如何在Android平台上,将采集到的PCM音频数据保存到wav文件,同时,也介绍如何读取和解析wav文件。
而文章最后,我还会给出一段AudioDemo程序,该程序将最近的几篇文章涉及到的代码综合起来了,演示了一个完整的Android音频从采集到播放的全过程。
下面言归正传,讲讲如何读写wav文件格式。
1.文件头
首先,我们了解一下wav格式的“文件头”,可以参考这篇文章:《WAVEPCMsoundfileformat》
我们可以简单地分析一下这个wav格式头,它主要分为三个部分:
第一部分,属于最“顶层”的信息块,通过“ChunkID”来表示这是一个“RIFF”格式的文件,通过“Format”填入“WAVE”来标识这是一个wav文件。而“ChunkSize”则记录了整个wav文件的字节数。
第二部分,属于“fmt”信息块,主要记录了本wav音频文件的详细音频参数信息,例如:通道数、采样率、位宽等等(含义请参考我的第一篇文章《Android音频开发(1):基础知识》)
第三部分,属于“data”信息块,由“Subchunk2Size”这个字段来记录后面存储的二进制原始音频数据的长度。
分析到这里,我想大家应该就明白了,其实,做一种多媒体格式的解析,也不是一件特别复杂的事,说白了,格式就是一种规范,告诉你,我的二进制数据是怎么存储的,你应该按照什么样的方式来解析。
具体而言,我们可以定义一个如下的Java类来抽象和描述wav文件头:
具体每一个字段的含义,可以参考我上面给出的链接,下面我们再看看如何读写wav文件。
2.读写wav文件
文章开头已经说过,其实说白了,wav文件就是一段“文件头”+“音频二进制数据”,因此:
(1)写wav文件,其实就是先写入一个wav文件头,然后再继续写入音频二进制数据即可
(2)读wav文件,其实也就是先读一个wav文件头,然后再继续读出音频二进制数据即可
那么,在动手写代码之前,有两点你需要搞清楚:
(1)wav文件头中,有哪些是“变化的”,哪些是“不变的”?
比如:文件头开头的“RIFF”字符串就是“不变的”部分,而用来记录音频数据总长度的“Subchunk2Size”变量就是属于“变化的”部分,因为,再音频数据没有彻底全部写完之前,你是无法知道一共写入了多少字节的音频数据的,因此,这个部分,需要用一个变量记录起来,到全部写完之后,再使用Java的“RandomAccessFile”类,将文件指针跳转到“Subchunk2Size”字段,改写一下默认值即可。
(2)如何把int、short变量与byte[]的转换
因为wav文件都是二进制的方式读写,因此,“WavFileHeader”类中定义的变量都需要转换为byte字节流,具体转换方法如下:
关于wav文件读写的类我已经帮大家“封装”好了,并且结合着前面几篇文章给出的音频采集和播放的代码,完成了一个AudioDemo程序,放在我的Github上了,欢迎大家下载运行测试,然后结合着代码具体学习Android音频相关技术,代码地址:
https://github.com/Jhuster/AudioDemo
注:本系列文章的所有代码,以后都会并入到该demo项目中。
3.小结
免费学习更多精品课程,登录乐搏学院官网http://h.learnbo.cn/
或关注我们的官方微博微信,还有更多惊喜哦~
本文出自“Jhuster的专栏”博客,请务必保留此出处http://ticktick.blog.51cto.com/823160/1750593
wav格式,与bitmap一样,都是微软开发的一种文件格式规范,它们都有一个相似之处,就是整个文件分为两部分,第一部分是“文件头”,记录重要的参数信息,对于音频而言,就包括:采样率、通道数、位宽等等,对于图像而言,就包括:图像的宽高、色彩位数等等;第二部分是“数据块”,即一帧一帧的二进制数据,对于音频而言,就是原始的PCM数据;对于图像而言,就是RGB数据。
前面几篇文章讲了如何利用
而文章最后,我还会给出一段AudioDemo程序,该程序将最近的几篇文章涉及到的代码综合起来了,演示了一个完整的Android音频从采集到播放的全过程。
下面言归正传,讲讲如何读写wav文件格式。
1.文件头
首先,我们了解一下wav格式的“文件头”,可以参考这篇文章:
我们可以简单地分析一下这个wav格式头,它主要分为三个部分:
第一部分,属于最“顶层”的信息块,通过“ChunkID”来表示这是一个“RIFF”格式的文件,通过“Format”填入“WAVE”来标识这是一个wav文件。而“ChunkSize”则记录了整个wav文件的字节数。
第二部分,属于“fmt”信息块,主要记录了本wav音频文件的详细音频参数信息,例如:通道数、采样率、位宽等等(含义请参考我的第一篇文章
第三部分,属于“data”信息块,由“Subchunk2Size”这个字段来记录后面存储的二进制原始音频数据的长度。
分析到这里,我想大家应该就明白了,其实,做一种多媒体格式的解析,也不是一件特别复杂的事,说白了,格式就是一种规范,告诉你,我的二进制数据是怎么存储的,你应该按照什么样的方式来解析。
具体而言,我们可以定义一个如下的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36< 7fe1 /p>37 38 39 40 41 42 43 44 45 |
2.读写wav文件
文章开头已经说过,其实说白了,wav文件就是一段“文件头”+“音频二进制数据”,因此:
(1)写wav文件,其实就是先写入一个wav文件头,然后再继续写入音频二进制数据即可
(2)读wav文件,其实也就是先读一个wav文件头,然后再继续读出音频二进制数据即可
那么,在动手写代码之前,有两点你需要搞清楚:
(1)wav文件头中,有哪些是“变化的”,哪些是“不变的”?
比如:文件头开头的“RIFF”字符串就是“不变的”部分,而用来记录音频数据总长度的“Subchunk2Size”变量就是属于“变化的”部分,因为,再音频数据没有彻底全部写完之前,你是无法知道一共写入了多少字节的音频数据的,因此,这个部分,需要用一个变量记录起来,到全部写完之后,再使用Java的“RandomAccessFile”类,将文件指针跳转到“Subchunk2Size”字段,改写一下默认值即可。
(2)如何把int、short变量与byte[]的转换
因为wav文件都是二进制的方式读写,因此,“WavFileHeader”类中定义的变量都需要转换为byte字节流,具体转换方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
注:本系列文章的所有代码,以后都会并入到该demo项目中。
3.小结
免费学习更多精品课程,登录乐搏学院官网
或关注我们的官方微博
相关文章推荐
- Android 音频开发-如何存储和解析wav文件
- Android音频开发(4):如何存储和解析wav文件
- Android音频开发(4):如何存储和解析wav文件
- Android音频开发(4):如何存储和解析wav文件
- Android音频开发(4):如何存储和解析wav文件
- Windows Phone7开发,一步一步完成一个即时聊天软件之咏叹调:在Windows phone 7 中如何压缩WAV音频文件
- 【Android开发经验】如何获取媒体库中所有音频文件信息,并在文件增删后及时更新媒体库
- android开发 解析服务器端xml文件数据存储到android客户端SQLite数据库
- iphone开发 服务器、android、iphone音频文件播放和传输 amr和wav的转换
- 【Android开发经验】如何获取媒体库中所有音频文件信息,并在文件增删后及时更新媒体库(转)
- Android音视频-存储和解析音频文件
- Android开发 解析JSON数据格式 如何去掉JSON数据文件的BOM头
- android录音开发问题<记录1>:AudioRecord录制的音频文件如何用MediaPlayer类读取
- 【Android开发经验】如何获取媒体库中所有音频文件信息,并在文件增删后及时更新媒体库
- Android开发之资源文件存储
- Android网络开发中如何使用JSON进行网络通信---Android JSON数据通讯方法解析
- Android开发九:从网上下载文件并存储到SD卡中
- android开发-------案例十(文件存储--sharedpreferences)
- Android开发进阶(六)--PULL模式解析XML文件
- Android开发之XML文件的解析的三种方法