Android Audio代码分析2 - 函数getMinBufferSize
AudioTrack的使用示例中,用到了函数getMinBufferSize,今天把它倒出来,再嚼嚼。
*****************************************源码*************************************************
***********************************************************************************************
源码路径:
frameworks\base\media\java\android\media\AudioTrack.java
###########################################说明##############################################################
先把自带的注释拿来看看吧:
从注释可以看出,通过该函数获取的最小buffer size,只是保证在MODE_STREAM模式下成功地创建一个AudioTrack对象。
并不能保证流畅地播放。
1、参数就不说了,可以参考上面注释,上一篇文章中也有说。
2、定义了一个内部变量:
int channelCount = 0;
用来记录声道数量。
调用native函数native_get_min_buff_size时会用。
可见buffer size也是由native层来决定的。
3、接下来根据Channel类型,计算声道数量:
MONO都是1,Stereo的都是2。
不过,我们之前看过,Channel类型不止这几种。有以下一堆呢:
并且,AudioFormat.CHANNEL_CONFIGURATION_MONO和AudioFormat.CHANNEL_CONFIGURATION_STEREO的定义还不包含在这一堆之中,而是在它们之前定义:
难道其他的Channel类型都不需要获取这个min buffer size???
还是说,目前只支持单声道和双声道???
4、下面判断音频格式,即采样点数据所占的bit数:
可见,只支持16bit和8bit两种。
5、判断采用率:
只支持4000Hz到48000Hz之间。
6、接下来调到native中去:
可见,真正干活的是在native中,java层中只是做些辅助操作。
通过前文中JNI的函数对照表,可知native_get_min_buff_size函数对应的是native中的android_media_AudioTrack_get_min_buff_size函数。
路径:frameworks\base\core\jni\android_media_AudioTrack.cpp
函数android_media_AudioTrack_get_min_buff_size的实现:
可见,最小buffer size是frameCoun乘以声道个数,在根据音频格式乘以1或2得到。
声道个数和音频格式都是传入的,不再说。
frameCount是调用函数AudioTrack::getMinFrameCount取得的。从函数名可知,此处取得的应该是最小frame数。
传入的三个参数:
&frameCount是用来保存frame计数的。
sampleRateInHertz是采样率。
AudioSystem::DEFAULT是写死的。其定义在类AudioSystem中,其他的定义如下:
原来是stream的类型。
为什么不在调用getMinBufferSize的时候传入stream类型,而在此处使用DEFAULT呢???
先放放,继续看函数AudioTrack::getMinFrameCount。
函数AudioTrack::getMinFrameCount的实现:
开始,调用了三个AudioSystem的函数,似曾谋面,不过当时被无视了,今天看看吧。
函数AudioSystem::getOutputSamplingRate的实现:
判断流的类型,如果是DEFAULT,将其设置为MUSIC!
纳炉嚎啕!!!
DEFAULT的流类型原来是这么用的。
接下来根据stream type获取output。
然后获取output的描述。
若获取成功,则output描述中的采样率就是要获取的采样率。
否则,尝试从AudioFlinger中获取采样率。
函数AudioSystem::getOutputFrameCount,AudioSystem::getOutputLatency,与函数AudioSystem::getOutputSamplingRate的处理类似。
至此,采样率,frameCount和延迟都取得了。
接下来计算minBufCount:
从注释可知,buff大小应至少能覆盖audio 硬件的延迟。
公式不太明白。
先看看从链接:http://blog.csdn.net/innost/article/details/6125779
中摘过来的frame的说明:
一个frame就是1个采样点的字节数*声道。为啥搞个frame出来?因为对于多声道的话,用1个采样点的字节数表示不全,
因为播放的时候肯定是多个声道的数据都要播出来才行。所以为了方便,就说1秒钟有多少个frame,这样就能抛开声道数,把意思表示全了。
还不是很明白。先放放。
猜了半天也猜不出来。哪位大侠指点指点。
下面计算frameCount:
我们的sampleRate肯定不为0,所以最后的计算应该为:afFrameCount * minBufCount * sampleRate / afSampleRate
*****************************************源码*************************************************
***********************************************************************************************
源码路径:
frameworks\base\media\java\android\media\AudioTrack.java
###########################################说明##############################################################
先把自带的注释拿来看看吧:
从注释可以看出,通过该函数获取的最小buffer size,只是保证在MODE_STREAM模式下成功地创建一个AudioTrack对象。
并不能保证流畅地播放。
1、参数就不说了,可以参考上面注释,上一篇文章中也有说。
2、定义了一个内部变量:
int channelCount = 0;
用来记录声道数量。
调用native函数native_get_min_buff_size时会用。
可见buffer size也是由native层来决定的。
3、接下来根据Channel类型,计算声道数量:
MONO都是1,Stereo的都是2。
不过,我们之前看过,Channel类型不止这几种。有以下一堆呢:
并且,AudioFormat.CHANNEL_CONFIGURATION_MONO和AudioFormat.CHANNEL_CONFIGURATION_STEREO的定义还不包含在这一堆之中,而是在它们之前定义:
难道其他的Channel类型都不需要获取这个min buffer size???
还是说,目前只支持单声道和双声道???
4、下面判断音频格式,即采样点数据所占的bit数:
可见,只支持16bit和8bit两种。
5、判断采用率:
只支持4000Hz到48000Hz之间。
6、接下来调到native中去:
可见,真正干活的是在native中,java层中只是做些辅助操作。
通过前文中JNI的函数对照表,可知native_get_min_buff_size函数对应的是native中的android_media_AudioTrack_get_min_buff_size函数。
路径:frameworks\base\core\jni\android_media_AudioTrack.cpp
函数android_media_AudioTrack_get_min_buff_size的实现:
可见,最小buffer size是frameCoun乘以声道个数,在根据音频格式乘以1或2得到。
声道个数和音频格式都是传入的,不再说。
frameCount是调用函数AudioTrack::getMinFrameCount取得的。从函数名可知,此处取得的应该是最小frame数。
传入的三个参数:
&frameCount是用来保存frame计数的。
sampleRateInHertz是采样率。
AudioSystem::DEFAULT是写死的。其定义在类AudioSystem中,其他的定义如下:
原来是stream的类型。
为什么不在调用getMinBufferSize的时候传入stream类型,而在此处使用DEFAULT呢???
先放放,继续看函数AudioTrack::getMinFrameCount。
函数AudioTrack::getMinFrameCount的实现:
开始,调用了三个AudioSystem的函数,似曾谋面,不过当时被无视了,今天看看吧。
函数AudioSystem::getOutputSamplingRate的实现:
判断流的类型,如果是DEFAULT,将其设置为MUSIC!
纳炉嚎啕!!!
DEFAULT的流类型原来是这么用的。
接下来根据stream type获取output。
然后获取output的描述。
若获取成功,则output描述中的采样率就是要获取的采样率。
否则,尝试从AudioFlinger中获取采样率。
函数AudioSystem::getOutputFrameCount,AudioSystem::getOutputLatency,与函数AudioSystem::getOutputSamplingRate的处理类似。
至此,采样率,frameCount和延迟都取得了。
接下来计算minBufCount:
从注释可知,buff大小应至少能覆盖audio 硬件的延迟。
公式不太明白。
先看看从链接:http://blog.csdn.net/innost/article/details/6125779
中摘过来的frame的说明:
一个frame就是1个采样点的字节数*声道。为啥搞个frame出来?因为对于多声道的话,用1个采样点的字节数表示不全,
因为播放的时候肯定是多个声道的数据都要播出来才行。所以为了方便,就说1秒钟有多少个frame,这样就能抛开声道数,把意思表示全了。
还不是很明白。先放放。
猜了半天也猜不出来。哪位大侠指点指点。
下面计算frameCount:
我们的sampleRate肯定不为0,所以最后的计算应该为:afFrameCount * minBufCount * sampleRate / afSampleRate