织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>嵌入式开发>Android>

AudioTrack学习

落鹤生 发布于 2012-04-01 10:13 点击:次 
MODE_STREAM模式下,在JAVA层构造AudioTrack时,bufferSizeInBytes的大小设定为9600,在Native层调用Write方法拷贝数据至Hardware进行回放,每次拷贝的大小为320.则需要拷贝到30次,声卡才发出声音。即需要将数据填满缓冲区才进行播放。(320*30=9600)
TAG:

AudioTrack主要是用来播放声音的,AudioTrack贯穿了JAVA层,JNI层和Native层。

AudioTrack JAVA层:

framework\base\media\java\android\media\AudioTrack.java

以AudioTrack的使用方法举例:

  1. // 得到一个满足最小要求的缓冲区的大小 
  2. int bufsize = AudioTrack.getMinBufferSize(8000,//采样率 = 每秒8K个点 
  3.  
  4.   AudioFormat.CHANNEL_CONFIGURATION_STEREO,//双声道 
  5.  
  6. AudioFormat.ENCODING_PCM_16BIT);//采样精度 = 一个采样点16比特 = 2个字节 
  7.  
  8. //创建AudioTrack 
  9. AudioTrack trackplayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000
  10.  
  11.   AudioFormat.CHANNEL_CONFIGURATION_ STEREO, 
  12.  
  13.   AudioFormat.ENCODING_PCM_16BIT, 
  14.  
  15.   bufsize, 
  16.  
  17. AudioTrack.MODE_STREAM);// 
  18.  
  19.  trackplayer.play() ;//开始 
  20.  
  21. trackplayer.write(bytes_pkg, 0, bytes_pkg.length) ;//往track中写数据 
  22.  
  23. //... 
  24.  
  25. trackplayer.stop();//停止播放 
  26.  
  27. trackplayer.release();//释放底层资源 

AudioTrack Native层:

  1. // 得到一个满足最小要求的缓冲区的大小 
  2. int bufsize = AudioTrack.getMinBufferSize(8000,//采样率 = 每秒8K个点 
  3.  
  4.   AudioFormat.CHANNEL_CONFIGURATION_STEREO,//双声道 
  5.  
  6. AudioFormat.ENCODING_PCM_16BIT);//采样精度 = 一个采样点16比特 = 2个字节 

getMinBufferSize实际调用了JNI通过Native代码来实现。

framework/base/core/jni/android_media_track.cpp

  1. static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env
  2. ,jobject thiz,jint sampleRateInHertz,jint nbChannels,jint audioFormat) 
  3. {//注意我们传入的参数是: 
  4. //sampleRateInHertz = 8000 
  5. //nbChannels = 2; 
  6. //audioFormat = AudioFormat.ENCODING_PCM_16BIT 
  7.     int afSamplingRate; 
  8.     int afFrameCount; 
  9.     uint32_t afLatency; 
  10.  
  11.     if (AudioSystem::getOutputSamplingRate(&afSamplingRate) != NO_ERROR) { 
  12.         return -1; 
  13.     } 
  14.     if (AudioSystem::getOutputFrameCount(&afFrameCount) != NO_ERROR) { 
  15.         return -1; 
  16.     } 
  17.     if (AudioSystem::getOutputLatency(&afLatency) != NO_ERROR) { 
  18.         return -1; 
  19.     } 
  20.  
  21.      //音频中最常见的是frame,解释:一个frame就是1个采样点的字节数*声道。 
  22.     // Ensure that buffer depth covers at least audio hardware latency 
  23.     uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSamplingRate); 
  24.     if (minBufCount < 2) minBufCount = 2; 
  25. uint32_t minFrameCount = 
  26.  (afFrameCount*sampleRateInHertz*minBufCount)/afSamplingRate; 
  27.  
  28. //下面根据最小的framecount计算最小的buffersize    
  29.     int minBuffSize = minFrameCount 
  30.             * (audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1) 
  31.             * nbChannels; 
  32.     return minBuffSize; 
  33.  
MODE_STREAM和MODE_STATIC
STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,然后write到audiotrack。这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。
In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using one of the write() methods. These are blocking and return when the data has been transferred from the Java layer to the native layer and queued for playback.
MODE_STREAM模式终使用Write方法,该方法是阻塞的,当数据从Java层到Native层执行播放完毕后才返回。
而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用
 
AudioTrack的构造函数
public AudioTrack (int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)
AudioTrack的构造函数
中有一个变量用来指定buffer的大小bufferSizeInBytes。 
AudioTrack在Native层会对这个变量的值进行有效性判断。首先,它至少要等于或者大于getMinBufferSize返回的值,然后它必须是frame大小的整数倍
 

举例说明,

MODE_STREAM模式

下,在JAVA层构造

AudioTrack

时,

bufferSizeInBytes

的大小设定为9600,在Native层调用

Write

方法拷贝数据至Hardware进行回放,每次拷贝的大小为320.则需要拷贝到30次,声卡才发出声音。即需要将数据填满缓冲区才进行播放。(320*30=9600)

(stefzeus)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201204/15897.html]
本文出处:CSDN博客 作者:stefzeus 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容