AudioRecord 录制播放PCM音频
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
int 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音频的更多相关文章
- 使用AudioTrack播放PCM音频数据(android)
众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...
- 使用WindowsAPI实现播放PCM音频的方法
这篇文章主要介绍了使用WindowsAPI实现播放PCM音频的方法,很实用的一个功能,需要的朋友可以参考下 本文介绍了使用WindowsAPI实现播放PCM音频的方法,同前面一篇使用WindowsAP ...
- linux下mono播放PCM音频
测试环境: Ubuntu 14 MonoDevelop CodeBlocks 1.建立一个共享库(shared library) 这里用到了linux下的音频播放库,alsa-lib. al ...
- Android 音视频开发(三):使用 AudioTrack 播放PCM音频
一.AudioTrack 基本使用 AudioTrack 类可以完成Android平台上音频数据的输出任务.AudioTrack有两种数据加载模式(MODE_STREAM和MODE_STATIC),对 ...
- 使用WindowsAPI播放PCM音频
这一篇文章同上一篇<使用WindowsAPI获取录音音频>原理具有相似之处,不再详细介绍函数与结构体的参数 1. waveOutGetNumDevs 2. waveOutGetDevCap ...
- 11.3、Libgdx的音频之播放PCM音频
(官网:www.libgdx.cn) audio模块可以提供对音频硬件的直接访问. 音频硬件是通过AudioDevice接口进行的抽象. 以下创建一个新的AudioDevice实例: AudioDev ...
- DirectSound播放PCM(可播放实时采集的音频数据)
前言 该篇整理的原始来源为http://blog.csdn.net/leixiaohua1020/article/details/40540147.非常感谢该博主的无私奉献,写了不少关于不同多媒体库的 ...
- 最简单的视音频播放示例9:SDL2播放PCM
本文记录SDL播放音频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API ...
- 最简单的视音频播放示例8:DirectSound播放PCM
本文记录DirectSound播放音频的技术.DirectSound是Windows下最常见的音频播放技术.目前大部分的音频播放应用都是通过DirectSound来播放的.本文记录一个使用Direct ...
随机推荐
- 平时常用sql
总结一下平时用到最多的sql语句 1.特殊日期 --今天凌晨 ,) --明天凌晨 ,,) --当周周一(每周从周日开始) ,) --当月的第一天 ,) --当月的最后一天 ,,,)) --今年的第一天 ...
- leetcode菜鸡斗智斗勇系列(4)--- 单一数字的乘积和总合的减法
1.原题: https://leetcode.com/problems/subtract-the-product-and-sum-of-digits-of-an-integer/ Given an i ...
- 2019icpc银川站 复现赛
打了计蒜客上的银川重现赛,总体感觉难度上确实比平时区域赛要低上一些. 这里补一下F题和G题的思路和代码. upd:I题也补了,理解差不多都在注释里. F题 做法,玩一下n=10的样例就出 ...
- Python活力练习Day4
Day4:将列表的值按相反顺序依次输出 eg : input : list = [1,2,3,4,5] output : [5,4,3,2,1] 方法一:时间复杂度O(n),其中 n ...
- Jmeter脚本参数化和正则匹配
我们在做接口测试过程中,往往会遇到以下几种情况 每次发送请求,都需要更改参数值为未使用的参数值,比如手机号注册.动态时间等 上一个接口的请求体参数用于下一个接口的请求体参数 上一个接口的响应体参数用于 ...
- vivo web service:亿万级规模web服务引擎架构
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/ovOS0l9U5svlUMfZoYFU9Q vivo web service是开发团队围绕奇点 ...
- 2019 Vue开发指南:你都需要学点啥?
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://dzone.com/articles/vue-development-in-2019 ...
- css实现图片动画效果
需求 项目里有个消息中心,当有消息的时候,小铃铛图标可以晃两下,提示当前有信息. 实现过程 书写css 使用css的keyframe属性,配合animation. @keyframes ringing ...
- django nginx 504 time-out 错误
报错: 分析 nginx和uwsgi整合时有三个参数可以用于设置超时时间: 1.uwsgi_connect_timeout: 默认60秒,与uwsgi-server连接的超时时间,该值不能超过75秒. ...
- NETGEAR R7800路由器TFTP刷回原厂固件方法
前几天因图新鲜将用了一年的R7800刷为dd-wrt固件,结果发现信号覆盖和网络速率相对于原厂固件还有一些差距. 然后从dd-wrt固件刷回原厂,具体操作过程如下: 1.到NETGEAR官网[支持]模 ...