专栏首页搜狗测试语音项目——Android录音学习

语音项目——Android录音学习

一、引言

小编所在的语音SDK项目,提供的是AI服务,录音是基础,识别是品质。录音方式选择,录音参数设置,录音策略的制定(如解决首字吞字问题),录音架构选择,对识别都有着重要影响。

二、Android两种录音方式

1、音频采集简介

Android提供了两个API用于录音的实现:MediaRecorder 和AudioRecord。

(1). MediaRecorder:录制的音频文件是经过压缩后的,需要设置编码器。并且录制的音频文件可以用系统自带的Music播放器播放。MediaRecorder已经集成了录音、编码、压缩等,并支持少量的录音音频格式,但是这也是他的缺点,支持的格式过少并且无法实时处理音频数据。

(2). AudioRecord:主要实现对音频实时处理以及边录边播功能,相对MediaRecorder比较专业,输出是PCM语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩。

2、优、缺点

录音方式

优点

缺点

AudioRecord(基于字节流录音)

可实现语音的实时处理,边录边播,对音频的实时处理,AudioTrack更接近底层。

输出的是PCM的语音数据,如果保存成音频文件是不能被播放器播放的。要用AudioTrack进行处理。API还有待完善,常见的暂停功能都不支持。

MediaRecorder(基于文件录音)

已集成了录音,编码,压缩等。封装度很高,操作简单,录制的音频文件可以用系统自带的播放器播放。

缺点:无法实现实时处理音频,输出的音频格式少。录制的音频文件是经过压缩后的,需要设置编码器。

技术选型,目前行业现状:API多是选用AudioRecord

三、AudioRecord

1、AudioRecord

AndioRecord 类的主要功能是让各种 Java 应用能够管理音频资源,以便它们通过此类能从平台的音频输入硬件记录音频。此功能的实现就是通过 "pulling 同步"(reading读取)AudioRecord对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过后面三个类方法中的一个去及时地获取AudioRecord 对象的录音数据。

AudioRecord 类提供了三个获取声音数据的方法,分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int)。无论选择使用那一个方法,都必须事先设定方便用户使用的声音数据的存储格式。

开始录音的时候,一个AudioRecord需要初始化一个相关联的声音buffer,这个buffer主要是用来保存新的声音数据。这个buffer的大小,可以在对象构造期间去指定。它表明一个AudioRecord对象还没有被读取(同步)声音数据前能录多长的音(即一次可以录制的声音容量)。声音数据从音频硬件中被读出,数据大小不超过整个录音数据的大小(可以分多次读出),即每次读取初始化 buffer 容量的数据。音频采集工作,需要构造一个AudioRecord对象,然后传入各种不同配置的参数。

2、利用AudioRecord实现Android录音的流程

(1). 构造一个AudioRecord对象,其中需要的最小录音缓存buffer大小可以通过getMinBufferSize方法得到。如果buffer容量过小,将导致对象构造的失败;

(2). 初始化一个buffer,该buffer大于等于AudioRecord对象用于写声音数据的buffer大小;

(3). 调用startRecording函数,开始录音;

(4). 创建一个数据流,一边从AudioRecord中读取声音数据到初始化的buffer,一边将buffer中数据导入数据流,生成PCM格式文件;

(5). 录音结束时,关闭数据流,停止录音;

3、构造函数

publicAudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, intbufferSizeInBytes)

参数说明

(1). audioSource这个参数指的是音频采集的输入源,接受的值定义在MediaRecorder.AudioSource里面,一般来说使用DEFAULT或者MIC即可。

(2). sampleRateInHz指定采集音频的采样频率,比较通用的是44100(44.1kHz),这个值是科学家们通过奈葵斯特采样定理得出的一个人能接受最佳的采样频率值。

(3). channelConfig指定AudioRecord采集几个声道的声音,预设值定义在AudioFormat中,常用值有CHANNEL_CONFIGURATION_MONO(单声道) 和 CHANNEL_CONFIGURATION_STEREO(双声道)。

(4). audioFormat指定采样PCM数据的采样格式,预设值定义在也AudioFormat中,常用值有:

ENCODING_PCM_8BIT、ENCODING_PCM_16BIT和ENCODING_PCM_FLOAT,其中ENCODING_PCM_16BIT可以保证兼容大部分Andorid手机。

(5). bufferSizeInBytes配置AudioRecord内部的音频数据缓冲区,一般来说缓存区越小,产生的音频延迟也越小。可以通过AudioRecord.getMinBufferSize获取最小的缓冲区。(将音频采集到缓冲区中然后再从缓冲区中读取)

4、录音参数设置

(1). audioSource:音频源,从哪个硬件设备获取音频,一般直接设置成麦克风。

MediaRecorder.AudioSource.MIC,AudioRecorder为它设置了默认值:

AUDIO_INPUT =MediaRecorder.AudioSource.MIC;

AudioSource可以设置的来源包括:

  • MediaRecorder.AudioSource.CAMCORDER :设定录音来源于同方向的相机麦克风相同,若相机无内置相机或无法识别,则使用预设的麦克风
  • MediaRecorder.AudioSource.DEFAULT :默认音频源
  • MediaRecorder.AudioSource.MIC:设定录音来源为主麦克风。
  • MediaRecorder.AudioSource.VOICE_CALL:设定录音来源为语音拨出的语音与对方说话的声音
  • MediaRecorder.AudioSource.VOICE_COMMUNICATION:摄像头旁边的麦克风
  • MediaRecorder.AudioSource.VOICE_DOWNLINK:电话下行声音
  • MediaRecorder.AudioSource.VOICE_RECOGNITION:语音识别
  • MediaRecorder.AudioSource.VOICE_UPLINK:电话上行声音

(2). sampleRateInHz:音频采样率,越高质量越好。

  • 常用频率为44100Hz,可以在所有的设备上完美运行,还有其他的频率包括22050,16000,11025只能在某些设备上正常运行。
  • AudioFormat.SAMPLE_RATE_UNSPECIFIED 可以自动根据选定的音频源设置频率。AUDIO_SAMPLE_RATE = 16000。

(3). ChannelConfig:声道设置

  • AudioFormat.CHANNEL_IN_MONO单声道,常量为AUDIO_CHANNEL =AudioFormat.CHANNEL_IN_MONO。
  • CHANNEL_IN_STEREO为双声道,立体声道。

(4). audioFormat:音频格式

  • AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT, andAudioFormat.ENCODING_PCM_FLOAT,以上都是音频PCM编码,android支持的采样大小16bit 或者8bit。当然采样大小越大,那么信息量越多,音质也越高,现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。

(5). bufferSizeInBytes:采集数据需要的缓冲区的大小

  • getMinBufferSize()可以查看最小的缓冲区。使用的缓冲区不能比getMinBufferSize获取的最小值,否则将报错。
  • public static int getMinBufferSize (int sampleRateInHz, intchannelConfig, int audioFormat)

四、录音编码

1、编码格式

AudioRecorder录音声音数据从音频硬件中被读出,编码格式为 PCM格式,PCM是英文Pulse-codemodulation的缩写,中文译名是脉冲编码调制。但 PCM语音数据,如果保存成音频文件,是不能够被播放器播放的。

2、播放PCM文件

Audacity工具可以导入pcm原始文件,并且提供了波形图查看和播放功能。

操作流程是:

文件 => 导入 => 原始数据 => 设置PCM数据格式=> 导入

具体效果图如下:

五、录音问题

项目测试,遇到的用户反馈的录音问题举例:录音架构、适配

(1). start线程、read loop线程,是同一个线程还是分开的子线程,线程的释放策略;

(2). 是否有常驻线程,是否有超时守候机制;

(3). 是否有麦克风占用问题、是否有read线程卡住问题;

(4). 对不同硬件设置,录音的参数设置是否有适配策略(Audiosource、Channel);

(5). 是否可支持蓝牙输入;


注:参考

https://cloud.tencent.com/developer/article/1560099

https://www.jianshu.com/p/90c4071c7768

https://developer.android.com/reference/android/media/AudioRecord

https://blog.csdn.net/u010126792/article/details/86309592

https://www.jianshu.com/p/01b374acd6a4

本文分享自微信公众号 - 搜狗测试(SogouQA),作者:​baiyang

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-02-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android语音录制,语音发送

    这是一个录音的例子,可用于IM的语音发送,OA的语音留言等。 首先我们需要引入权限:

    饮水思源为名
  • Android使用webrtc实现检测用户是否在说话

    我们在Android应用做语音识别的时候,一般是用户唤醒之后开始说话。当用户超过一定的时候没有说话,就停止录音,并把录音发送到语音识别服务器,获取语音识别结果。...

    夜雨飘零
  • Android仿微信语音对讲录音功能

    自微信出现以来取得了很好的成绩,语音对讲的实现更加方便了人与人之间的交流。今天来实践一下微信的语音对讲的录音实现,这个也比较容易实现。在此,我将该按钮封装成为一...

    砸漏
  • Android实现语音播放与录音功能

    本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下

    砸漏
  • Arduino 入门项目系列 (5) - Android 手机通过蓝牙语音控制 LED

    为了加快 Arduino 的学习,决定周一这一天的上午也用来学习 Arduino。今天还是继续学习蓝牙模块的使用。实现通过蓝牙模块,在手机端语音控制 LED 的...

    caoqi95
  • 2019 Google I/O 大会:充满了科技感 & 人文关怀

    在刚过去的时间里(北京时间 5月8日),一年一度的2019年 Google I/O大会 在美国 谷歌山景城 海岸线圆形剧场 如期举行

    AndroidTraveler
  • Android使用AIUI快速搭建智能助手

    目前大部分的手机都有语音助手,例如小米手机的小爱同学,VIVO的小V等等,通过智能助手我们可以快速询一些资讯或者操作手机,例如询问天气,发送微信给你的好友等等。...

    夜雨飘零
  • FFmpeg 开发(01):FFmpeg 编译和集成

    FFmpeg 是一款知名的开源音视频处理软件,它提供了丰富而友好的接口支持开发者进行二次开发。

    字节流动
  • Android实现录音方法(仿微信语音、麦克风录音、发送语音、解决5.0以上BUG)

    使用很简单,主要就是开始录音startRecord()、取消录音cancelRecord()、结束录音stopRecord()和录音监听setOnAudioSt...

    砸漏

扫码关注云+社区

领取腾讯云代金券