- 浏览: 1504258 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (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 1490http://www.cnblogs.com/xiaowen ... -
Windows的adb shell中使用vi不乱码方法及AdbPutty
2013-12-27 10:17 7575http://www.veryhuo.com/down/ht ... -
AppMobi推出新XDK,可创建测试PhoneGap项目
2012-09-03 13:39 2637AppMobi今天发布了一个新的工具PhoneGap Mobi ... -
Sencha
2012-09-03 12:59 1185http://www.sencha.com/ Se ... -
jQuery Mobile学习
2012-09-01 12:33 1691使用Jquery Mobile设计Android通讯录 ... -
BackBone
2012-09-01 12:34 1260Backbone.js 是一种重量级javascript M ... -
jQTouch
2012-08-30 15:57 984A Zepto/jQuery plugin for mobil ... -
SwiFTP
2012-08-30 15:43 1307SwiFTP is a FTP server that run ... -
kWS
2012-08-30 15:41 1198kWS is a lightweight and fast W ... -
jQuery Mobile
2012-08-30 15:07 1027http://jquerymobile.com/ -
PhoneGap
2012-08-30 15:07 1044http://phonegap.com/ -
Android Button background image pressed/highlighted and disabled states without
2012-08-06 12:49 1678http://shikii.net/blog/android- ... -
[AndriodTips]Image, saved to sdcard, doesn't appear in Android's Gallery app
2012-08-04 16:15 1158http://stackoverflow.com/questi ... -
Voice detection for Android
2012-07-23 11:39 2347Here it is, my fist JAVA applic ... -
[AndroidTip]local reference table overflow (max=512)的错误解决
2012-07-22 22:56 6049JNI层coding经常会遇到ReferenceTable o ... -
[AndroidTip]EditText如何初始状态不获得焦点?
2012-07-22 15:35 1226最简单的办法是在EditText前面放置一个看不到的Linea ... -
[AndroidTip]android textview滚动条
2012-07-21 14:29 1297本来是想做一个显示文字信息的,当文字很多时View的高度不能超 ... -
Google公布Android 4.1完整功能
2012-07-16 09:48 3185http://www.android.com/about/je ... -
Android上的行车记录仪
2012-07-11 22:31 2010MyCar Recorder DailyRoads -
Google hired one of Nuance soft engineers to help work around all Nuance patents
2012-07-10 14:33 1100很有趣的消息: http://forums.macrumor ...
相关推荐
android基于AudioTrack播放PCM音频文件的源码实例,播放扩展名为rm格式的文件,不使用android 内置的Audio和video来播放PCM音频数据,通过通过解码得到PCM数据源,使用AudioTrack类实现音频文件的播放,本源码就是...
`AudioTrack`类是Android提供的一种高级音频播放接口,它允许开发者直接控制音频缓冲区,从而实现更低的延迟播放。下面将详细探讨如何使用`AudioTrack`来实现这一目标。 首先,`AudioTrack`的创建需要几个关键参数...
在降噪过程中,通常会使用AudioRecord来捕获原始音频数据,然后通过自定义的降噪算法对数据进行处理,最后使用AudioTrack将处理后的音频数据播放出来。 2. **WebRTC的音频引擎** WebRTC的音频引擎(Audio Engine)...
5. **源码实现**:这个压缩包中的源码示例很可能展示了如何使用Android SDK中的`AudioRecord`和`AudioTrack`类进行录音和播放操作,并且可能包含了处理PCM、BIN、ADPCM和WAV格式转换的函数或类。例如,它可能包含...
AudioDemoAndroid 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件:Android 音视频开发(三):使用 AudioTrack 播放PCM音频:使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放,并实现...
在Android上,播放PCM或BIN音频文件通常需要使用`AudioTrack`类。对于PCM数据,开发者需要确保采样率、位深度和通道数与录音时保持一致。而对于BIN文件,由于可能缺少元数据,可能需要额外的处理步骤来确定正确的...
- 解码音频:使用libavcodec对音频流进行解码,生成原始的PCM数据。 - 数据转换:根据OpenSL ES的要求,可能需要将解码后的PCM数据转换为特定的格式和采样率。 - 填充缓冲区:将转换后的PCM数据填充到OpenSL ES的...
8. **播放音频**:通过`AudioTrack.write()`写入数据,然后调用`AudioTrack.play()`开始播放。 9. **停止播放**:调用`AudioTrack.stop()`停止播放,释放资源。 在实际开发中,还需要关注权限问题。确保在...
本文旨在通过对AudioTrack的剖析,揭示其工作原理以及如何在Android系统中实现音频播放功能。我们将采用深度优先的方式,从API层面入手,逐步下沉至JNI及服务层,遇到陌生或初次接触的类或方法均会进行详尽解释。 #...
2. **音频播放**:对于PCM数据的播放,Android提供了`AudioTrack`类。你需要创建一个`AudioTrack`实例,传入相应的PCM数据、采样率、位深度和声道数等信息,然后调用`play()`方法开始播放。注意,PCM数据通常是裸...
AudioTrack用于将PCM数据推送到音频硬件进行播放,而AudioRecord则用于从麦克风捕获音频数据。 八、性能优化 为了优化媒体播放性能,开发者可以考虑使用硬件解码、异步准备、预缓存策略等技术。同时,注意处理好...
编码过程涉及将原始PCM音频数据转换为AMR格式,这通常通过Android的MediaCodec API实现。 2. **音频录制**:Android提供了AudioRecord类,用于从麦克风捕获音频流。开发者需要设置适当的采样率、通道数和位深度,...
在Android开发中,音频文件通常使用不同的编码格式进行压缩,如PCM(脉冲编码调制)、AAC(高级音频编码)、MP3等。这些编码方式能够有效减少音频数据的大小,同时保持可接受的声音质量。 2. Android MediaCodec ...
同时,音高和音量的控制也是关键,可能涉及到对PCM音频数据的处理。 此外,音效的实时合成也是一个挑战。开发者可能会使用OpenSL ES,这是一个高性能的音频API,能够处理复杂的音频处理任务,如音频合成、滤波等。...
本资源"安卓Android源码——语音压缩,android开发语音功能较多使用的时候,压缩大小50%"提供了一套针对语音数据进行压缩的解决方案,其主要目标是减少音频文件的大小,以便更高效地存储和传输。 首先,让我们了解...
LAME(Low-Average-Mean Error)是一个高效的MP3编码器,它能够将原始的音频数据(如PCM)转换为高质量的MP3音频文件。LAME库提供了一套API,使得开发者可以在不同平台上,包括Android,方便地集成MP3编码功能。 2...
1. **AudioTrack**: 这是Android SDK提供的一个类,用于播放音频数据。开发者可以创建AudioTrack实例,传入音频缓冲区,然后调用play()方法来播放声音。源码中可能涉及到设置音频格式(如采样率、位深度、通道数)、...
3. **AudioTrack使用**:与AudioRecord相对,AudioTrack负责将音频数据播放出来。同样需要设置音频格式参数,如采样率、通道配置和音频格式(如PCM)。调用write()方法将音频数据写入播放队列,然后调用play()方法...
同样需要初始化解码器状态,然后将编码数据输入解码器,得到解码后的PCM数据,最后通过`AudioTrack`类播放音频。 5. **VoIP通信** 在实现VoIP(Voice over IP)通话时,编解码后的音频数据通常会通过网络发送到另...
5. **MediaRecorder配置**:使用MediaRecorder时,开发者需要设置音频源、输出格式、编码器、采样率、声道数等参数。例如,如果选择AAC编码,可以设定`setAudioEncoder(MediaRecorder.AudioEncoder.AAC)`。 6. **...