当前位置:操作系统 > 安卓/Android >>

Android Audio代码分析13 - AudioTrack::getPosition函数

打算以测试代码中所使用的接口为点,以接口间调用关系为线,逐步撕开Android中Audio的面纱。


*****************************************源码*************************************************
    public void testPlaybackHeadPositionAfterInit() throws Exception {
        // constants for test
        final String TEST_NAME = "testPlaybackHeadPositionAfterInit";
        final int TEST_SR = 22050;
        final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
        final int TEST_MODE = AudioTrack.MODE_STREAM;
        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
       
        //-------- initialization --------------
        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
                AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT), TEST_MODE);
        //--------    test        --------------
        assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
        assertTrue(TEST_NAME, track.getPlaybackHeadPosition() == 0);
        //-------- tear down      --------------
        track.release();
    }
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java


#######################说明################################
    //Test case 1: getPlaybackHeadPosition() at 0 after initialization
    public void testPlaybackHeadPositionAfterInit() throws Exception {
        // constants for test
        final String TEST_NAME = "testPlaybackHeadPositionAfterInit";
        final int TEST_SR = 22050;
        final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
        final int TEST_MODE = AudioTrack.MODE_STREAM;
        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
       
        //-------- initialization --------------
        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
                AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT), TEST_MODE);
        //--------    test        --------------
        assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
// 今天要看的,就是下面的getPlaybackHeadPosition函数
// 由于在getPlaybackHeadPosition之前,并没有调用play函数,也就是没有开始播放,所以获取的position应该为0
        assertTrue(TEST_NAME, track.getPlaybackHeadPosition() == 0);
+++++++++++++++++++++++++++++++getPlaybackHeadPosition+++++++++++++++++++++++++++++++++
    /**
     * Returns the playback head position expressed in frames
     */
    public int getPlaybackHeadPosition() {
// 很直接
// 调用的是函数android_media_AudioTrack_get_position
        return native_get_position();
++++++++++++++++++++++++++++++android_media_AudioTrack_get_position++++++++++++++++++++++++++++++++++
路径:frameworks\base\core\jni\android_media_AudioTrack.cpp


static jint android_media_AudioTrack_get_position(JNIEnv *env,  jobject thiz) {
   
    AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
                thiz, javaAudioTrackFields.nativeTrackInJavaObj);
    uint32_t position = 0;
               
    if (lpTrack) {
        lpTrack->getPosition(&position);
        return (jint)position;
++++++++++++++++++++++++++++++++AudioTrack::getPosition++++++++++++++++++++++++++++++++
status_t AudioTrack::getPosition(uint32_t *position)
{
    if (position == 0) return BAD_VALUE;


    *position = mCblk->server;


    return NO_ERROR;
}


server是mCblk的成员变量,mCblk是audio_track_cblk_t对象。
server在函数audio_track_cblk_t::stepServer中有被赋值。
另外,mCblk->server有在函数AudioTrack::setPosition中被赋值。
+++++++++++++++++++++++++++++++++AudioTrack::setPosition+++++++++++++++++++++++++++++++
status_t AudioTrack::setPosition(uint32_t position)
{
    Mutex::Autolock _l(mCblk->lock);


    if (!stopped()) return INVALID_OPERATION;


    if (position > mCblk->user) return BAD_VALUE;


    mCblk->server = position;
    mCblk->flags |= CBLK_FORCEREADY_ON;


    return NO_ERROR;
}


android_media_AudioTrack.cpp文件中的以下两个函数调用了AudioTrack::setPosition:
android_media_AudioTrack_set_pos_update_period函数
android_media_AudioTrack_set_position函数
这些接口上给java层用的。
想象一下使用场景,拖动当前光标?
---------------------------------AudioTrack::setPosition-------------------------------
+++++++++++++++++++++++++++++++++audio_track_cblk_t::stepServer+++++++++++++++++++++++++++++++
bool audio_track_cblk_t::stepServer(uint32_t frameCount)
{
    // the code below simulates lock-with-timeout
    // we MUST do this to protect the AudioFlinger server
    // as this lock is shared with the client.
    status_t err;


    err = lock.tryLock();
    if (err == -EBUSY) { // just wait a bit
        usleep(1000);
        err = lock.tryLock();
    }
    if (err != NO_ERROR) {
        // probably, the client just died.
        return false;
补充:移动开发 , Android ,

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,