Android Audio代码分析19 - setPosition函数
16lz
2021-01-23
之前我们看过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 Sqlite数据库查询操作使用 '%?%' 的问题
- android 做登陆与mysql数据库交互
- Android黑名单来电自动静音源码
- Android中使用GridView实现标签效果源码
- android volley封装及源码解析
- Android GPS获得经纬度并得到该坐标精确地址
- Android中从服务器端向客户端传数据
- android 使用Java自带的HttpURLConnection 连接网络 读取返回数
- Android Fastboot源码分析