2121#include < stdlib.h>
2222#include < string.h>
2323#include < new>
24+ #include < time.h>
2425#include < audio_effects/effect_visualizer.h>
2526
2627
@@ -47,9 +48,9 @@ enum visualizer_state_e {
4748 VISUALIZER_STATE_ACTIVE,
4849};
4950
50- // maximum number of reads from same buffer before resetting capture buffer. This means
51+ // maximum time since last capture buffer update before resetting capture buffer. This means
5152// that the framework has stopped playing audio and we must start returning silence
52- #define MAX_STALL_COUNT 10
53+ #define MAX_STALL_TIME_MS 1000
5354
5455struct VisualizerContext {
5556 const struct effect_interface_s *mItfe ;
@@ -59,7 +60,7 @@ struct VisualizerContext {
5960 uint8_t mState ;
6061 uint8_t mCurrentBuf ;
6162 uint8_t mLastBuf ;
62- uint8_t mStallCount ;
63+ struct timespec mBufferUpdateTime ;
6364 uint8_t mCaptureBuf [2 ][VISUALIZER_CAPTURE_SIZE_MAX];
6465};
6566
@@ -72,7 +73,7 @@ void Visualizer_reset(VisualizerContext *pContext)
7273 pContext->mCaptureIdx = 0 ;
7374 pContext->mCurrentBuf = 0 ;
7475 pContext->mLastBuf = 1 ;
75- pContext->mStallCount = 0 ;
76+ pContext->mBufferUpdateTime . tv_sec = 0 ;
7677 memset (pContext->mCaptureBuf [0 ], 0x80 , VISUALIZER_CAPTURE_SIZE_MAX);
7778 memset (pContext->mCaptureBuf [1 ], 0x80 , VISUALIZER_CAPTURE_SIZE_MAX);
7879}
@@ -321,6 +322,11 @@ int Visualizer_process(
321322 if (pContext->mCaptureIdx == pContext->mCaptureSize ) {
322323 pContext->mCurrentBuf ^= 1 ;
323324 pContext->mCaptureIdx = 0 ;
325+
326+ // update last buffer update time stamp
327+ if (clock_gettime (CLOCK_MONOTONIC, &pContext->mBufferUpdateTime ) < 0 ) {
328+ pContext->mBufferUpdateTime .tv_sec = 0 ;
329+ }
324330 }
325331
326332 if (inBuffer->raw != outBuffer->raw ) {
@@ -453,16 +459,25 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
453459 pContext->mCaptureSize );
454460 // if audio framework has stopped playing audio although the effect is still
455461 // active we must clear the capture buffer to return silence
456- if (pContext->mLastBuf == pContext->mCurrentBuf ) {
457- if (pContext->mStallCount < MAX_STALL_COUNT) {
458- if (++pContext->mStallCount == MAX_STALL_COUNT) {
462+ if ((pContext->mLastBuf == pContext->mCurrentBuf ) &&
463+ (pContext->mBufferUpdateTime .tv_sec != 0 )) {
464+ struct timespec ts;
465+ if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0 ) {
466+ time_t secs = ts.tv_sec - pContext->mBufferUpdateTime .tv_sec ;
467+ long nsec = ts.tv_nsec - pContext->mBufferUpdateTime .tv_nsec ;
468+ if (nsec < 0 ) {
469+ --secs;
470+ nsec += 1000000000 ;
471+ }
472+ uint32_t deltaMs = secs * 1000 + nsec / 1000000 ;
473+ if (deltaMs > MAX_STALL_TIME_MS) {
474+ ALOGV (" capture going to idle" );
475+ pContext->mBufferUpdateTime .tv_sec = 0 ;
459476 memset (pContext->mCaptureBuf [pContext->mCurrentBuf ^ 1 ],
460477 0x80 ,
461478 pContext->mCaptureSize );
462479 }
463480 }
464- } else {
465- pContext->mStallCount = 0 ;
466481 }
467482 pContext->mLastBuf = pContext->mCurrentBuf ;
468483 } else {
0 commit comments