AudioRecord 与 MediaRecorder 区别
AudioRecord 基于字节流录制,输出的是pcm数据,未进行压缩,直接保存的pcm文件不能被播放器识别播放。
可以对音频文件进行实时处理,直播类中对录制的声音进行变声编辑。
MediaRecorder 是基于AudioRecord之上,进行了封装,使用简单,由于本身对录制的音频进行压缩,编码,无法对音频进行实时处理编辑。适用于普通的音频录制。
配合MediaPlayer 进行播放。
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes)
AudioRecord 构造函数
AudioSource  音频源, 常用MediaRecorder.AudioSource.MIC(麦克风音频源)
SampleRateInHz  采样率,(采样率用赫兹表示。44100Hz是目前唯一的*保证适用于所有设备的费率)
ChannelConfig  音频声道
AudioFormat  返回音频数据格式
BufferSizeInBytes 缓冲区大小
录制流程:
  • 构造AudioRecord 对象
  • startRecording() 开始采集
  • 在线程中将采集数据写入pcm文件
  • stop() 停止采集

    public void record(){
    mAudioRecord.startRecording();
    new Thread(new Runnable() {
    @Override
    public void run() {
    FileOutputStream fileOutputStream=new FileOutputStream(recordFile);
    byte[] buffer=new byte[mBufferSizeInBytes];
    while(isRecording){
    int read=mAudioRecord.read(buffer,0,mBufferSizeInBytes);
    if(AudioRecord.ERROR_INVALID_OPERATION!=read){
    fileOutputStream.write(buffer);
    }
    }
    fileOutputStream.close();
    }
    }).start(); }
    public void stopRecord(){
    isRecording=false;
    if(mAudioRecord.getState()==AudioRecord.RECORDSTATE_RECORDING){
    mAudioRecord.stop();
    }
    mAudioRecord.release();
    }
    使用AudioTrack播放
    • 构造AudioTrack
    • play() 
    • 在线程中write() 写入pcm文件流
    • release()回收资源
    与MediaPlayer的区别
    MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。MediaPlayer会在framework层创建对应的音频解码器。而AudioTrack只能播放已经解码的PCM流,如果对比支持的文件格式的话则是AudioTrack只支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,只能播放不需要解码的wav文件
    构造函数
    public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
    int mode, int sessionId)
    mAudioTrack.play();
    new Thread(new Runnable(){
    @Override
    public void run() { try {
    FileInputStream fileInputStream=new FileInputStream(filePath);
    byte[] tempBuffer=new byte[mWriteMinBufferSize];
    while (fileInputStream.available()>0){
    int readCount= fileInputStream.read(tempBuffer);
    if (readCount== AudioTrack.ERROR_INVALID_OPERATION||readCount==AudioTrack.ERROR_BAD_VALUE){
    continue;
    }
    if (readCount!=0&&readCount!=-1){
    mAudioTrack.write(tempBuffer,0,readCount);
    }
    }
    Log.e("TAG","end");
    } catch (Exception e) {
    e.printStackTrace();
    } }
    }).start();

    实例:使用AudioRecord 采集PCM,AudioTrack 播放

    package com.rexkell.mediaapplication;
    
    import android.media.AudioAttributes;
    import android.media.AudioFormat;
    import android.media.AudioManager;
    import android.media.AudioRecord;
    import android.media.AudioTrack;
    import android.media.MediaRecorder;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button; import com.rexkell.mediaapplication.media.MediaConfig; import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.concurrent.Executors; /**
    * author: rexkell
    * date: 2019/7/22
    * explain:
    */
    public class AudioRecordActivity extends AppCompatActivity {
    boolean isRecording=false;
    //音频源 MIC指的是麦克风
    private final int mAudioSource= MediaRecorder.AudioSource.MIC;
    //(MediaRecoder 的采样率通常是8000Hz AAC的通常是44100Hz。 设置采样率为44100,目前为常用的采样率,官方文档表示这个值可以兼容所有的设置)
    private final int SampleRateInHz=44100; //采样率
    //输入声道
    private final int channelInMono= AudioFormat.CHANNEL_CONFIGURATION_MONO;
    private final int channelOutMono=AudioFormat.CHANNEL_OUT_MONO;
    //指定音频量化位数 ,在AudioFormaat类中指定了以下各种可能的常量。通常我们选择ENCODING_PCM_16BIT和ENCODING_PCM_8BIT PCM代表的是脉冲编码调制,它实际上是原始音频样本。
    //因此可以设置每个样本的分辨率为16位或者8位,16位将占用更多的空间和处理能力,表示的音频也更加接近真实
    private final int mAudioFormat=AudioFormat.ENCODING_PCM_16BIT;
    //指定缓冲区大小
    private int mBufferSizeInBytes;
    private String filePath; private int mWriteMinBufferSize;
    private AudioAttributes mAudioAttributes;
    AudioRecord mAudioRecord;
    AudioTrack mAudioTrack;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ac_audio_record);
    filePath=getExternalFilesDir("Music").getPath()+"/test.pcm";
    initAudioRecord();
    }
    private void initAudioRecord(){
    mBufferSizeInBytes=AudioRecord.getMinBufferSize(SampleRateInHz,channelInMono,mAudioFormat);
    mWriteMinBufferSize=AudioTrack.getMinBufferSize(SampleRateInHz,channelInMono,mAudioFormat);
    mAudioRecord=new AudioRecord(mAudioSource,SampleRateInHz,channelInMono,mAudioFormat,mBufferSizeInBytes); AudioFormat audioFormat=new AudioFormat.Builder().setSampleRate(SampleRateInHz).setEncoding(mAudioFormat).setChannelMask(channelOutMono).build();
    mAudioAttributes=new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();
    mAudioTrack=new AudioTrack(mAudioAttributes,audioFormat,mWriteMinBufferSize, AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE);
    File recordFile=new File(filePath);
    if (!recordFile.exists()){
    try {
    recordFile.createNewFile();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } }
    public void record(View view){
    isRecording=!isRecording;
    String text=isRecording?"结束":"录制";
    ((Button)view).setText(text);
    if (isRecording){
    final File recordFile=new File(filePath);
    if (recordFile.exists()){
    recordFile.delete();
    try {
    recordFile.createNewFile();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    mAudioRecord.startRecording();
    Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override
    public void run() {
    try {
    FileOutputStream fileOutputStream=new FileOutputStream(recordFile);
    byte[] buffer=new byte[mBufferSizeInBytes];
    while (isRecording){
    int read=mAudioRecord.read(buffer,0,mBufferSizeInBytes);
    if (AudioRecord.ERROR_INVALID_OPERATION!=read){
    fileOutputStream.write(buffer);
    }
    }
    fileOutputStream.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    });
    }else {
    if (mAudioRecord!=null&&isRecording){
    if (mAudioRecord.getState()==AudioRecord.RECORDSTATE_RECORDING){
    mAudioRecord.stop();
    }
    mAudioRecord.release();
    isRecording=false;
    } } }
    public void play(View view){
    mAudioTrack.play();
    Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override
    public void run() {
    try {
    FileInputStream fileInputStream=new FileInputStream(filePath);
    byte[] tempBuffer=new byte[mWriteMinBufferSize];
    while (fileInputStream.available()>0){
    int readCount= fileInputStream.read(tempBuffer);
    if (readCount== AudioTrack.ERROR_INVALID_OPERATION||readCount==AudioTrack.ERROR_BAD_VALUE){
    continue;
    }
    if (readCount!=0&&readCount!=-1){
    mAudioTrack.write(tempBuffer,0,readCount);
    }
    }
    Log.e("TAG","end");
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    });
    } @Override
    protected void onDestroy() {
    if (mAudioRecord!=null){
    mAudioRecord.release();
    mAudioRecord=null;
    }
    if (mAudioTrack!=null){
    mAudioTrack.release();
    mAudioTrack=null;
    }
    super.onDestroy();
    }
    }

AudioRecord 录制播放PCM音频的更多相关文章

  1. 使用AudioTrack播放PCM音频数据(android)

    众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...

  2. 使用WindowsAPI实现播放PCM音频的方法

    这篇文章主要介绍了使用WindowsAPI实现播放PCM音频的方法,很实用的一个功能,需要的朋友可以参考下 本文介绍了使用WindowsAPI实现播放PCM音频的方法,同前面一篇使用WindowsAP ...

  3. linux下mono播放PCM音频

         测试环境: Ubuntu 14 MonoDevelop CodeBlocks 1.建立一个共享库(shared library) 这里用到了linux下的音频播放库,alsa-lib. al ...

  4. Android 音视频开发(三):使用 AudioTrack 播放PCM音频

    一.AudioTrack 基本使用 AudioTrack 类可以完成Android平台上音频数据的输出任务.AudioTrack有两种数据加载模式(MODE_STREAM和MODE_STATIC),对 ...

  5. 使用WindowsAPI播放PCM音频

    这一篇文章同上一篇<使用WindowsAPI获取录音音频>原理具有相似之处,不再详细介绍函数与结构体的参数 1. waveOutGetNumDevs 2. waveOutGetDevCap ...

  6. 11.3、Libgdx的音频之播放PCM音频

    (官网:www.libgdx.cn) audio模块可以提供对音频硬件的直接访问. 音频硬件是通过AudioDevice接口进行的抽象. 以下创建一个新的AudioDevice实例: AudioDev ...

  7. DirectSound播放PCM(可播放实时采集的音频数据)

    前言 该篇整理的原始来源为http://blog.csdn.net/leixiaohua1020/article/details/40540147.非常感谢该博主的无私奉献,写了不少关于不同多媒体库的 ...

  8. 最简单的视音频播放示例9:SDL2播放PCM

    本文记录SDL播放音频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API ...

  9. 最简单的视音频播放示例8:DirectSound播放PCM

    本文记录DirectSound播放音频的技术.DirectSound是Windows下最常见的音频播放技术.目前大部分的音频播放应用都是通过DirectSound来播放的.本文记录一个使用Direct ...

随机推荐

  1. Android 日期对话框 DatePickerDialog

    private int year; private int monthOfYear; private int dayOfMonth; @Override protected void onCreate ...

  2. 软件开发工具(第13章: Eclipse插件的使用与开发)

    一.插件简介 插件的定义(了解) 插件是一种遵循其所依附的软件的接口规范所编写出来的程序. 插件实际上是对原有软件的扩展,替应用程序增加一些所需要的特定 功能. 插件的构成(重点.记忆) 每个插件都由 ...

  3. [20191206]隐含参数_db_always_check_system_ts.txt

    [20191206]隐含参数_db_always_check_system_ts.txt --//今年年头我做tab$删除恢复时,遇到的问题,就是遇到延迟块清除的问题.参考链接:http://blog ...

  4. less 学习笔记

    一.介绍 Less (Leaner Style Sheets 简洁的样式表) 是一门向后兼容的 CSS 预处理语言,它扩展了CSS 语言. less is more. 好处: 1.具有部分编程语言的功 ...

  5. C#/.Net开发入门篇(3)——console类的输入输出

    相信看了我上一篇文章的小伙伴们都知道console这个类的最基本的2个方法了吧,下去练习过的小伙伴应该能知道4个方法. 那么下面我们就来介绍一下上期没有介绍完的另外2个方法Console.WriteL ...

  6. springboot + springcloud +nacos实战

    首先从整个软件的功能和应用场景来说,nacos更像consul,而非eureka,nacos设计的时候自带的配置中心功能,让我们省下了去搞springcloud config的时间,但这里并不是说na ...

  7. 搭建Nginx四层反向代理

    需求背景: 前段时间公司因为业务需求需要部署一个正向代理,我已经分享出来了https://www.cnblogs.com/Dfengshuo/p/11911406.html,现有因架构个更改,需要再加 ...

  8. LRC歌词原理和实现高仿Android网易云音乐

    大家好,我们是爱学啊,今天给大家带来一篇关于LRC歌词原理和在Android上如何实现歌词逐行滚动的效果,本文来自[Android开发项目实战我的云音乐]课程:逐字滚动下一篇文章讲解. 效果图 相信大 ...

  9. 团队项目之Scrum6

    小组:BLACK PANDA 时间:2019.11.26 每天举行站立式会议 提供当天站立式会议照片一张 2 昨天已完成的工作 2 编辑功能优化 实现主页内容展示 今天计划完成的工作 2 内容展示 根 ...

  10. Vim 命令常用功能详解

    Vim编辑器 文本编辑器 , 字处理器ASCIIvi:Visual Interface vim :VI iMproved 全屏编辑器,模式化编辑器vim 模式:编辑模式(命令模式)输入模式末行模式 模 ...