2011.08.12(4)——— android AudioTrack 不能播放awr
http://blog.sina.com.cn/s/blog_7cb539590100qkcr.html
http://blog.csdn.net/chenjie19891104/article/details/6333553
http://blog.csdn.net/hellogv/article/details/6026455
我用AudioTrack播放MP3 awr都是不成功的 只会传出一堆的噪声,但是播放wav是没有问题的,因为wav就相当于原生态的pcm
这时候 我有两个选择
1、从3gp网站上下载awr解码算法 用jni调用 把awr解码成pcm
2、可以用AudioRecord来录制pcm 并用AudioTrack来播放
我用的时后者
package com.lp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private TextView stateView;
private Button btnStart,btnStop,btnPlay,btnFinish;
private RecordTask recorder;
private PlayTask player;
private File audioFile;
private boolean isRecording=true, isPlaying=false;
private int frequence = 44100;
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main_pcm);
stateView = (TextView)this.findViewById(R.id.view_state);
stateView.setText("准备开始");
btnStart = (Button)this.findViewById(R.id.btn_start);
btnStop = (Button)this.findViewById(R.id.btn_stop);
btnPlay = (Button)this.findViewById(R.id.btn_play);
btnFinish = (Button)this.findViewById(R.id.btn_finish);
btnFinish.setText("停止播放");
btnPlay.setEnabled(false);
btnFinish.setEnabled(false);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
btnPlay.setOnClickListener(this);
btnFinish.setOnClickListener(this);
// File fpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/11");
// fpath.mkdirs();
try {
//audioFile = File.createTempFile("test", ".pcm", fpath);
audioFile = new File("/mnt/sdcard/1.pcm");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onClick(View v){
int id = v.getId();
switch(id){
case R.id.btn_start:
recorder = new RecordTask();
recorder.execute();
break;
case R.id.btn_stop:
this.isRecording = false;
System.out.println(isRecording);
break;
case R.id.btn_play:
player = new PlayTask();
player.execute();
break;
case R.id.btn_finish:
this.isPlaying = false;
break;
}
}
class RecordTask extends AsyncTask<Void, Integer, Void>{
@Override
protected Void doInBackground(Void... arg0) {
//isRecording = true;
try {
//开通输出流到指定的文件
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile)));
//FileOutputStream fos = new FileOutputStream(audioFile);
//根据定义好的几个配置,来获取合适的缓冲大小
int bufferSize = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
//实例化AudioRecord
AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, frequence, channelConfig, audioEncoding, bufferSize);
//定义缓冲
short[] buffer = new short[bufferSize];
//byte[] buffer = new byte[bufferSize];
//开始录制
record.startRecording();
int r = 0; //存储录制进度
//定义循环,根据isRecording的值来判断是否继续录制
while(isRecording){
//从bufferSize中读取字节,返回读取的short个数
//这里老是出现buffer overflow,不知道是什么原因,试了好几个值,都没用,TODO:待解决
int bufferReadResult = record.read(buffer, 0, buffer.length);
//循环将buffer中的音频数据写入到OutputStream中
for(int i=0; i<bufferReadResult; i++){
dos.writeShort(buffer[i]);
}
// byte[] tmpBuf = new byte[bufferReadResult];
// System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);
// fos.write(tmpBuf, 0, bufferReadResult);
// fos.flush();
publishProgress(new Integer(r)); //向UI线程报告当前进度
r++; //自增进度值
}
//录制结束
record.stop();
System.out.println("The File length::"+audioFile.length());
dos.close();
//fos.close();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
//当在上面方法中调用publishProgress时,该方法触发,该方法在UI线程中被执行
protected void onProgressUpdate(Integer...progress){
stateView.setText(progress[0].toString());
}
protected void onPostExecute(Void result){
btnStop.setEnabled(false);
btnStart.setEnabled(true);
btnPlay.setEnabled(true);
btnFinish.setEnabled(false);
}
protected void onPreExecute(){
//stateView.setText("正在录制");
btnStart.setEnabled(false);
btnPlay.setEnabled(false);
btnFinish.setEnabled(false);
btnStop.setEnabled(true);
}
}
class PlayTask extends AsyncTask<Void, Integer, Void>{
@Override
protected Void doInBackground(Void... arg0) {
isPlaying = true;
int bufferSize = AudioTrack.getMinBufferSize(frequence, channelConfig, audioEncoding);
short[] buffer = new short[bufferSize/4];
//byte[] buffer = new byte[bufferSize];
try {
//定义输入流,将音频写入到AudioTrack类中,实现播放
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(audioFile)));
//FileInputStream fis = new FileInputStream(audioFile);
//实例AudioTrack
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, frequence, channelConfig, audioEncoding, bufferSize, AudioTrack.MODE_STREAM);
//开始播放
track.play();
//由于AudioTrack播放的是流,所以,我们需要一边播放一边读取
while(isPlaying && dis.available()>0){
int i = 0;
while(dis.available()>0 && i<buffer.length){
buffer[i] = dis.readShort();
i++;
}
//然后将数据写入到AudioTrack中
track.write(buffer, 0, buffer.length);
}
//播放结束
track.stop();
dis.close();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
protected void onPostExecute(Void result){
btnPlay.setEnabled(true);
btnFinish.setEnabled(false);
btnStart.setEnabled(true);
btnStop.setEnabled(false);
}
protected void onPreExecute(){
//stateView.setText("正在播放");
btnStart.setEnabled(false);
btnStop.setEnabled(false);
btnPlay.setEnabled(false);
btnFinish.setEnabled(true);
}
}
}
对了 别忘了权限
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
注意:其实这种方法也是不可取的 因为保存的PCM原始音频 没有压缩 所以非常大,一般还是用awr来传输 所以还是需要解码的
分享到:
相关推荐
android使用AudioTrack低延迟播放音频文件.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
android基于AudioTrack播放PCM音频文件的源码实例,播放扩展名为rm格式的文件,不使用android 内置的Audio和video来播放PCM音频数据,通过通过解码得到PCM数据源,使用AudioTrack类实现音频文件的播放,本源码就是...
可以多个音频顺序播放,可以重复播放音频 博文地址:http://blog.csdn.net/w1027296673/article/details/50441709
本Demo使用MediaCodec解码AAC音频数据,解码之后直接使用AudioTrack播放PCM音频数据
android AudioRecord AudioTrack实现录音并播放 并支持参数选择(频率、编码格式、声道) 更多信息可参考http://blog.sina.com.cn/u/1788464665
Android实现使用AudioTrack实现正弦波音频播放,不固定频率可任意切换频率。20Hz~2KHz之间进行无缝切换。
android使用audioRecord和audioTrack实现语音录音播放与即时播放
实现用audiotrack播放pcm音频流
Android AudioTrack 分析,从理论及代码角度分析 android audioTrack framework 层。
目录一、动态路由的初始化1、获取路由...针对Android原生路由策略不做深入分析。 什么是音频路由?如何实现音频路由?如何定制音频路由?这是本文要解决的三大问题。 什么是音频路由?音频无非就是把音频数据流放到指
RT,一个使用audiotrack播放PCM音频数据的DEMO,上传的代码工程中有个音频数据文件夹,包含了用于测试的PCM数据文件,详情请看readme.txt;另外代码附详细说明,走过路过的都不要错过了,喜欢就顶下吧
读取wav文件,用static模式播放.注意需要添加权限,<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
主要为大家详细介绍了Android音频系统AudioTrack的使用方法,如何使用AudioTrack进行音频播放,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
//一个list里面存的是音频的渲染器//构造方法//添加音频渲染器,与去除音频渲染器//释放掉AudioTrack//方法含义同AudioTrackpriva
Android深入浅出之AudioTrack.
Android 使用 AudioRecord 和 AudioTrack 完成音频PCM数据的采集和播放,并读写音频wav文件。 封装好的Java代码,可同时录制PCM和WAV文件。自己定义存储位置。 Android提供了AudioRecord和MediaRecord。MediaRecord...
本文主要介绍Android上可以进行音频(PCM)播放的两个组件–AudioTrack/OpenSL ES的简单使用方法。 对一个音频文件(如MP3文件),如何使用FFmpeg进行解码获取到PCM,之前的文章已经有相应的说明: ...
Basic4Android最新最全类库,包含B4a上市后截止到2017.04.24的库文件。希望对大家有帮助。以下为文件列表。 2012/08/09 周四 01:55 35,901 ABExtDrawing.jar 2012/08/09 周四 01:55 191,079 ABExtDrawing.xml 2010/...
使用AudioTrack进行播放时,将音频数据保存下来,保存为pcm格式,可以用于分析音频文件是否有问题。