diff options
-rw-r--r-- | include/media/AudioEffect.h | 21 | ||||
-rw-r--r-- | include/media/Visualizer.h | 11 | ||||
-rw-r--r-- | media/libeffects/visualizer/EffectVisualizer.cpp | 91 | ||||
-rw-r--r-- | media/libmedia/Visualizer.cpp | 45 |
4 files changed, 123 insertions, 45 deletions
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 02dfc1b..05d834d 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -402,6 +402,15 @@ protected: int32_t mId; // system wide unique effect engine instance ID Mutex mLock; // Mutex for mEnabled access + // IEffectClient + virtual void controlStatusChanged(bool controlGranted); + virtual void enableStatusChanged(bool enabled); + virtual void commandExecuted(uint32_t cmdCode, + uint32_t cmdSize, + void *pCmdData, + uint32_t replySize, + void *pReplyData); + private: // Implements the IEffectClient interface @@ -433,20 +442,8 @@ private: AudioEffect *mEffect; }; - - friend class EffectClient; - - // IEffectClient - void controlStatusChanged(bool controlGranted); - void enableStatusChanged(bool enabled); - void commandExecuted(uint32_t cmdCode, - uint32_t cmdSize, - void *pCmdData, - uint32_t replySize, - void *pReplyData); void binderDied(); - sp<IEffect> mIEffect; // IEffect binder interface sp<EffectClient> mIEffectClient; // IEffectClient implementation sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h index 60fa15b..fdec5ee 100644 --- a/include/media/Visualizer.h +++ b/include/media/Visualizer.h @@ -108,6 +108,12 @@ public: // returns the sampling rate of the audio being captured uint32_t getSamplingRate() { return mSampleRate; } + // set the way volume affects the captured data + // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED, + // VISUALIZER_SCALING_MODE_AS_PLAYED + status_t setScalingMode(uint32_t mode); + uint32_t getScalingMode() { return mScalingMode; } + // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to // getCaptureSize() status_t getWaveForm(uint8_t *waveform); @@ -117,6 +123,10 @@ public: // are returned status_t getFft(uint8_t *fft); +protected: + // from IEffectClient + virtual void controlStatusChanged(bool controlGranted); + private: static const uint32_t CAPTURE_RATE_MAX = 20000; @@ -147,6 +157,7 @@ private: uint32_t mCaptureRate; uint32_t mCaptureSize; uint32_t mSampleRate; + uint32_t mScalingMode; capture_cbk_t mCaptureCallBack; void *mCaptureCbkUser; sp<CaptureThread> mCaptureThread; diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index bdb1a1c..44d05cd 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define LOG_TAG "Visualizer" +#define LOG_TAG "EffectVisualizer" //#define LOG_NDEBUG 0 #include <cutils/log.h> #include <assert.h> @@ -57,6 +57,7 @@ struct VisualizerContext { effect_config_t mConfig; uint32_t mCaptureIdx; uint32_t mCaptureSize; + uint32_t mScalingMode; uint8_t mState; uint8_t mCurrentBuf; uint8_t mLastBuf; @@ -164,6 +165,7 @@ int Visualizer_init(VisualizerContext *pContext) pContext->mConfig.outputCfg.mask = EFFECT_CONFIG_ALL; pContext->mCaptureSize = VISUALIZER_CAPTURE_SIZE_MAX; + pContext->mScalingMode = VISUALIZER_SCALING_MODE_NORMALIZED; Visualizer_setConfig(pContext, &pContext->mConfig); @@ -285,26 +287,32 @@ int Visualizer_process( } // all code below assumes stereo 16 bit PCM output and input - - // derive capture scaling factor from peak value in current buffer - // this gives more interesting captures for display. - int32_t shift = 32; - int len = inBuffer->frameCount * 2; - for (int i = 0; i < len; i++) { - int32_t smp = inBuffer->s16[i]; - if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range - int32_t clz = __builtin_clz(smp); - if (shift > clz) shift = clz; - } - // A maximum amplitude signal will have 17 leading zeros, which we want to - // translate to a shift of 8 (for converting 16 bit to 8 bit) - shift = 25 - shift; - // Never scale by less than 8 to avoid returning unaltered PCM signal. - if (shift < 3) { - shift = 3; + int32_t shift; + + if (pContext->mScalingMode == VISUALIZER_SCALING_MODE_NORMALIZED) { + // derive capture scaling factor from peak value in current buffer + // this gives more interesting captures for display. + shift = 32; + int len = inBuffer->frameCount * 2; + for (int i = 0; i < len; i++) { + int32_t smp = inBuffer->s16[i]; + if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range + int32_t clz = __builtin_clz(smp); + if (shift > clz) shift = clz; + } + // A maximum amplitude signal will have 17 leading zeros, which we want to + // translate to a shift of 8 (for converting 16 bit to 8 bit) + shift = 25 - shift; + // Never scale by less than 8 to avoid returning unaltered PCM signal. + if (shift < 3) { + shift = 3; + } + // add one to combine the division by 2 needed after summing left and right channels below + shift++; + } else { + assert(pContext->mScalingMode == VISUALIZER_SCALING_MODE_AS_PLAYED); + shift = 9; } - // add one to combine the division by 2 needed after summing left and right channels below - shift++; uint32_t captIdx; uint32_t inIdx; @@ -414,15 +422,26 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, effect_param_t *p = (effect_param_t *)pReplyData; p->status = 0; *replySize = sizeof(effect_param_t) + sizeof(uint32_t); - if (p->psize != sizeof(uint32_t) || - *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) { + if (p->psize != sizeof(uint32_t)) { p->status = -EINVAL; break; } - ALOGV("get mCaptureSize = %d", pContext->mCaptureSize); - *((uint32_t *)p->data + 1) = pContext->mCaptureSize; - p->vsize = sizeof(uint32_t); - *replySize += sizeof(uint32_t); + switch (*(uint32_t *)p->data) { + case VISUALIZER_PARAM_CAPTURE_SIZE: + ALOGV("get mCaptureSize = %d", pContext->mCaptureSize); + *((uint32_t *)p->data + 1) = pContext->mCaptureSize; + p->vsize = sizeof(uint32_t); + *replySize += sizeof(uint32_t); + break; + case VISUALIZER_PARAM_SCALING_MODE: + ALOGV("get mScalingMode = %d", pContext->mScalingMode); + *((uint32_t *)p->data + 1) = pContext->mScalingMode; + p->vsize = sizeof(uint32_t); + *replySize += sizeof(uint32_t); + break; + default: + p->status = -EINVAL; + } } break; case EFFECT_CMD_SET_PARAM: { if (pCmdData == NULL || @@ -432,14 +451,22 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, } *(int32_t *)pReplyData = 0; effect_param_t *p = (effect_param_t *)pCmdData; - if (p->psize != sizeof(uint32_t) || - p->vsize != sizeof(uint32_t) || - *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) { + if (p->psize != sizeof(uint32_t) || p->vsize != sizeof(uint32_t)) { + *(int32_t *)pReplyData = -EINVAL; + break; + } + switch (*(uint32_t *)p->data) { + case VISUALIZER_PARAM_CAPTURE_SIZE: + pContext->mCaptureSize = *((uint32_t *)p->data + 1); + ALOGV("set mCaptureSize = %d", pContext->mCaptureSize); + break; + case VISUALIZER_PARAM_SCALING_MODE: + pContext->mScalingMode = *((uint32_t *)p->data + 1); + ALOGV("set mScalingMode = %d", pContext->mScalingMode); + break; + default: *(int32_t *)pReplyData = -EINVAL; - break;; } - pContext->mCaptureSize = *((uint32_t *)p->data + 1); - ALOGV("set mCaptureSize = %d", pContext->mCaptureSize); } break; case EFFECT_CMD_SET_DEVICE: case EFFECT_CMD_SET_VOLUME: diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp index bcd6ae4..de0bf7d 100644 --- a/media/libmedia/Visualizer.cpp +++ b/media/libmedia/Visualizer.cpp @@ -41,6 +41,7 @@ Visualizer::Visualizer (int32_t priority, mCaptureRate(CAPTURE_RATE_DEF), mCaptureSize(CAPTURE_SIZE_DEF), mSampleRate(44100000), + mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED), mCaptureCallBack(NULL), mCaptureCbkUser(NULL) { @@ -146,9 +147,38 @@ status_t Visualizer::setCaptureSize(uint32_t size) if (status == NO_ERROR) { status = p->status; + if (status == NO_ERROR) { + mCaptureSize = size; + } } + + return status; +} + +status_t Visualizer::setScalingMode(uint32_t mode) { + if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED) + && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) { + return BAD_VALUE; + } + + Mutex::Autolock _l(mCaptureLock); + + uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; + effect_param_t *p = (effect_param_t *)buf32; + + p->psize = sizeof(uint32_t); + p->vsize = sizeof(uint32_t); + *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE; + *((int32_t *)p->data + 1)= mode; + status_t status = setParameter(p); + + ALOGV("setScalingMode mode %d status %d p->status %d", mode, status, p->status); + if (status == NO_ERROR) { - mCaptureSize = size; + status = p->status; + if (status == NO_ERROR) { + mScalingMode = mode; + } } return status; @@ -289,6 +319,19 @@ uint32_t Visualizer::initCaptureSize() return size; } +void Visualizer::controlStatusChanged(bool controlGranted) { + if (controlGranted) { + // this Visualizer instance regained control of the effect, reset the scaling mode + // and capture size as has been cached through it. + ALOGV("controlStatusChanged(true) causes effect parameter reset:"); + ALOGV(" scaling mode reset to %d", mScalingMode); + setScalingMode(mScalingMode); + ALOGV(" capture size reset to %d", mCaptureSize); + setCaptureSize(mCaptureSize); + } + AudioEffect::controlStatusChanged(controlGranted); +} + //------------------------------------------------------------------------- Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava) |