Fix issue 2913071.

Scale audio signal during capture according to peak level so that
returned values on 8 bits contain enough information even for weak
signals.

Also do not reject requests to enable/disable the visualizer if we are
already in the requested state.

Change-Id: I07a705619764350834e61f82d161761eab688747
diff --git a/media/java/android/media/Visualizer.java b/media/java/android/media/Visualizer.java
index 453fc04..33222ff 100755
--- a/media/java/android/media/Visualizer.java
+++ b/media/java/android/media/Visualizer.java
@@ -218,13 +218,16 @@
     public int setEnabled(boolean enabled)
     throws IllegalStateException {
         synchronized (mStateLock) {
-            if ((enabled && mState != STATE_INITIALIZED) ||
-                    (!enabled && mState != STATE_ENABLED)) {
+            if (mState == STATE_UNINITIALIZED) {
                 throw(new IllegalStateException("setEnabled() called in wrong state: "+mState));
             }
-            int status = native_setEnabled(enabled);
-            if (status == SUCCESS) {
-                mState = enabled ? STATE_ENABLED : STATE_INITIALIZED;
+            int status = SUCCESS;
+            if ((enabled && (mState == STATE_INITIALIZED)) ||
+                    (!enabled && (mState == STATE_ENABLED))) {
+                status = native_setEnabled(enabled);
+                if (status == SUCCESS) {
+                    mState = enabled ? STATE_ENABLED : STATE_INITIALIZED;
+                }
             }
             return status;
         }
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 8ab57c93..03a6bbb 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -239,6 +239,24 @@
     }
 
     // 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;
+    for (size_t i = 0; i < inBuffer->frameCount; i++) {
+        int32_t smp = inBuffer->s16[i];
+        if (smp < 0) smp = -smp;
+        int32_t clz = __builtin_clz(smp);
+        if (shift > clz) shift = clz;
+    }
+    // never scale by less than 8 to avoid returning unaltered PCM signal.
+    // add one to combine the division by 2 needed after summing left and right channels below
+    if (20 > shift) {
+        shift = (31 - 8 + 1) - shift;
+    } else {
+        shift = (3 + 1);
+    }
+
     uint32_t captIdx;
     uint32_t inIdx;
     uint8_t *buf = pContext->mCaptureBuf[pContext->mCurrentBuf];
@@ -246,7 +264,7 @@
          inIdx < inBuffer->frameCount && captIdx < pContext->mCaptureSize;
          inIdx++, captIdx++) {
         int32_t smp = inBuffer->s16[2 * inIdx] + inBuffer->s16[2 * inIdx + 1];
-        smp = (smp + (1 << 8)) >> 9;
+        smp = (smp + (1 << (shift - 1))) >> shift;
         buf[captIdx] = ((uint8_t)smp)^0x80;
     }
     pContext->mCaptureIdx = captIdx;
@@ -369,7 +387,7 @@
 
 
     case VISU_CMD_CAPTURE:
-        if (pReplyData == NULL || *replySize != (int)pContext->mCaptureSize) {
+        if (pReplyData == NULL || *replySize != pContext->mCaptureSize) {
             LOGV("VISU_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
                     *replySize, pContext->mCaptureSize);
             return -EINVAL;