使用AudioRecord录制语音
来源:互联网 发布:linux mysql配置文件 编辑:程序博客网 时间:2024/06/05 14:25
Android中录制语音最简单的方式是使用MediaRecorder来录制,但是MediaRecorder只能录制几种语音格式,录制的结果也是直接保存到了文件中。如果需要实现自定义的需求,比如录制过程中显示音量的大小,就得使用AudioRecord来录制语音了。
几个概念
在 数字音频基础 中讲到了一些数字音频的基础知识,这里将几个需要用到的概念再解释下:
- 采样:录音的本质就是将连续的空气压力变化录制下来。由于时间是连续的,数字化录音就只能在某些时间记录下那时的空气压力变化,这个过程就是采样。
- 量化及量化误差:量化就是用数字来表示空气压力的变化值,由于计算机的存储能力有限,无法精确表达所有的空气压力变化值,所以真实的压力值肯定会与量化值有一定的误差。
- 通道数:这个就和我们日常所说的左声道、右声道是一个意思,通道数指的就是有多少个声道。
- 采样率:即一秒钟采集的次数。
涉及的方法参数解析
在录音的时候,我们需要构造一个AudioRecord对象,然后通过它与硬件设备打交道,来获取语音数据。先看看它的构造函数:
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
audioSource:录音源,指定声音是从哪里录制的,常用的参数有:MIC、VOICE_COMMUNICATION。MIC录制的时候没啥特别的,但是VOICE_COMMUNICATION就有些特别,它表示当前录音是为了语音通信,比如VoIP。在这种场景下,驱动及硬件就可以做一些特殊的处理,比如开启回声消除等算法来达到更好的通话音质。
sampleRateInHz:即前面说的采样率,常用采样率有:8000、16000,CD音质使用的是44.1khz。
channelConfig:声道配置,和日常说的左右声道意思一样,只是这个参数所使用的值是一些规定好的值,比如CHANNEL_IN_MONO表示单声道,CHANNEL_IN_STEREO表示立体声。
audioFormat:这个是指量化所采用的方案,一般使用的是 ENCODING_PCM_16BIT 或ENCODING_PCM_8BIT,PCM表示两个量化值之间是线性关系,而不是类似指数那种关系。16BIT和8BIT指的是使用2个字节来表示一个量化点,还是使用一个字节来表示。
bufferSizeInBytes:用字节表示的缓冲区大小,AudioRecord在收集到语音数据后,会缓存到特定的缓冲区里面,等待调用者读取。缓冲区的大小不能小于getMinBufferSize所返回的值,否则会导致初始化失败。调用者为了防止未能及时获取语音数据,而导致语音数据丢失,可以将这个值设为几倍于最小缓冲区的大小。
public int read(byte[] audioData, int offsetInBytes, int sizeInBytes)
在开始录制之后,需要调用这个方法获取语音数据。这个方法是一个阻塞的方法,在audioData填满后,或者发生错误时,这个方法才会返回。
这个缓冲区的大小的设定,一般是和一帧的数据量有关,一帧通常设为20ms。比如在采样率为16000、立体声、ENCODING_PCM_16BIT 的场景下,20ms就需要采样320次(16000/1000*20),每次采样需要采集2个点(左右声道),每个采样点两个字节(16BIT),所以20ms的数据量为1280字节。
录音流程
录音流程比较简单:
- 构造AudioRecord对象。
- 调用AudioRecord.getState检查AudioRecord对象是否有效,如果无效表示初始化失败,直接结束。
- 调用AudioRecord.startRecording开始录音。
- 调用AudioRecord.read读取数据,read返回后,将数据写入文件。
- 调用AudioRecord.stopRecording结束录音。
该流程使用的是read方法来读取数据,AudioRecord也提供了通知方式来读取数据,即周期性的通知数据到了。
这里就不之间贴代码了,需要的读者可以见该文件。
语音数据的处理
在read返回之后,缓冲区里面存储的就是语音的数据,通过对语音的数据进行一些处理,可以达到某些目的。语音数据排列是按照每个采样点顺序排列的,如果是多声道的语音数据,则两个声道也是按照顺序排列的。通过检查采样点的数值,我们可以做以下两种事情:
- 显示当前音量大小:每个采样点的数值及时反馈到UI界面上,给用户反馈,让用户知道当前的声音大小。
- 静音检测:如果用户不给应用录音权限的时候,程序读取到的数据都是没有声音的,也就是采样点的值为0。通过检查采样点的数值是否都为0,可以判断出来是否有录音权限。
- 使用AudioRecord录制语音
- 使用AudioRecord录制音频
- Android音频开发之使用AudioRecord录制
- 使用AudioTrack和AudioRecord录制和播放PCM wave文件
- 使用AudioRecord和AudioTrack来录制和播放音频
- 使用AudioTrack和AudioRecord录制和播放PCM wave文件
- Android Native C++ 层中使用AudioRecord录制PCM音频
- 使用AudioTrack和AudioRecord录制和播放PCM wave文件
- AudioRecord 录制音频
- AudioRecord音频录制的IllegalStateException
- Android使用AudioRecord录制pcm音频原始数据以及使用AudioTrack播放
- 音频的两种录制方式-AudioRecord,MediaRecorder的使用及播放
- AudioRecord实现"助听器" ,录制和播放功能
- Android: AudioRecord 通过蓝牙设备录制声音
- Android音频录制--AudioRecord
- AudioRecord录制音频文件并存储本地
- Android AudioRecord录制wav格式的音频
- android AudioRecord 音频录制 噪音消除
- 2015弱校联盟(2) - J. Usoperanto
- Java finished with non-zero exit value 2 - Android Gradle
- 前端学习首页
- eCharts使用图表简单示例
- pat1013Battle Over Cities (25)
- 使用AudioRecord录制语音
- LeetCode题解:Construct Binary Tree from Preorder and Inorder Traversal
- selenium-webdriver(python) (十五) -- 鼠标事件
- 大话计算机-计算机系统-硬件-运算器
- 基本字符串压缩
- Hibernate CURD操作
- 安卓在xml文件(布局文件)中做一些细微改变却运行程序报错的原因
- LeetCode算法第7篇:235 Lowest Common Ancestor of a Binary Search Tree
- HDU 2256 Problem of Precision(矩阵快速幂 数论 )