diff --git a/framework/render/audio/Android/AudioTrackRender.cpp b/framework/render/audio/Android/AudioTrackRender.cpp index 3f08005e3..50f6e629b 100644 --- a/framework/render/audio/Android/AudioTrackRender.cpp +++ b/framework/render/audio/Android/AudioTrackRender.cpp @@ -188,7 +188,8 @@ int AudioTrackRender::start_device() return -1; } -void AudioTrackRender::flush_device() + +void AudioTrackRender::flush_device_inner() { JniEnv jniEnv; JNIEnv *handle = jniEnv.getEnv(); @@ -211,15 +212,26 @@ void AudioTrackRender::flush_device() } mSendSimples = 0; - start_device(); /* work around some device position didn't set to zero, and MUST get after start_device */ - mAudioFlushPosition = getPlayedSimples(); + start_device(); + if (mFlushPositionReset == FlushRestPosition::unknow) { + mFlushPositionReset = (getDevicePlayedSimples() == 0) ? FlushRestPosition::reset + : FlushRestPosition::notReset; + } if (state == PLAYSTATE_PAUSED) { pause_device(); } } + +void AudioTrackRender::flush_device() +{ + flush_device_inner(); + mBasePlayedPosition = 0; + mAudioFlushPosition = getPlayedPosition(); +} + void AudioTrackRender::device_setVolume(float gain) { if (audio_track && method_setVolume) { @@ -231,12 +243,32 @@ void AudioTrackRender::device_setVolume(float gain) int64_t AudioTrackRender::device_get_position() { - uint64_t playedSimples = getPlayedSimples(); + uint64_t playedSimples = getPlayedPosition(); return static_cast((playedSimples - mAudioFlushPosition ) / (float(mOutputInfo.sample_rate) / 1000000)); } -uint64_t AudioTrackRender::getPlayedSimples() +uint64_t AudioTrackRender::getPlayedPosition() { + uint64_t playedSimples = getDevicePlayedSimples(); + uint64_t playedPosition = playedSimples + mBasePlayedPosition; + + if(mFlushPositionReset == FlushRestPosition ::notReset ){ + return playedPosition; + } + + if (playedSimples >= 0x7F000000) { + mBasePlayedPosition += playedSimples + device_get_que_duration(); + flush_device_inner(); + } + + return playedPosition; +} + +uint64_t AudioTrackRender::getDevicePlayedSimples() { + if(mFlushPositionReset == FlushRestPosition ::notReset) { + return static_cast(mSendSimples); + } + uint64_t simples = 0; JniEnv jniEnv; JNIEnv *handle = jniEnv.getEnv(); @@ -296,10 +328,10 @@ int AudioTrackRender::device_write(unique_ptr &frame) uint64_t AudioTrackRender::device_get_que_duration() { - if (mSendSimples < getPlayedSimples()) { + if (mSendSimples < getDevicePlayedSimples()) { return 0; } - return static_cast((mSendSimples - getPlayedSimples()) / + return static_cast((mSendSimples - getDevicePlayedSimples()) / (float(mOutputInfo.sample_rate) / 1000000)); } diff --git a/framework/render/audio/Android/AudioTrackRender.h b/framework/render/audio/Android/AudioTrackRender.h index 629a1258e..b35958376 100644 --- a/framework/render/audio/Android/AudioTrackRender.h +++ b/framework/render/audio/Android/AudioTrackRender.h @@ -60,7 +60,11 @@ class AudioTrackRender : int init_jni(); - uint64_t getPlayedSimples(); + uint64_t getDevicePlayedSimples(); + + void flush_device_inner() ; + + uint64_t getPlayedPosition(); private: @@ -77,7 +81,7 @@ class AudioTrackRender : private: - int64_t mPlayedPosition = 0; + uint64_t mBasePlayedPosition = 0; uint8_t *mPcmBuffer = nullptr; int64_t mPcmBufferLen = 0; @@ -87,6 +91,13 @@ class AudioTrackRender : std::atomic mSendSimples{0}; int mSimpleSize{0}; jobject jbuffer{nullptr}; + + enum class FlushRestPosition{ + unknow , reset, notReset + }; + + FlushRestPosition mFlushPositionReset = FlushRestPosition::unknow; + };