Android Audio代码分析16 - testPlaybackHeadPositionAfterPause函数

play, stop, flush这几个函数,今天来看看pause函数。


*****************************************源码*************************************************
//Test case 4: getPlaybackHeadPosition() is > 0 after play(); pause(); @LargeTest public void testPlaybackHeadPositionAfterPause() throws Exception { // constants for test final String TEST_NAME = "testPlaybackHeadPositionAfterPause"; 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 -------------- int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT); AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, minBuffSize, TEST_MODE); byte data[] = new byte[minBuffSize/2]; //-------- test -------------- assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED); track.write(data, 0, data.length); track.write(data, 0, data.length); track.play(); Thread.sleep(100); track.pause(); int pos = track.getPlaybackHeadPosition(); log(TEST_NAME, "position ="+ pos); assertTrue(TEST_NAME, pos > 0); //-------- tear down -------------- track.release(); }
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java


#######################说明################################
//Test case 4: getPlaybackHeadPosition() is > 0 after play(); pause(); @LargeTest public void testPlaybackHeadPositionAfterPause() throws Exception { // constants for test final String TEST_NAME = "testPlaybackHeadPositionAfterPause"; 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 -------------- int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT); AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, minBuffSize, TEST_MODE); byte data[] = new byte[minBuffSize/2]; //-------- test -------------- assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED); track.write(data, 0, data.length); track.write(data, 0, data.length); track.play(); Thread.sleep(100); track.pause(); // ++++++++++++++++++++++++++++++pause++++++++++++++++++++++++++++++++++ /** * Pauses the playback of the audio data. * @throws IllegalStateException */ public void pause() throws IllegalStateException { if (mState != STATE_INITIALIZED) { throw(new IllegalStateException("pause() called on uninitialized AudioTrack.")); } //logd("pause()"); // pause playback synchronized(mPlayStateLock) { native_pause(); // +++++++++++++++++++++++++++++++android_media_AudioTrack_pause+++++++++++++++++++++++++++++++++ static void android_media_AudioTrack_pause(JNIEnv *env, jobject thiz) { AudioTrack *lpTrack = (AudioTrack *)env->GetIntField( thiz, javaAudioTrackFields.nativeTrackInJavaObj); if (lpTrack == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioTrack pointer for pause()"); return; } lpTrack->pause(); // ++++++++++++++++++++++++++++++AudioTrack::pause++++++++++++++++++++++++++++++++++ void AudioTrack::pause() { LOGV("pause"); if (android_atomic_and(~1, &mActive) == 1) { // mAudioTrack在函数AudioTrack::createTrack中被赋值,其最终指向的其实是一个TrackHandle对象 mAudioTrack->pause(); // ++++++++++++++++++++++++++++AudioFlinger::TrackHandle::pause++++++++++++++++++++++++++++++++++++ void AudioFlinger::TrackHandle::pause() { mTrack->pause(); // ++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::Track::pause++++++++++++++++++++++++++++++++++++ void AudioFlinger::PlaybackThread::Track::pause() { LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid()); sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); if (mState == ACTIVE || mState == RESUMING) { mState = PAUSING; LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get()); if (!isOutputTrack()) { // ++++++++++++++++++++++++++++isOutputTrack++++++++++++++++++++++++++++++++++++ bool isOutputTrack() const { return (mStreamType == AudioSystem::NUM_STREAM_TYPES); } // ----------------------------isOutputTrack------------------------------------ thread->mLock.unlock(); // 在看stop代码的时候已经看过函数AudioSystem::stopOutput AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType, mSessionId); thread->mLock.lock(); } } } } // ----------------------------AudioFlinger::PlaybackThread::Track::pause------------------------------------ } // ----------------------------AudioFlinger::TrackHandle::pause------------------------------------ } } // ------------------------------AudioTrack::pause---------------------------------- } // -------------------------------android_media_AudioTrack_pause--------------------------------- mPlayState = PLAYSTATE_PAUSED; } } // ------------------------------pause---------------------------------- int pos = track.getPlaybackHeadPosition(); log(TEST_NAME, "position ="+ pos); assertTrue(TEST_NAME, pos > 0); //-------- tear down -------------- track.release(); // ++++++++++++++++++++++++++++++release++++++++++++++++++++++++++++++++++ /** * Releases the native AudioTrack resources. */ public void release() { // even though native_release() stops the native AudioTrack, we need to stop // AudioTrack subclasses too. try { stop(); } catch(IllegalStateException ise) { // don't raise an exception, we're releasing the resources. } native_release(); // +++++++++++++++++++++++++++++android_media_AudioTrack_native_release+++++++++++++++++++++++++++++++++++ static void android_media_AudioTrack_native_release(JNIEnv *env, jobject thiz) { // do everything a call to finalize would android_media_AudioTrack_native_finalize(env, thiz); +++++++++++++++++++++++++++++android_media_AudioTrack_native_finalize+++++++++++++++++++++++++++++++++++ // static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz) { //LOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz); // delete the AudioTrack object AudioTrack *lpTrack = (AudioTrack *)env->GetIntField( thiz, javaAudioTrackFields.nativeTrackInJavaObj); if (lpTrack) { //LOGV("deleting lpTrack: %x\n", (int)lpTrack); lpTrack->stop(); delete lpTrack; } // delete the JNI data AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetIntField( thiz, javaAudioTrackFields.jniData); if (pJniStorage) { // delete global refs created in native_setup env->DeleteGlobalRef(pJniStorage->mCallbackData.audioTrack_class); env->DeleteGlobalRef(pJniStorage->mCallbackData.audioTrack_ref); //LOGV("deleting pJniStorage: %x\n", (int)pJniStorage); delete pJniStorage; } } // -----------------------------android_media_AudioTrack_native_finalize----------------------------------- // + reset the native resources in the Java object so any attempt to access // them after a call to release fails. env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, 0); env->SetIntField(thiz, javaAudioTrackFields.jniData, 0); } // -----------------------------android_media_AudioTrack_native_release----------------------------------- mState = STATE_UNINITIALIZED; } // ------------------------------release---------------------------------- }
###########################################################


&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
pause与stop类似,都会调用函数AudioSystem::stopOutput。
差别是,stop会reset,也就是将audio_track_cblk_t中的user, server等清0。
而pause不会。


这也就是在播放的时候,按暂停,播放进度条会停在当前位置不动,按停止的话,进度条则回到了初始状态。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值