参考 http://www.cnblogs.com/renhui/p/7457321.html

1.计算缓冲录音数据的字节数组的大小。AudioRecord 需要一个容器来缓冲来自硬件的音频信息。

int recordBufSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);

2.创建AudioRecord对象

audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, recordBufSize);

3.创建数组对象

byte[] buffer = new byte[recordBufSize];

4.开始录音

audioRecord.startRecording();

5.在录音过程中来自硬件的数据写入缓冲数组

audioRecord.read(buffer, 0, recordBufSize);

6.把数组的数据保存到文件

os = new FileOutputStream(pcmFileName);
os.write(buffer);

7.这样的音频文件还需要写入头部信息才能播放

8.代码实例如下

布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent"android:padding="20dp"android:layout_margin="20dp"android:text="start"android:id="@+id/start"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toRightOf="@id/start"app:layout_constraintTop_toTopOf="parent"android:padding="20dp"android:layout_margin="20dp"android:text="stop"android:id="@+id/stop"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@id/start"android:padding="20dp"android:layout_margin="20dp"android:text="transform"android:id="@+id/transform"/></android.support.constraint.ConstraintLayout>

activity文件

public class MainActivity extends AppCompatActivity {// 音频源:音频输入-麦克风private final static int AUDIO_INPUT = MediaRecorder.AudioSource.MIC;// 采样率// 44100是目前的标准,但是某些设备仍然支持22050,16000,11025// 采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级private final static int AUDIO_SAMPLE_RATE = 16000;// 音频通道 单声道private final static int AUDIO_CHANNEL = AudioFormat.CHANNEL_IN_MONO;// 音频格式:PCM编码private final static int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;/*** 需要申请的运行时权限*/private String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};private static final int MY_PERMISSIONS_REQUEST = 1001;private final String pcmFileName = Environment.getExternalStorageDirectory() + "/Download/record.pcm";private final String wavFileName = Environment.getExternalStorageDirectory() + "/Download/record.wav";private AudioRecord audioRecord = null;  // 声明 AudioRecord 对象private int recordBufSize = 0; // 声明recoordBufffer的大小字段private byte[] buffer;private boolean isRecording;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST);findViewById(R.id.start).setOnClickListener(v -> start());findViewById(R.id.stop).setOnClickListener(v -> stop());findViewById(R.id.transform).setOnClickListener(v -> Pcm2WavUtil.pcmToWav(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL,recordBufSize, pcmFileName, wavFileName));}private void stop(){isRecording = false;if (null != audioRecord) {audioRecord.stop();audioRecord.release();audioRecord = null;}}private void start(){//audioRecord能接受的最小的buffer大小recordBufSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING);audioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING, recordBufSize);buffer = new byte[recordBufSize];audioRecord.startRecording();isRecording = true;new Thread(() -> {FileOutputStream os = null;try {if(!new File(pcmFileName).exists()){new File(pcmFileName).createNewFile();}os = new FileOutputStream(pcmFileName);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}if (null != os) {while (isRecording) {int read = audioRecord.read(buffer, 0, recordBufSize);// 如果读取音频数据没有出现错误,就将数据写入到文件if (AudioRecord.ERROR_INVALID_OPERATION != read) {try {os.write(buffer);} catch (IOException e) {e.printStackTrace();}}}try {os.close();} catch (IOException e) {e.printStackTrace();}}}).start();}}

转wav的工具文件

public class Pcm2WavUtil {/*** pcm文件转wav文件** @param inFilename 源文件路径* @param outFilename 目标文件路径*/public static void pcmToWav(long mSampleRate, int mChannel, int mBufferSize, String inFilename, String outFilename) {FileInputStream in;FileOutputStream out;long totalAudioLen;long totalDataLen;long longSampleRate = mSampleRate;int channels = mChannel == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;long byteRate = 16 * mSampleRate * channels / 8;byte[] data = new byte[mBufferSize];try {in = new FileInputStream(inFilename);out = new FileOutputStream(outFilename);totalAudioLen = in.getChannel().size();totalDataLen = totalAudioLen + 36;writeWaveFileHeader(out, totalAudioLen, totalDataLen,longSampleRate, channels, byteRate);while (in.read(data) != -1) {out.write(data);}in.close();out.close();} catch (IOException e) {e.printStackTrace();}}/*** 加入wav文件头*/private static void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,long totalDataLen, long longSampleRate, int channels, long byteRate)throws IOException {byte[] header = new byte[44];// RIFF/WAVE headerheader[0] = 'R';header[1] = 'I';header[2] = 'F';header[3] = 'F';header[4] = (byte) (totalDataLen & 0xff);header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);//WAVEheader[8] = 'W';header[9] = 'A';header[10] = 'V';header[11] = 'E';// 'fmt ' chunkheader[12] = 'f';header[13] = 'm';header[14] = 't';header[15] = ' ';// 4 bytes: size of 'fmt ' chunkheader[16] = 16;header[17] = 0;header[18] = 0;header[19] = 0;// format = 1header[20] = 1;header[21] = 0;header[22] = (byte) channels;header[23] = 0;header[24] = (byte) (longSampleRate & 0xff);header[25] = (byte) ((longSampleRate >> 8) & 0xff);header[26] = (byte) ((longSampleRate >> 16) & 0xff);header[27] = (byte) ((longSampleRate >> 24) & 0xff);header[28] = (byte) (byteRate & 0xff);header[29] = (byte) ((byteRate >> 8) & 0xff);header[30] = (byte) ((byteRate >> 16) & 0xff);header[31] = (byte) ((byteRate >> 24) & 0xff);// block alignheader[32] = (byte) (2 * 16 / 8);header[33] = 0;// bits per sampleheader[34] = 16;header[35] = 0;//dataheader[36] = 'd';header[37] = 'a';header[38] = 't';header[39] = 'a';header[40] = (byte) (totalAudioLen & 0xff);header[41] = (byte) ((totalAudioLen >> 8) & 0xff);header[42] = (byte) ((totalAudioLen >> 16) & 0xff);header[43] = (byte) ((totalAudioLen >> 24) & 0xff);out.write(header, 0, 44);}}

AudioRecord的用法相关推荐

  1. Android 调用系统api录音的两种方式(MediaRecorder、AudioRecord)

    废话 权限.权限.权限,必须要先获取了录音权限,其他的事情晚点再说. 另外,新版本的Android 10系统会对录音有调整,引入了一个录音焦点的概念,也就是说以前的麦克风只能一个APP使用,必须要等它 ...

  2. pcm 降采样_Android_android downsample降低音频采样频率代码,使用Android AudioRecord 录制PCM文 - phpStudy...

    android downsample降低音频采样频率代码 使用Android AudioRecord 录制PCM文件,android SDK保证在所有设备上都支持的采样频率只有44100HZ, 所以如 ...

  3. android pcm文件大小_Android 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件...

    一.AudioRecord API详解 AudioRecord是Android系统提供的用于实现录音的功能类. 要想了解这个类的具体的说明和用法,我们可以去看一下官方的文档: AndioRecord类 ...

  4. c语言中external,static关键字用法

    static用法: 在C中,static主要定义全局静态变量.定义局部静态变量.定义静态函数. 1.定义全局静态变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量.全局静态变量有 ...

  5. Pandas_transform的用法

    先来看一个实例问题. 如下销售数据中展现了三笔订单,每笔订单买了多种商品,求每种商品销售额占该笔订单总金额的比例.例如第一条数据的最终结果为:235.83 / (235.83+232.32+107.9 ...

  6. Python中yield和yield from的用法

    yield 后面接的是 future 对象 调用方 委托生成器 yield from 直接给出循环后的结果 yield from 委托者和子生成器直接通信 yield from 直接处理stopIte ...

  7. pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法

    squeeze的用法主要就是对数据的维度进行压缩或者解压. 先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的 ...

  8. python yield 和 yield from用法总结

    #例1. 简单输出斐波那契數列前 N 个数 #缺点:该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列 #要提高 fab 函数的可复用性,最好不要直接打印出数列,而 ...

  9. tf.nn.embedding_lookup()的用法

    函数: tf.nn.embedding_lookup( params, ids, partition_strategy='mod', name=None, validate_indices=True, ...

  10. OpenMP用法大全

    OpenMP基本概念 OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的 ...

最新文章

  1. html 怎么让tr的css覆盖td的_html表格标签
  2. 小程序自动化测试--测试3
  3. react学习(28)---react挂载图
  4. 现代软件工程 结对编程 (II) 电梯调度 算法和测试框架
  5. sqlserver中日期保存及取值
  6. java jtextfield 输入_【java】JTextField与JComboBox结合动态匹配输入信息
  7. numpy无法导入的问题--ModuleNotFoundError: No module named 'numpy'总结
  8. android中include标签使用详解
  9. 常用的 T-SQL 语言
  10. 一键解决局域网共享之批处理
  11. html360chromeURL无法编辑,关于近期360拦截本站以及部分网友无法用chrome打开本站问题...
  12. 推荐一款护眼的软件——f.lux。它可以随着时间,自己调节色温
  13. Linux服务器安装云锁
  14. Moniter和Lock
  15. 学了C语言,能开发什么项目?
  16. jmeter 进行弱网测试
  17. wince博客名人堂
  18. 职场中年危机,可能只是你放水太多又不接受现实而已
  19. jquery 中 $(document).ready() 与window.onload 的区别
  20. 【探花交友DAY 03】个人信息完善 阿里云OSS百度人脸识别引入 统一Token和异常处理

热门文章

  1. winrar破解注册
  2. 黑盒测试方法之错误推测法概述
  3. kdev-ruby 停止开发,原 maintainer 转用其它编辑器
  4. 合肥工业大学计算机信息学院,合肥工业大学计算机与信息学院在职研究生_合肥工业大学在职研究生_125在职研究生...
  5. android os parcel,java.lang.RuntimeException:Parcel android.os.Parcel:...
  6. 开课吧 dubbo+zookeeper
  7. android qq音乐 搜索,QQ音乐搜索功能基本思路
  8. Java SE 基础知识~流程控制
  9. 用GetGlyphOutline搞字模
  10. 迅捷pdf转换成word转换器 4.1 官方版