- 浏览: 1482932 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (419)
- XMPP (19)
- Android (180)
- Java (59)
- Network (4)
- HTML5 (13)
- Eclipse (9)
- SCM (23)
- C/C++ (4)
- UML (4)
- Libjingle (15)
- Tools&Softwares (29)
- Linphone (5)
- Linux&UNIX (6)
- Windows (18)
- Google (10)
- MISC (3)
- SIP (6)
- SQLite (5)
- Security (4)
- Opensource (29)
- Online (2)
- 文章 (3)
- MemoryLeak (10)
- Decompile (5)
- Ruby (1)
- Image (1)
- Bat (4)
- TTS&ASR (28)
- Multimedia (1)
- iOS (20)
- Asciiflow - ASCII Flow Diagram Tool.htm (1)
- Networking (1)
- DLNA&UPnP (2)
- Chrome (2)
- CI (1)
- SmartHome (0)
- CloudComputing (1)
- NodeJS (3)
- MachineLearning (2)
最新评论
-
bzhao:
点赞123!
Windows的adb shell中使用vi不乱码方法及AdbPutty -
wahahachuang8:
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方 ...
HTML5 WebSocket 技术介绍 -
obehavior:
view.setOnTouchListenerview是什么
[转]android 一直在最前面的浮动窗口效果 -
wutenghua:
[转]android 一直在最前面的浮动窗口效果 -
zee3.lin:
Sorry~~
When I build "call ...
Step by Step about How to Build libjingle 0.4
http://www.linuxidc.com/Linux/2012-06/63186.htm
众所周知,Android 的 MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用 MediaPlayer实现的。MediaPlayer在底层是基于OpenCore(PacketVideo)的库实现的,为了构建一个 MediaPlayer程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础是Android基本库中的Binder机制。但是该类只能对完整的音 频文件进行操作,而不能直接对纯PCM音频数据操作。假如我们通过解码得到PCM数据源,又当如何将它们播放?没错,就是用AudioTrack这个类 (MediaPlayer内部也是调用该类进行真正的播放音频流操作)下面这个DEMO演示了如何使用AudioTrack来播放PCM音频数据。
废话不多说,先上效果图:
工程代码结构也较为简单:
简单说下思路,先把PCM音频数据从指定的路径文件读到内存,然后给AudioPlayer设置数据源,音频参数等,最后执行播放,暂停,停止等操作
贴上部分类代码片段:
- public class AudioParam {
- int mFrequency; // 采样率
- int mChannel; // 声道
- int mSampBit; // 采样精度
- }
- public interface PlayState {
- public static final int MPS_UNINIT = 0 ; // 未就绪
- public static final int MPS_PREPARE = 1 ; // 准备就绪(停止)
- public static final int MPS_PLAYING = 2 ; // 播放中
- public static final int MPS_PAUSE = 3 ; // 暂停
-
}
AudioPlayer代码片段如下:
- public class AudioPlayer implements IPlayComplete{
- private final static String TAG = "AudioPlayer" ;
- public final static int STATE_MSG_ID = 0x0010 ;
- private Handler mHandler;
- private AudioParam mAudioParam; // 音频参数
- private byte [] mData; // 音频数据
- private AudioTrack mAudioTrack; // AudioTrack对象
- private boolean mBReady = false ; // 播放源是否就绪
- private PlayAudioThread mPlayAudioThread; // 播放线程
- public AudioPlayer(Handler handler)
- {
- mHandler = handler;
- }
- public AudioPlayer(Handler handler,AudioParam audioParam)
- {
- mHandler = handler;
- setAudioParam(audioParam);
- }
- /*
- * 设置音频参数
- */
- public void setAudioParam(AudioParam audioParam)
- {
- mAudioParam = audioParam;
- }
- /*
- * 设置音频源
- */
- public void setDataSource( byte [] data)
- {
- mData = data;
- }
- /*
- * 就绪播放源
- */
- public boolean prepare()
- {
- if (mData == null || mAudioParam == null )
- {
- return false ;
- }
- if (mBReady == true )
- {
- return true ;
- }
- try {
- createAudioTrack();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return false ;
- }
- mBReady = true ;
- setPlayState(PlayState.MPS_PREPARE);
- return true ;
-
}
- private boolean mThreadExitFlag = false ; // 线程退出标志
- private int mPrimePlaySize = 0 ; // 较优播放块大小
- private int mPlayOffset = 0 ; // 当前播放位置
- private int mPlayState = 0 ; // 当前播放状态
- /*
- * 播放音频的线程
- */
- class PlayAudioThread extends Thread
- {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- Log.d(TAG, "PlayAudioThread run mPlayOffset = " + mPlayOffset);
- mAudioTrack.play();
- while ( true )
- {
- if (mThreadExitFlag == true )
- {
- break ;
- }
- try {
- int size = mAudioTrack.write(mData, mPlayOffset, mPrimePlaySize);
- mPlayOffset += mPrimePlaySize;
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- AudioPlayer. this .onPlayComplete();
- break ;
- }
- if (mPlayOffset >= mData.length)
- {
- AudioPlayer. this .onPlayComplete();
- break ;
- }
- }
- mAudioTrack.stop();
- Log.d(TAG, "PlayAudioThread complete..." );
- }
-
}
下面来剖析以下如何使用AudioTrack来播放PCM音频数据
首先要构建一个AudioTrack对象:(需要采样率,声道,采样精度参数)
- private void createAudioTrack() throws Exception
- {
- // 获得构建对象的最小缓冲区大小
- int minBufSize = AudioTrack.getMinBufferSize(mAudioParam.mFrequency,
- mAudioParam.mChannel,
- mAudioParam.mSampBit);
- mPrimePlaySize = minBufSize * 2 ;
- Log.d(TAG, "mPrimePlaySize = " + mPrimePlaySize);
- // STREAM_ALARM:警告声
- // STREAM_MUSCI:音乐声,例如music等
- // STREAM_RING:铃声
- // STREAM_SYSTEM:系统声音
- // STREAM_VOCIE_CALL:电话声音
- mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
- mAudioParam.mFrequency,
- mAudioParam.mChannel,
- mAudioParam.mSampBit,
- minBufSize,
- AudioTrack.MODE_STREAM);
- // AudioTrack中有MODE_STATIC和MODE_STREAM两种分类。
- // STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。
- // 这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,然后write到audiotrack。
- // 这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。
- // 而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,
- // 后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。
- // 这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用。
- }
然后开一个子线程从缓存区里分块取数据然后写入硬件设备进行播放
- private void startThread()
- {
- if (mPlayAudioThread == null )
- {
- mThreadExitFlag = false ;
- mPlayAudioThread = new PlayAudioThread();
- mPlayAudioThread.start();
- }
-
}
AudioTrack里有三个重要方法:
void play()
int write(byte[] audioData, int offsetInBytes, int sizeInBytes) (该方法是阻塞的)
void stop()
从前面那个线程代码可以看出,我们在写数据之前需要先执行 play(),然后才能进行write操作,当数据播放完毕或是线程被外部终止的时候最后调用stop()停止写数据;若执行了play操作但后面却没有 执行write操作的话,或是write操作结束后没有调用stop,观察logcat会不断打印提示信息,这是提示我们对以上三个方法的调用要规范
只要大家设置的音频参数和音频数据都是正确的,就能顺畅的播放出声音,本例已经附带了用于测试的音频文件以及参数说明(已测试通过),具体看工程里 音频数据这个文件夹下的readme.txt即可.网上有些童鞋反应说audiotrack播放音频不顺畅,如果数据源没问题的话估计是他们的demo里 没有连续地执行write操作而导致的,其它的不多说了,觉得有用的童鞋自己写代码看吧。。。喜欢就顶一下吧!
发表评论
-
[Android] 为Android安装BusyBox —— 完整的bash shell
2013-12-27 10:19 1413http://www.cnblogs.com/xiaowen ... -
Windows的adb shell中使用vi不乱码方法及AdbPutty
2013-12-27 10:17 7398http://www.veryhuo.com/down/ht ... -
AppMobi推出新XDK,可创建测试PhoneGap项目
2012-09-03 13:39 2533AppMobi今天发布了一个新的工具PhoneGap Mobi ... -
Sencha
2012-09-03 12:59 1140http://www.sencha.com/ Se ... -
jQuery Mobile学习
2012-09-01 12:33 1629使用Jquery Mobile设计Android通讯录 ... -
BackBone
2012-09-01 12:34 1222Backbone.js 是一种重量级javascript M ... -
jQTouch
2012-08-30 15:57 939A Zepto/jQuery plugin for mobil ... -
SwiFTP
2012-08-30 15:43 1244SwiFTP is a FTP server that run ... -
kWS
2012-08-30 15:41 1147kWS is a lightweight and fast W ... -
jQuery Mobile
2012-08-30 15:07 978http://jquerymobile.com/ -
PhoneGap
2012-08-30 15:07 996http://phonegap.com/ -
Android Button background image pressed/highlighted and disabled states without
2012-08-06 12:49 1627http://shikii.net/blog/android- ... -
[AndriodTips]Image, saved to sdcard, doesn't appear in Android's Gallery app
2012-08-04 16:15 1114http://stackoverflow.com/questi ... -
Voice detection for Android
2012-07-23 11:39 2298Here it is, my fist JAVA applic ... -
[AndroidTip]local reference table overflow (max=512)的错误解决
2012-07-22 22:56 5952JNI层coding经常会遇到ReferenceTable o ... -
[AndroidTip]EditText如何初始状态不获得焦点?
2012-07-22 15:35 1185最简单的办法是在EditText前面放置一个看不到的Linea ... -
[AndroidTip]android textview滚动条
2012-07-21 14:29 1259本来是想做一个显示文字信息的,当文字很多时View的高度不能超 ... -
Google公布Android 4.1完整功能
2012-07-16 09:48 3138http://www.android.com/about/je ... -
Android上的行车记录仪
2012-07-11 22:31 1966MyCar Recorder DailyRoads -
Google hired one of Nuance soft engineers to help work around all Nuance patents
2012-07-10 14:33 1051很有趣的消息: http://forums.macrumor ...
相关推荐
android基于AudioTrack播放PCM音频文件的源码实例,播放扩展名为rm格式的文件,不使用android 内置的Audio和video来播放PCM音频数据,通过通过解码得到PCM数据源,使用AudioTrack类实现音频文件的播放,本源码就是...
RT,一个使用audiotrack播放PCM音频数据的DEMO,上传的代码工程中有个音频数据文件夹,包含了用于测试的PCM数据文件,详情请看readme.txt;另外代码附详细说明,走过路过的都不要错过了,喜欢就顶下吧
本Demo使用MediaCodec解码AAC音频数据,解码之后直接使用AudioTrack播放PCM音频数据
一个使用audiotrack播放PCM音频数据的DEMO,上传的代码工程中有个音频数据文件夹,包含了用于测试的PCM数据文件,详情请看readme.txt;另外代码附详细说明,走过路过的都不要错过了,喜欢就顶下吧
Android 使用 AudioRecord 和 AudioTrack 完成音频PCM数据的采集和播放,并读写音频wav文件。 封装好的Java代码,可同时录制PCM和WAV文件。自己定义存储位置。 Android提供了AudioRecord和MediaRecord。MediaRecord...
播放PCM音频数据的双缓冲用法
实现用audiotrack播放pcm音频流
终于迎来了蓝牙a2dp的第二篇:利用AudioTrack播放PCM音频数据。如想查看更多内容,请点击《Android蓝牙开发系列文章-策划篇》。 先回顾一下上一篇文章《Android蓝牙开发系列文章-蓝牙音箱连接》讲到的蓝牙音箱的完成...
PCMAudioPlayerDemothis project Using AudioTrack play PCM audio files##chinese这里要感谢原文的作者,大部分的播放功能以及实现都是出于原作者的代码,我只是经过改编而已,该Demo用Android Studio编写。...
这份代码是打开PCM裸流文件并截取一段数据然后播放的,可以轻松的经过加一条线程的方式改成网络传输的形式。
本文主要介绍Android上可以进行音频(PCM)播放的两个组件–AudioTrack/OpenSL ES的简单使用方法。 对一个音频文件(如MP3文件),如何使用FFmpeg进行解码获取到PCM,之前的文章已经有相应的说明: ...
通过AudioTrack实现播放PCM文件,设置采样率,将文件读取到byte字节中
AudioTrack播放pcm文件,波形显示, 用于测试的demo, 比较简单。
android使用AudioTrack低延迟播放音频文件.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
可以多个音频顺序播放,可以重复播放音频 博文地址:http://blog.csdn.net/w1027296673/article/details/50441709
Android实现使用AudioTrack实现正弦波音频播放,不固定频率可任意切换频率。20Hz~2KHz之间进行无缝切换。
主要为大家详细介绍了Android音频系统AudioTrack的使用方法,如何使用AudioTrack进行音频播放,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
读入文件,pcm dat等格式,转换为数组由Androidtrack播放
AudioDemoAndroid 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件:Android 音视频开发(三):使用 AudioTrack 播放PCM音频:使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放,并实现...
audiotrack 播放音频