Android(安卓)Audio代码分析19 - setPosition函数
16lz
2022-06-13
之前我们看过get position,今天来看看set position。
*****************************************源码*************************************************
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java
#######################说明################################
###########################################################
&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
set position改变的其实是audio_track_cblk_t结构体中的server成员。
也就是AudioMixer中从audio_track_cblk_t中copy数据时的起始地址。
这儿设置position有个限制,就是不能跑到user前面去,
即不能让取数据的其实地址超出已写数据的范围。
在播放器中,大幅度拖动进度条,改变的应该是读取文件时的地址,
*****************************************源码*************************************************
//Test case 3: setPlaybackHeadPosition() on paused track @LargeTest public void testSetPlaybackHeadPositionPaused() throws Exception { // constants for test final String TEST_NAME = "testSetPlaybackHeadPositionPaused"; final int TEST_SR = 22050; final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO; final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT; final int TEST_MODE = AudioTrack.MODE_STREAM; final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC; //-------- initialization -------------- int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT); AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, 2*minBuffSize, TEST_MODE); byte data[] = new byte[minBuffSize]; //-------- test -------------- assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED); track.write(data, 0, data.length); track.write(data, 0, data.length); track.play(); track.pause(); assumeTrue(TEST_NAME, track.getPlayState() == AudioTrack.PLAYSTATE_PAUSED); assertTrue(TEST_NAME, track.setPlaybackHeadPosition(10) == AudioTrack.SUCCESS); //-------- tear down -------------- track.release(); }
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java
#######################说明################################
//Test case 3: setPlaybackHeadPosition() on paused track @LargeTest public void testSetPlaybackHeadPositionPaused() throws Exception { // constants for test final String TEST_NAME = "testSetPlaybackHeadPositionPaused"; final int TEST_SR = 22050; final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO; final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT; final int TEST_MODE = AudioTrack.MODE_STREAM; final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC; //-------- initialization -------------- int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT); AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, 2*minBuffSize, TEST_MODE); byte data[] = new byte[minBuffSize]; //-------- test -------------- assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED); track.write(data, 0, data.length); track.write(data, 0, data.length); track.play(); track.pause(); assumeTrue(TEST_NAME, track.getPlayState() == AudioTrack.PLAYSTATE_PAUSED); assertTrue(TEST_NAME, track.setPlaybackHeadPosition(10) == AudioTrack.SUCCESS);// +++++++++++++++++++++++++++++setPlaybackHeadPosition+++++++++++++++++++++++++++++++++++ /** * Sets the playback head position. The track must be stopped for the position to be changed. * @param positionInFrames playback head position expressed in frames * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, * {@link #ERROR_INVALID_OPERATION} */ public int setPlaybackHeadPosition(int positionInFrames) { synchronized(mPlayStateLock) { if ((mPlayState == PLAYSTATE_STOPPED) || (mPlayState == PLAYSTATE_PAUSED)) { return native_set_position(positionInFrames);// ++++++++++++++++++++++++++++android_media_AudioTrack_set_position++++++++++++++++++++++++++++++++++++static jint android_media_AudioTrack_set_position(JNIEnv *env, jobject thiz, jint position) { AudioTrack *lpTrack = (AudioTrack *)env->GetIntField( thiz, javaAudioTrackFields.nativeTrackInJavaObj); if (lpTrack) { return android_media_translateErrorCode( lpTrack->setPosition(position) );// ++++++++++++++++++++++++++++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;}// ----------------------------AudioTrack::setPosition------------------------------------ } else { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioTrack pointer for setPosition()"); return AUDIOTRACK_ERROR; }}// ----------------------------android_media_AudioTrack_set_position------------------------------------ } else { return ERROR_INVALID_OPERATION; } } }// -----------------------------setPlaybackHeadPosition----------------------------------- //-------- tear down -------------- track.release(); }
###########################################################
&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
set position改变的其实是audio_track_cblk_t结构体中的server成员。
也就是AudioMixer中从audio_track_cblk_t中copy数据时的起始地址。
这儿设置position有个限制,就是不能跑到user前面去,
即不能让取数据的其实地址超出已写数据的范围。
在播放器中,大幅度拖动进度条,改变的应该是读取文件时的地址,
而不是audio_track_cblk_t对象中的地址。
另外,只能在stop的状态下才能改变position。
更多相关文章
- android 做登陆与mysql数据库交互
- Android(安卓)ScrollView里嵌套ListView
- android:SQlite
- Android(安卓)Sqlite数据库查询操作使用 '%?%' 的问题
- Android(安卓)java List 转Json格式
- ANDROID与.Net之间JSON实践
- 百度地图中android获取经纬度和地方名称
- Android(安卓)联系人选择Widget
- mybatisplus的坑 insert标签insert into select无参数问题的解决