Merge "Improve resampler speed for floating point and arm64"
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index cc41efe..194a646 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -145,7 +145,16 @@
             sp<ICamera>& device) = 0;
 
     /**
-     * Turn on or off a camera's torch mode.
+     * Turn on or off a camera's torch mode. Torch mode will be turned off by
+     * camera service if the lastest client binder that turns it on dies.
+     *
+     * return values:
+     * 0:       on a successful operation.
+     * -ENOSYS: the camera device doesn't support this operation. It it returned
+     *          if and only if android.flash.into.available is false.
+     * -EBUSY:  the camera device is opened.
+     * -EINVAL: camera_id is invalid or clientBinder is NULL when enabling a
+     *          torch mode.
      */
     virtual status_t setTorchMode(const String16& cameraId, bool enabled,
             const sp<IBinder>& clientBinder) = 0;
diff --git a/include/camera/ICameraServiceListener.h b/include/camera/ICameraServiceListener.h
index 9e8b912..709ff31 100644
--- a/include/camera/ICameraServiceListener.h
+++ b/include/camera/ICameraServiceListener.h
@@ -71,18 +71,20 @@
      *
      * Initial status will be transmitted with onTorchStatusChanged immediately
      * after this listener is added to the service listener list.
+     *
+     * The enums should be set to values matching
+     * include/hardware/camera_common.h
      */
     enum TorchStatus {
-        // The camera's torch mode has become available to use via
-        // setTorchMode().
-        TORCH_STATUS_AVAILABLE      = TORCH_MODE_STATUS_AVAILABLE,
         // The camera's torch mode has become not available to use via
         // setTorchMode().
-        TORCH_STATUS_NOT_AVAILABLE  = TORCH_MODE_STATUS_RESOURCE_BUSY,
-        // The camera's torch mode has been turned off by setTorchMode().
-        TORCH_STATUS_OFF            = TORCH_MODE_STATUS_OFF,
-        // The camera's torch mode has been turned on by setTorchMode().
-        TORCH_STATUS_ON             = 0x80000000,
+        TORCH_STATUS_NOT_AVAILABLE  = TORCH_MODE_STATUS_NOT_AVAILABLE,
+        // The camera's torch mode is off and available to be turned on via
+        // setTorchMode().
+        TORCH_STATUS_AVAILABLE_OFF  = TORCH_MODE_STATUS_AVAILABLE_OFF,
+        // The camera's torch mode is on and available to be turned off via
+        // setTorchMode().
+        TORCH_STATUS_AVAILABLE_ON   = TORCH_MODE_STATUS_AVAILABLE_ON,
 
         // Use to initialize variables only
         TORCH_STATUS_UNKNOWN        = 0xFFFFFFFF,
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 482b85f..d6fe390 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -113,7 +113,19 @@
                 const audio_offload_info_t *offloadInfo = NULL) = 0;
 
         virtual status_t    start() = 0;
-        virtual ssize_t     write(const void* buffer, size_t size) = 0;
+
+        /* Input parameter |size| is in byte units stored in |buffer|.
+         * Data is copied over and actual number of bytes written (>= 0)
+         * is returned, or no data is copied and a negative status code
+         * is returned (even when |blocking| is true).
+         * When |blocking| is false, AudioSink will immediately return after
+         * part of or full |buffer| is copied over.
+         * When |blocking| is true, AudioSink will wait to copy the entire
+         * buffer, unless an error occurs or the copy operation is
+         * prematurely stopped.
+         */
+        virtual ssize_t     write(const void* buffer, size_t size, bool blocking = true) = 0;
+
         virtual void        stop() = 0;
         virtual void        flush() = 0;
         virtual void        pause() = 0;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 0b18ae0..5e5d099 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1672,13 +1672,13 @@
     }
 }
 
-ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
+ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size, bool blocking)
 {
     LOG_ALWAYS_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
 
     //ALOGV("write(%p, %u)", buffer, size);
     if (mTrack != 0) {
-        ssize_t ret = mTrack->write(buffer, size);
+        ssize_t ret = mTrack->write(buffer, size, blocking);
         if (ret >= 0) {
             mBytesWritten += ret;
         }
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 7320311..4ce4b81 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -97,7 +97,7 @@
                 const audio_offload_info_t *offloadInfo = NULL);
 
         virtual status_t        start();
-        virtual ssize_t         write(const void* buffer, size_t size);
+        virtual ssize_t         write(const void* buffer, size_t size, bool blocking = true);
         virtual void            stop();
         virtual void            flush();
         virtual void            pause();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 5d98d98..33378db 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -602,11 +602,11 @@
                     // output queue, and handles it in renderer instead.
                     rememberCodecSpecificData(newFormat);
                     onFlush(false /* notifyComplete */);
-                    err = OK;
+                    continue;
                 } else if (seamlessFormatChange) {
                     // reuse existing decoder and don't flush
                     rememberCodecSpecificData(newFormat);
-                    err = OK;
+                    continue;
                 } else {
                     // This stream is unaffected by the discontinuity
                     return -EWOULDBLOCK;
@@ -696,10 +696,7 @@
         int32_t streamErr = ERROR_END_OF_STREAM;
         CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
 
-        if (streamErr == OK) {
-            /* buffers are returned to hold on to */
-            return true;
-        }
+        CHECK(streamErr != OK);
 
         // attempt to queue EOS
         status_t err = mCodec->queueInputBuffer(
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index d21884b..e491a31 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -567,6 +567,7 @@
 }
 
 bool NuPlayer::Renderer::onDrainAudioQueue() {
+#if 0
     uint32_t numFramesPlayed;
     if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
         return false;
@@ -575,7 +576,6 @@
     ssize_t numFramesAvailableToWrite =
         mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
 
-#if 0
     if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
         ALOGI("audio sink underrun");
     } else {
@@ -584,10 +584,7 @@
     }
 #endif
 
-    size_t numBytesAvailableToWrite =
-        numFramesAvailableToWrite * mAudioSink->frameSize();
-
-    while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
+    while (!mAudioQueue.empty()) {
         QueueEntry *entry = &*mAudioQueue.begin();
 
         mLastAudioBufferDrained = entry->mBufferOrdinal;
@@ -620,14 +617,16 @@
         }
 
         size_t copy = entry->mBuffer->size() - entry->mOffset;
-        if (copy > numBytesAvailableToWrite) {
-            copy = numBytesAvailableToWrite;
-        }
 
-        ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, copy);
+        ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset,
+                                            copy, false /* blocking */);
         if (written < 0) {
             // An error in AudioSink write. Perhaps the AudioSink was not properly opened.
-            ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
+            if (written == WOULD_BLOCK) {
+                ALOGW("AudioSink write would block when writing %zu bytes", copy);
+            } else {
+                ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
+            }
             break;
         }
 
@@ -639,7 +638,6 @@
             entry = NULL;
         }
 
-        numBytesAvailableToWrite -= written;
         size_t copiedFrames = written / mAudioSink->frameSize();
         mNumFramesWritten += copiedFrames;
 
@@ -651,21 +649,23 @@
         if (written != (ssize_t)copy) {
             // A short count was received from AudioSink::write()
             //
-            // AudioSink write should block until exactly the number of bytes are delivered.
-            // But it may return with a short count (without an error) when:
+            // AudioSink write is called in non-blocking mode.
+            // It may return with a short count when:
             //
             // 1) Size to be copied is not a multiple of the frame size. We consider this fatal.
-            // 2) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
+            // 2) The data to be copied exceeds the available buffer in AudioSink.
+            // 3) An error occurs and data has been partially copied to the buffer in AudioSink.
+            // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
 
             // (Case 1)
             // Must be a multiple of the frame size.  If it is not a multiple of a frame size, it
             // needs to fail, as we should not carry over fractional frames between calls.
             CHECK_EQ(copy % mAudioSink->frameSize(), 0);
 
-            // (Case 2)
+            // (Case 2, 3, 4)
             // Return early to the caller.
             // Beware of calling immediately again as this may busy-loop if you are not careful.
-            ALOGW("AudioSink write short frame count %zd < %zu", written, copy);
+            ALOGV("AudioSink write short frame count %zd < %zu", written, copy);
             break;
         }
     }
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 482ccff..934e2e5 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -92,8 +92,10 @@
     KeyedVector<unsigned, sp<Stream> > mStreams;
     bool mFirstPTSValid;
     uint64_t mFirstPTS;
+    int64_t mLastRecoveredPTS;
 
     status_t parseProgramMap(ABitReader *br);
+    int64_t recoverPTS(uint64_t PTS_33bit);
 
     DISALLOW_EVIL_CONSTRUCTORS(Program);
 };
@@ -182,7 +184,8 @@
       mProgramNumber(programNumber),
       mProgramMapPID(programMapPID),
       mFirstPTSValid(false),
-      mFirstPTS(0) {
+      mFirstPTS(0),
+      mLastRecoveredPTS(0) {
     ALOGV("new program number %u", programNumber);
 }
 
@@ -425,6 +428,21 @@
     return OK;
 }
 
+int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
+    // We only have the lower 33-bit of the PTS. It could overflow within a
+    // reasonable amount of time. To handle the wrap-around, use fancy math
+    // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
+    // of the latest recovered PTS.
+    mLastRecoveredPTS = static_cast<int64_t>(
+            ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll)
+            & 0xfffffffe00000000ull) | PTS_33bit);
+
+    // We start from 0, but recovered PTS could be slightly below 0.
+    // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
+    // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
+    return mLastRecoveredPTS < 0ll ? 0ll : mLastRecoveredPTS;
+}
+
 sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
     size_t index = (type == AUDIO) ? 0 : 0;
 
@@ -455,6 +473,8 @@
 }
 
 int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
+    PTS = recoverPTS(PTS);
+
     if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
         if (!mFirstPTSValid) {
             mFirstPTSValid = true;
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index be8cf46..07ea605 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -1,10 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-ifeq ($(TARGET_DEVICE), manta)
-    LOCAL_CFLAGS += -DSURFACE_IS_BGR32
-endif
-
 LOCAL_SRC_FILES:=                     \
         FrameDropper.cpp              \
         GraphicBufferSource.cpp       \
diff --git a/media/libstagefright/yuv/YUVImage.cpp b/media/libstagefright/yuv/YUVImage.cpp
index bb3e2fd..c098135 100644
--- a/media/libstagefright/yuv/YUVImage.cpp
+++ b/media/libstagefright/yuv/YUVImage.cpp
@@ -374,13 +374,13 @@
 
 void YUVImage::yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue,
         uint8_t *r, uint8_t *g, uint8_t *b) const {
-    *r = yValue + (1.370705 * (vValue-128));
-    *g = yValue - (0.698001 * (vValue-128)) - (0.337633 * (uValue-128));
-    *b = yValue + (1.732446 * (uValue-128));
+    int rTmp = yValue + (1.370705 * (vValue-128));
+    int gTmp = yValue - (0.698001 * (vValue-128)) - (0.337633 * (uValue-128));
+    int bTmp = yValue + (1.732446 * (uValue-128));
 
-    *r = clamp(*r, 0, 255);
-    *g = clamp(*g, 0, 255);
-    *b = clamp(*b, 0, 255);
+    *r = clamp(rTmp, 0, 255);
+    *g = clamp(gTmp, 0, 255);
+    *b = clamp(bTmp, 0, 255);
 }
 
 bool YUVImage::writeToPPM(const char *filename) const {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f3780a9..940267a 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2949,4 +2949,4 @@
     return BnAudioFlinger::onTransact(code, data, reply, flags);
 }
 
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index aa0af1f..f5dec97 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -799,6 +799,6 @@
 
 // ----------------------------------------------------------------------------
 
-}; // namespace android
+} // namespace android
 
 #endif // ANDROID_AUDIO_FLINGER_H
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 836f550..93d821a 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -2300,4 +2300,4 @@
 }
 
 // ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index c5df08a..381036b 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -485,6 +485,6 @@
 };
 
 // ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
 #endif // ANDROID_AUDIO_MIXER_H
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index 069d946..863614a 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -170,7 +170,6 @@
 };
 
 // ----------------------------------------------------------------------------
-}
-; // namespace android
+} // namespace android
 
 #endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/services/audioflinger/AudioResamplerCubic.cpp b/services/audioflinger/AudioResamplerCubic.cpp
index 8f14ff9..d3cbd1c 100644
--- a/services/audioflinger/AudioResamplerCubic.cpp
+++ b/services/audioflinger/AudioResamplerCubic.cpp
@@ -185,5 +185,4 @@
 }
 
 // ----------------------------------------------------------------------------
-}
-; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioResamplerCubic.h b/services/audioflinger/AudioResamplerCubic.h
index b315da5..1ddc5f9 100644
--- a/services/audioflinger/AudioResamplerCubic.h
+++ b/services/audioflinger/AudioResamplerCubic.h
@@ -63,6 +63,6 @@
 };
 
 // ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index 0eeb201..c21d4ca 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -618,4 +618,4 @@
 template class AudioResamplerDyn<int32_t, int16_t, int32_t>;
 
 // ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioResamplerDyn.h b/services/audioflinger/AudioResamplerDyn.h
index e886a68..238b163 100644
--- a/services/audioflinger/AudioResamplerDyn.h
+++ b/services/audioflinger/AudioResamplerDyn.h
@@ -127,6 +127,6 @@
               void* mCoefBuffer;       // if a filter is created, this is not null
 };
 
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/
diff --git a/services/audioflinger/AudioResamplerFirGen.h b/services/audioflinger/AudioResamplerFirGen.h
index a9c84de..ad18965 100644
--- a/services/audioflinger/AudioResamplerFirGen.h
+++ b/services/audioflinger/AudioResamplerFirGen.h
@@ -707,6 +707,6 @@
     }
 }
 
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_FIR_GEN_H*/
diff --git a/services/audioflinger/AudioResamplerFirOps.h b/services/audioflinger/AudioResamplerFirOps.h
index 4af328c..658285d 100644
--- a/services/audioflinger/AudioResamplerFirOps.h
+++ b/services/audioflinger/AudioResamplerFirOps.h
@@ -158,6 +158,6 @@
 #endif
 }
 
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_FIR_OPS_H*/
diff --git a/services/audioflinger/AudioResamplerFirProcess.h b/services/audioflinger/AudioResamplerFirProcess.h
index 91d7c54..176202e 100644
--- a/services/audioflinger/AudioResamplerFirProcess.h
+++ b/services/audioflinger/AudioResamplerFirProcess.h
@@ -434,6 +434,6 @@
     }
 }
 
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_FIR_PROCESS_H*/
diff --git a/services/audioflinger/AudioResamplerFirProcessNeon.h b/services/audioflinger/AudioResamplerFirProcessNeon.h
index e8d1318..3de9edd 100644
--- a/services/audioflinger/AudioResamplerFirProcessNeon.h
+++ b/services/audioflinger/AudioResamplerFirProcessNeon.h
@@ -1209,6 +1209,6 @@
 
 #endif //USE_NEON
 
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_FIR_PROCESS_NEON_H*/
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index fdad8b6..ba9a356 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -601,4 +601,4 @@
     }
 }
 // ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index 4691d0a..6d8e85d 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -95,6 +95,6 @@
 };
 
 // ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
 #endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
diff --git a/services/audioflinger/AudioResamplerSincDown.h b/services/audioflinger/AudioResamplerSincDown.h
index b2b5969..2d0fb86 100644
--- a/services/audioflinger/AudioResamplerSincDown.h
+++ b/services/audioflinger/AudioResamplerSincDown.h
@@ -1,129 +1,131 @@
-        0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631,
-        0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d,
-        0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545,
-        0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86,
-        0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639,
-        0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b,
-        0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4,
-        0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce,
-        0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12,
-        0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9,
-        0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c,
-        0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1,
-        0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910,
-        0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f,
-        0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057,
-        0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b,
-        0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812,
-        0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02,
-        0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0,
-        0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf,
-        0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794,
-        0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934,
-        0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3,
-        0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2,
-        0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7,
-        0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542,
-        0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968,
-        0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b,
-        0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c,
-        0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef,
-        0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3,
-        0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c,
-        0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea,
-        0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf,
-        0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb,
-        0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0,
-        0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef,
-        0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508,
-        0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b,
-        0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9,
-        0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93,
-        0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9,
-        0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b,
-        0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9,
-        0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3,
-        0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa,
-        0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd,
-        0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c,
-        0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119,
-        0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821,
-        0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156,
-        0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8,
-        0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07,
-        0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962,
-        0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab,
-        0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1,
-        0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5,
-        0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976,
-        0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6,
-        0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5,
-        0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764,
-        0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473,
-        0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3,
-        0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6,
-        0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b,
-        0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686,
-        0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36,
-        0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d,
-        0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd,
-        0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9,
-        0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0,
-        0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7,
-        0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f,
-        0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a,
-        0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c,
-        0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7,
-        0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e,
-        0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5,
-        0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de,
-        0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d,
-        0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57,
-        0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf,
-        0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89,
-        0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa,
-        0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17,
-        0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5,
-        0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8,
-        0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5,
-        0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4,
-        0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329,
-        0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a,
-        0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd,
-        0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a,
-        0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857,
-        0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a,
-        0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c,
-        0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52,
-        0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6,
-        0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60,
-        0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86,
-        0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62,
-        0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec,
-        0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e,
-        0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef,
-        0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b,
-        0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a,
-        0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5,
-        0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8,
-        0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d,
-        0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d,
-        0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525,
-        0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e,
-        0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84,
-        0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453,
-        0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86,
-        0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a,
-        0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09,
-        0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552,
-        0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef,
-        0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df,
-        0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e,
-        0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9,
-        0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e,
-        0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a,
-        0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc,
-        0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1,
-        0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787,
-        0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae,
-        0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713,
+// cmd-line: fir -l 7 -s48000 -c 17189
+
+    0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631,
+    0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d,
+    0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545,
+    0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86,
+    0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639,
+    0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b,
+    0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4,
+    0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce,
+    0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12,
+    0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9,
+    0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c,
+    0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1,
+    0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910,
+    0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f,
+    0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057,
+    0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b,
+    0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812,
+    0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02,
+    0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0,
+    0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf,
+    0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794,
+    0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934,
+    0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3,
+    0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2,
+    0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7,
+    0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542,
+    0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968,
+    0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b,
+    0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c,
+    0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef,
+    0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3,
+    0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c,
+    0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea,
+    0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf,
+    0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb,
+    0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0,
+    0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef,
+    0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508,
+    0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b,
+    0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9,
+    0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93,
+    0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9,
+    0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b,
+    0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9,
+    0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3,
+    0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa,
+    0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd,
+    0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c,
+    0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119,
+    0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821,
+    0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156,
+    0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8,
+    0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07,
+    0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962,
+    0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab,
+    0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1,
+    0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5,
+    0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976,
+    0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6,
+    0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5,
+    0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764,
+    0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473,
+    0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3,
+    0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6,
+    0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b,
+    0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686,
+    0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36,
+    0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d,
+    0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd,
+    0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9,
+    0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0,
+    0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7,
+    0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f,
+    0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a,
+    0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c,
+    0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7,
+    0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e,
+    0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5,
+    0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de,
+    0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d,
+    0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57,
+    0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf,
+    0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89,
+    0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa,
+    0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17,
+    0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5,
+    0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8,
+    0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5,
+    0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4,
+    0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329,
+    0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a,
+    0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd,
+    0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a,
+    0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857,
+    0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a,
+    0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c,
+    0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52,
+    0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6,
+    0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60,
+    0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86,
+    0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62,
+    0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec,
+    0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e,
+    0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef,
+    0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b,
+    0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a,
+    0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5,
+    0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8,
+    0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d,
+    0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d,
+    0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525,
+    0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e,
+    0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84,
+    0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453,
+    0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86,
+    0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a,
+    0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09,
+    0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552,
+    0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef,
+    0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df,
+    0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e,
+    0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9,
+    0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e,
+    0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a,
+    0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc,
+    0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1,
+    0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787,
+    0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae,
+    0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713,
diff --git a/services/audioflinger/AudioResamplerSincUp.h b/services/audioflinger/AudioResamplerSincUp.h
index eab20aa..fd5367e 100644
--- a/services/audioflinger/AudioResamplerSincUp.h
+++ b/services/audioflinger/AudioResamplerSincUp.h
@@ -1,129 +1,131 @@
-        0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300,
-        0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592,
-        0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e,
-        0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f,
-        0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10,
-        0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e,
-        0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6,
-        0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5,
-        0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd,
-        0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb,
-        0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2,
-        0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3,
-        0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371,
-        0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921,
-        0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5,
-        0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564,
-        0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04,
-        0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab,
-        0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62,
-        0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230,
-        0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e,
-        0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337,
-        0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85,
-        0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112,
-        0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec,
-        0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d,
-        0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3,
-        0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb,
-        0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244,
-        0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c,
-        0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012,
-        0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075,
-        0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97,
-        0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486,
-        0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854,
-        0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812,
-        0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3,
-        0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7,
-        0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1,
-        0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5,
-        0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54,
-        0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533,
-        0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84,
-        0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c,
-        0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace,
-        0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef,
-        0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2,
-        0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d,
-        0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434,
-        0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc,
-        0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99,
-        0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781,
-        0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8,
-        0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125,
-        0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b,
-        0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070,
-        0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69,
-        0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b,
-        0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b,
-        0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e,
-        0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba,
-        0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3,
-        0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd,
-        0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f,
-        0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb,
-        0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7,
-        0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6,
-        0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae,
-        0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1,
-        0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5,
-        0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b,
-        0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8,
-        0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff,
-        0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422,
-        0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245,
-        0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79,
-        0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2,
-        0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760,
-        0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235,
-        0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64,
-        0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc,
-        0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f,
-        0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac,
-        0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5,
-        0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9,
-        0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67,
-        0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce,
-        0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e,
-        0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535,
-        0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50,
-        0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e,
-        0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c,
-        0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8,
-        0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d,
-        0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108,
-        0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5,
-        0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130,
-        0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4,
-        0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb,
-        0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21,
-        0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff,
-        0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f,
-        0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b,
-        0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb,
-        0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8,
-        0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa,
-        0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a,
-        0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e,
-        0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d,
-        0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0,
-        0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b,
-        0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65,
-        0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74,
-        0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e,
-        0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426,
-        0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2,
-        0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65,
-        0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5,
-        0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54,
-        0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7,
-        0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e,
-        0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f,
-        0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa,
-        0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2,
-        0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39,
-        0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f,
-        0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7,
-        0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10,
-        0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c,
+// cmd-line: fir -l 7 -s48000 -c 20478
+
+    0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300,
+    0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592,
+    0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e,
+    0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f,
+    0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10,
+    0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e,
+    0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6,
+    0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5,
+    0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd,
+    0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb,
+    0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2,
+    0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3,
+    0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371,
+    0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921,
+    0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5,
+    0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564,
+    0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04,
+    0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab,
+    0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62,
+    0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230,
+    0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e,
+    0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337,
+    0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85,
+    0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112,
+    0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec,
+    0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d,
+    0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3,
+    0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb,
+    0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244,
+    0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c,
+    0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012,
+    0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075,
+    0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97,
+    0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486,
+    0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854,
+    0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812,
+    0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3,
+    0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7,
+    0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1,
+    0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5,
+    0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54,
+    0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533,
+    0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84,
+    0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c,
+    0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace,
+    0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef,
+    0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2,
+    0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d,
+    0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434,
+    0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc,
+    0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99,
+    0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781,
+    0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8,
+    0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125,
+    0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b,
+    0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070,
+    0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69,
+    0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b,
+    0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b,
+    0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e,
+    0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba,
+    0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3,
+    0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd,
+    0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f,
+    0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb,
+    0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7,
+    0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6,
+    0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae,
+    0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1,
+    0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5,
+    0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b,
+    0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8,
+    0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff,
+    0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422,
+    0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245,
+    0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79,
+    0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2,
+    0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760,
+    0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235,
+    0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64,
+    0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc,
+    0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f,
+    0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac,
+    0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5,
+    0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9,
+    0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67,
+    0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce,
+    0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e,
+    0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535,
+    0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50,
+    0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e,
+    0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c,
+    0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8,
+    0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d,
+    0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108,
+    0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5,
+    0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130,
+    0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4,
+    0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb,
+    0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21,
+    0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff,
+    0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f,
+    0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b,
+    0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb,
+    0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8,
+    0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa,
+    0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a,
+    0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e,
+    0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d,
+    0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0,
+    0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b,
+    0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65,
+    0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74,
+    0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e,
+    0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426,
+    0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2,
+    0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65,
+    0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5,
+    0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54,
+    0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7,
+    0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e,
+    0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f,
+    0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa,
+    0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2,
+    0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39,
+    0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f,
+    0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7,
+    0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10,
+    0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c,
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index 6a8aeb1..845697a 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -29,9 +29,8 @@
 // uncomment to display CPU load adjusted for CPU frequency
 //#define CPU_FREQUENCY_STATISTICS
 
-// uncomment to enable fast mixer to take performance samples for later statistical analysis
-#define FAST_MIXER_STATISTICS
-// FIXME rename to FAST_THREAD_STATISTICS
+// uncomment to enable fast threads to take performance samples for later statistical analysis
+#define FAST_THREAD_STATISTICS
 
 // uncomment for debugging timing problems related to StateQueue::push()
 //#define STATE_QUEUE_DUMP
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index bcaf8ae..8bccb47 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1953,4 +1953,4 @@
     }
 }
 
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index 255496e..9e7e8a4 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -29,18 +29,18 @@
 
 namespace android {
 
-/*static*/ const FastCaptureState FastCapture::initial;
+/*static*/ const FastCaptureState FastCapture::sInitial;
 
 FastCapture::FastCapture() : FastThread(),
-    inputSource(NULL), inputSourceGen(0), pipeSink(NULL), pipeSinkGen(0),
-    readBuffer(NULL), readBufferState(-1), format(Format_Invalid), sampleRate(0),
-    // dummyDumpState
-    totalNativeFramesRead(0)
+    mInputSource(NULL), mInputSourceGen(0), mPipeSink(NULL), mPipeSinkGen(0),
+    mReadBuffer(NULL), mReadBufferState(-1), mFormat(Format_Invalid), mSampleRate(0),
+    // mDummyDumpState
+    mTotalNativeFramesRead(0)
 {
-    previous = &initial;
-    current = &initial;
+    mPrevious = &sInitial;
+    mCurrent = &sInitial;
 
-    mDummyDumpState = &dummyDumpState;
+    mDummyDumpState = &mDummyFastCaptureDumpState;
 }
 
 FastCapture::~FastCapture()
@@ -63,13 +63,13 @@
 
 void FastCapture::onIdle()
 {
-    preIdle = *(const FastCaptureState *)current;
-    current = &preIdle;
+    mPreIdle = *(const FastCaptureState *)mCurrent;
+    mCurrent = &mPreIdle;
 }
 
 void FastCapture::onExit()
 {
-    delete[] readBuffer;
+    free(mReadBuffer);
 }
 
 bool FastCapture::isSubClassCommand(FastThreadState::Command command)
@@ -86,69 +86,67 @@
 
 void FastCapture::onStateChange()
 {
-    const FastCaptureState * const current = (const FastCaptureState *) this->current;
-    const FastCaptureState * const previous = (const FastCaptureState *) this->previous;
-    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) this->dumpState;
+    const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
+    const FastCaptureState * const previous = (const FastCaptureState *) mPrevious;
+    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
     const size_t frameCount = current->mFrameCount;
 
     bool eitherChanged = false;
 
     // check for change in input HAL configuration
-    NBAIO_Format previousFormat = format;
-    if (current->mInputSourceGen != inputSourceGen) {
-        inputSource = current->mInputSource;
-        inputSourceGen = current->mInputSourceGen;
-        if (inputSource == NULL) {
-            format = Format_Invalid;
-            sampleRate = 0;
+    NBAIO_Format previousFormat = mFormat;
+    if (current->mInputSourceGen != mInputSourceGen) {
+        mInputSource = current->mInputSource;
+        mInputSourceGen = current->mInputSourceGen;
+        if (mInputSource == NULL) {
+            mFormat = Format_Invalid;
+            mSampleRate = 0;
         } else {
-            format = inputSource->format();
-            sampleRate = Format_sampleRate(format);
-            unsigned channelCount = Format_channelCount(format);
+            mFormat = mInputSource->format();
+            mSampleRate = Format_sampleRate(mFormat);
+            unsigned channelCount = Format_channelCount(mFormat);
             ALOG_ASSERT(channelCount == 1 || channelCount == 2);
         }
-        dumpState->mSampleRate = sampleRate;
+        dumpState->mSampleRate = mSampleRate;
         eitherChanged = true;
     }
 
     // check for change in pipe
-    if (current->mPipeSinkGen != pipeSinkGen) {
-        pipeSink = current->mPipeSink;
-        pipeSinkGen = current->mPipeSinkGen;
+    if (current->mPipeSinkGen != mPipeSinkGen) {
+        mPipeSink = current->mPipeSink;
+        mPipeSinkGen = current->mPipeSinkGen;
         eitherChanged = true;
     }
 
     // input source and pipe sink must be compatible
-    if (eitherChanged && inputSource != NULL && pipeSink != NULL) {
-        ALOG_ASSERT(Format_isEqual(format, pipeSink->format()));
+    if (eitherChanged && mInputSource != NULL && mPipeSink != NULL) {
+        ALOG_ASSERT(Format_isEqual(mFormat, mPipeSink->format()));
     }
 
-    if ((!Format_isEqual(format, previousFormat)) || (frameCount != previous->mFrameCount)) {
-        // FIXME to avoid priority inversion, don't delete here
-        delete[] readBuffer;
-        readBuffer = NULL;
-        if (frameCount > 0 && sampleRate > 0) {
+    if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
+        // FIXME to avoid priority inversion, don't free here
+        free(mReadBuffer);
+        mReadBuffer = NULL;
+        if (frameCount > 0 && mSampleRate > 0) {
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal capture thread allocate for
             //       us to avoid blocking here and to prevent possible priority inversion
-            unsigned channelCount = Format_channelCount(format);
-            // FIXME frameSize
-            readBuffer = new short[frameCount * channelCount];
-            periodNs = (frameCount * 1000000000LL) / sampleRate;    // 1.00
-            underrunNs = (frameCount * 1750000000LL) / sampleRate;  // 1.75
-            overrunNs = (frameCount * 500000000LL) / sampleRate;    // 0.50
-            forceNs = (frameCount * 950000000LL) / sampleRate;      // 0.95
-            warmupNsMin = (frameCount * 750000000LL) / sampleRate;  // 0.75
-            warmupNsMax = (frameCount * 1250000000LL) / sampleRate; // 1.25
+            (void)posix_memalign(&mReadBuffer, 32, frameCount * Format_frameSize(mFormat));
+            mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;      // 1.00
+            mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;    // 1.75
+            mOverrunNs = (frameCount * 500000000LL) / mSampleRate;      // 0.50
+            mForceNs = (frameCount * 950000000LL) / mSampleRate;        // 0.95
+            mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;    // 0.75
+            mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate;   // 1.25
         } else {
-            periodNs = 0;
-            underrunNs = 0;
-            overrunNs = 0;
-            forceNs = 0;
-            warmupNsMin = 0;
-            warmupNsMax = LONG_MAX;
+            mPeriodNs = 0;
+            mUnderrunNs = 0;
+            mOverrunNs = 0;
+            mForceNs = 0;
+            mWarmupNsMin = 0;
+            mWarmupNsMax = LONG_MAX;
         }
-        readBufferState = -1;
+        mReadBufferState = -1;
         dumpState->mFrameCount = frameCount;
     }
 
@@ -156,44 +154,43 @@
 
 void FastCapture::onWork()
 {
-    const FastCaptureState * const current = (const FastCaptureState *) this->current;
-    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) this->dumpState;
-    const FastCaptureState::Command command = this->command;
+    const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
+    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
+    const FastCaptureState::Command command = mCommand;
     const size_t frameCount = current->mFrameCount;
 
     if ((command & FastCaptureState::READ) /*&& isWarm*/) {
-        ALOG_ASSERT(inputSource != NULL);
-        ALOG_ASSERT(readBuffer != NULL);
+        ALOG_ASSERT(mInputSource != NULL);
+        ALOG_ASSERT(mReadBuffer != NULL);
         dumpState->mReadSequence++;
         ATRACE_BEGIN("read");
-        ssize_t framesRead = inputSource->read(readBuffer, frameCount,
+        ssize_t framesRead = mInputSource->read(mReadBuffer, frameCount,
                 AudioBufferProvider::kInvalidPTS);
         ATRACE_END();
         dumpState->mReadSequence++;
         if (framesRead >= 0) {
             LOG_ALWAYS_FATAL_IF((size_t) framesRead > frameCount);
-            totalNativeFramesRead += framesRead;
-            dumpState->mFramesRead = totalNativeFramesRead;
-            readBufferState = framesRead;
+            mTotalNativeFramesRead += framesRead;
+            dumpState->mFramesRead = mTotalNativeFramesRead;
+            mReadBufferState = framesRead;
         } else {
             dumpState->mReadErrors++;
-            readBufferState = 0;
+            mReadBufferState = 0;
         }
         // FIXME rename to attemptedIO
-        attemptedWrite = true;
+        mAttemptedWrite = true;
     }
 
     if (command & FastCaptureState::WRITE) {
-        ALOG_ASSERT(pipeSink != NULL);
-        ALOG_ASSERT(readBuffer != NULL);
-        if (readBufferState < 0) {
-            unsigned channelCount = Format_channelCount(format);
-            // FIXME frameSize
-            memset(readBuffer, 0, frameCount * channelCount * sizeof(short));
-            readBufferState = frameCount;
+        ALOG_ASSERT(mPipeSink != NULL);
+        ALOG_ASSERT(mReadBuffer != NULL);
+        if (mReadBufferState < 0) {
+            unsigned channelCount = Format_channelCount(mFormat);
+            memset(mReadBuffer, 0, frameCount * Format_frameSize(mFormat));
+            mReadBufferState = frameCount;
         }
-        if (readBufferState > 0) {
-            ssize_t framesWritten = pipeSink->write(readBuffer, readBufferState);
+        if (mReadBufferState > 0) {
+            ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
             // FIXME This supports at most one fast capture client.
             //       To handle multiple clients this could be converted to an array,
             //       or with a lot more work the control block could be shared by all clients.
diff --git a/services/audioflinger/FastCapture.h b/services/audioflinger/FastCapture.h
index da0fe2f..e258a4d 100644
--- a/services/audioflinger/FastCapture.h
+++ b/services/audioflinger/FastCapture.h
@@ -46,19 +46,21 @@
     virtual void onStateChange();
     virtual void onWork();
 
-    static const FastCaptureState initial;
-    FastCaptureState preIdle; // copy of state before we went into idle
+    static const FastCaptureState sInitial;
+
+    FastCaptureState    mPreIdle;   // copy of state before we went into idle
     // FIXME by renaming, could pull up many of these to FastThread
-    NBAIO_Source *inputSource;
-    int inputSourceGen;
-    NBAIO_Sink *pipeSink;
-    int pipeSinkGen;
-    short *readBuffer;
-    ssize_t readBufferState;    // number of initialized frames in readBuffer, or -1 to clear
-    NBAIO_Format format;
-    unsigned sampleRate;
-    FastCaptureDumpState dummyDumpState;
-    uint32_t totalNativeFramesRead; // copied to dumpState->mFramesRead
+    NBAIO_Source*       mInputSource;
+    int                 mInputSourceGen;
+    NBAIO_Sink*         mPipeSink;
+    int                 mPipeSinkGen;
+    void*               mReadBuffer;
+    ssize_t             mReadBufferState;   // number of initialized frames in readBuffer,
+                                            // or -1 to clear
+    NBAIO_Format        mFormat;
+    unsigned            mSampleRate;
+    FastCaptureDumpState mDummyFastCaptureDumpState;
+    uint32_t            mTotalNativeFramesRead; // copied to dumpState->mFramesRead
 
 };  // class FastCapture
 
diff --git a/services/audioflinger/FastCaptureState.cpp b/services/audioflinger/FastCaptureState.cpp
index 1d029b7..c4d5e45 100644
--- a/services/audioflinger/FastCaptureState.cpp
+++ b/services/audioflinger/FastCaptureState.cpp
@@ -27,4 +27,19 @@
 {
 }
 
+// static
+const char *FastCaptureState::commandToString(Command command)
+{
+    const char *str = FastThreadState::commandToString(command);
+    if (str != NULL) {
+        return str;
+    }
+    switch (command) {
+    case FastCaptureState::READ:        return "READ";
+    case FastCaptureState::WRITE:       return "WRITE";
+    case FastCaptureState::READ_WRITE:  return "READ_WRITE";
+    }
+    LOG_ALWAYS_FATAL("%s", __func__);
+}
+
 }   // android
diff --git a/services/audioflinger/FastCaptureState.h b/services/audioflinger/FastCaptureState.h
index 29c865a..9bca2d4 100644
--- a/services/audioflinger/FastCaptureState.h
+++ b/services/audioflinger/FastCaptureState.h
@@ -29,21 +29,23 @@
     /*virtual*/ ~FastCaptureState();
 
     // all pointer fields use raw pointers; objects are owned and ref-counted by RecordThread
-    NBAIO_Source    *mInputSource;      // HAL input device, must already be negotiated
+    NBAIO_Source*   mInputSource;       // HAL input device, must already be negotiated
     // FIXME by renaming, could pull up these fields to FastThreadState
     int             mInputSourceGen;    // increment when mInputSource is assigned
-    NBAIO_Sink      *mPipeSink;         // after reading from input source, write to this pipe sink
+    NBAIO_Sink*     mPipeSink;          // after reading from input source, write to this pipe sink
     int             mPipeSinkGen;       // increment when mPipeSink is assigned
     size_t          mFrameCount;        // number of frames per fast capture buffer
-    audio_track_cblk_t  *mCblk;         // control block for the single fast client, or NULL
+    audio_track_cblk_t* mCblk;          // control block for the single fast client, or NULL
 
     // Extends FastThreadState::Command
     static const Command
         // The following commands also process configuration changes, and can be "or"ed:
-        READ = 0x8,             // read from input source
-        WRITE = 0x10,           // write to pipe sink
-        READ_WRITE = 0x18;      // read from input source and write to pipe sink
+        READ = 0x8,                     // read from input source
+        WRITE = 0x10,                   // write to pipe sink
+        READ_WRITE = 0x18;              // read from input source and write to pipe sink
 
+    // never returns NULL; asserts if command is invalid
+    static const char *commandToString(Command command);
 };  // struct FastCaptureState
 
 }   // namespace android
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 8b12f28..e070f90 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -31,7 +31,7 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <system/audio.h>
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
 #include <cpustats/CentralTendencyStatistics.h>
 #ifdef CPU_FREQUENCY_STATISTICS
 #include <cpustats/ThreadCpuUsage.h>
@@ -45,15 +45,15 @@
 
 namespace android {
 
-/*static*/ const FastMixerState FastMixer::initial;
+/*static*/ const FastMixerState FastMixer::sInitial;
 
 FastMixer::FastMixer() : FastThread(),
-    slopNs(0),
-    // fastTrackNames
-    // generations
-    outputSink(NULL),
-    outputSinkGen(0),
-    mixer(NULL),
+    mSlopNs(0),
+    // mFastTrackNames
+    // mGenerations
+    mOutputSink(NULL),
+    mOutputSinkGen(0),
+    mMixer(NULL),
     mSinkBuffer(NULL),
     mSinkBufferSize(0),
     mSinkChannelCount(FCC_2),
@@ -61,30 +61,30 @@
     mMixerBufferSize(0),
     mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT),
     mMixerBufferState(UNDEFINED),
-    format(Format_Invalid),
-    sampleRate(0),
-    fastTracksGen(0),
-    totalNativeFramesWritten(0),
+    mFormat(Format_Invalid),
+    mSampleRate(0),
+    mFastTracksGen(0),
+    mTotalNativeFramesWritten(0),
     // timestamp
-    nativeFramesWrittenButNotPresented(0)   // the = 0 is to silence the compiler
+    mNativeFramesWrittenButNotPresented(0)   // the = 0 is to silence the compiler
 {
-    // FIXME pass initial as parameter to base class constructor, and make it static local
-    previous = &initial;
-    current = &initial;
+    // FIXME pass sInitial as parameter to base class constructor, and make it static local
+    mPrevious = &sInitial;
+    mCurrent = &sInitial;
 
-    mDummyDumpState = &dummyDumpState;
+    mDummyDumpState = &mDummyFastMixerDumpState;
     // TODO: Add channel mask to NBAIO_Format.
     // We assume that the channel mask must be a valid positional channel mask.
     mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
 
     unsigned i;
     for (i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
-        fastTrackNames[i] = -1;
-        generations[i] = 0;
+        mFastTrackNames[i] = -1;
+        mGenerations[i] = 0;
     }
-#ifdef FAST_MIXER_STATISTICS
-    oldLoad.tv_sec = 0;
-    oldLoad.tv_nsec = 0;
+#ifdef FAST_THREAD_STATISTICS
+    mOldLoad.tv_sec = 0;
+    mOldLoad.tv_nsec = 0;
 #endif
 }
 
@@ -104,20 +104,20 @@
 
 void FastMixer::setLog(NBLog::Writer *logWriter)
 {
-    if (mixer != NULL) {
-        mixer->setLog(logWriter);
+    if (mMixer != NULL) {
+        mMixer->setLog(logWriter);
     }
 }
 
 void FastMixer::onIdle()
 {
-    preIdle = *(const FastMixerState *)current;
-    current = &preIdle;
+    mPreIdle = *(const FastMixerState *)mCurrent;
+    mCurrent = &mPreIdle;
 }
 
 void FastMixer::onExit()
 {
-    delete mixer;
+    delete mMixer;
     free(mMixerBuffer);
     free(mSinkBuffer);
 }
@@ -136,84 +136,84 @@
 
 void FastMixer::onStateChange()
 {
-    const FastMixerState * const current = (const FastMixerState *) this->current;
-    const FastMixerState * const previous = (const FastMixerState *) this->previous;
-    FastMixerDumpState * const dumpState = (FastMixerDumpState *) this->dumpState;
+    const FastMixerState * const current = (const FastMixerState *) mCurrent;
+    const FastMixerState * const previous = (const FastMixerState *) mPrevious;
+    FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
     const size_t frameCount = current->mFrameCount;
 
     // handle state change here, but since we want to diff the state,
-    // we're prepared for previous == &initial the first time through
+    // we're prepared for previous == &sInitial the first time through
     unsigned previousTrackMask;
 
     // check for change in output HAL configuration
-    NBAIO_Format previousFormat = format;
-    if (current->mOutputSinkGen != outputSinkGen) {
-        outputSink = current->mOutputSink;
-        outputSinkGen = current->mOutputSinkGen;
-        if (outputSink == NULL) {
-            format = Format_Invalid;
-            sampleRate = 0;
+    NBAIO_Format previousFormat = mFormat;
+    if (current->mOutputSinkGen != mOutputSinkGen) {
+        mOutputSink = current->mOutputSink;
+        mOutputSinkGen = current->mOutputSinkGen;
+        if (mOutputSink == NULL) {
+            mFormat = Format_Invalid;
+            mSampleRate = 0;
             mSinkChannelCount = 0;
             mSinkChannelMask = AUDIO_CHANNEL_NONE;
         } else {
-            format = outputSink->format();
-            sampleRate = Format_sampleRate(format);
-            mSinkChannelCount = Format_channelCount(format);
+            mFormat = mOutputSink->format();
+            mSampleRate = Format_sampleRate(mFormat);
+            mSinkChannelCount = Format_channelCount(mFormat);
             LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS);
 
             // TODO: Add channel mask to NBAIO_Format
             // We assume that the channel mask must be a valid positional channel mask.
             mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
         }
-        dumpState->mSampleRate = sampleRate;
+        dumpState->mSampleRate = mSampleRate;
     }
 
-    if ((!Format_isEqual(format, previousFormat)) || (frameCount != previous->mFrameCount)) {
+    if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
         // FIXME to avoid priority inversion, don't delete here
-        delete mixer;
-        mixer = NULL;
+        delete mMixer;
+        mMixer = NULL;
         free(mMixerBuffer);
         mMixerBuffer = NULL;
         free(mSinkBuffer);
         mSinkBuffer = NULL;
-        if (frameCount > 0 && sampleRate > 0) {
+        if (frameCount > 0 && mSampleRate > 0) {
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal mixer allocate for us
             //       to avoid blocking here and to prevent possible priority inversion
-            mixer = new AudioMixer(frameCount, sampleRate, FastMixerState::kMaxFastTracks);
+            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
             const size_t mixerFrameSize = mSinkChannelCount
                     * audio_bytes_per_sample(mMixerBufferFormat);
             mMixerBufferSize = mixerFrameSize * frameCount;
             (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
             const size_t sinkFrameSize = mSinkChannelCount
-                    * audio_bytes_per_sample(format.mFormat);
+                    * audio_bytes_per_sample(mFormat.mFormat);
             if (sinkFrameSize > mixerFrameSize) { // need a sink buffer
                 mSinkBufferSize = sinkFrameSize * frameCount;
                 (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize);
             }
-            periodNs = (frameCount * 1000000000LL) / sampleRate;    // 1.00
-            underrunNs = (frameCount * 1750000000LL) / sampleRate;  // 1.75
-            overrunNs = (frameCount * 500000000LL) / sampleRate;    // 0.50
-            forceNs = (frameCount * 950000000LL) / sampleRate;      // 0.95
-            warmupNsMin = (frameCount * 750000000LL) / sampleRate;  // 0.75
-            warmupNsMax = (frameCount * 1250000000LL) / sampleRate; // 1.25
+            mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;    // 1.00
+            mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;  // 1.75
+            mOverrunNs = (frameCount * 500000000LL) / mSampleRate;    // 0.50
+            mForceNs = (frameCount * 950000000LL) / mSampleRate;      // 0.95
+            mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;  // 0.75
+            mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
         } else {
-            periodNs = 0;
-            underrunNs = 0;
-            overrunNs = 0;
-            forceNs = 0;
-            warmupNsMin = 0;
-            warmupNsMax = LONG_MAX;
+            mPeriodNs = 0;
+            mUnderrunNs = 0;
+            mOverrunNs = 0;
+            mForceNs = 0;
+            mWarmupNsMin = 0;
+            mWarmupNsMax = LONG_MAX;
         }
         mMixerBufferState = UNDEFINED;
 #if !LOG_NDEBUG
         for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
-            fastTrackNames[i] = -1;
+            mFastTrackNames[i] = -1;
         }
 #endif
         // we need to reconfigure all active tracks
         previousTrackMask = 0;
-        fastTracksGen = current->mFastTracksGen - 1;
+        mFastTracksGen = current->mFastTracksGen - 1;
         dumpState->mFrameCount = frameCount;
     } else {
         previousTrackMask = previous->mTrackMask;
@@ -222,7 +222,7 @@
     // check for change in active track set
     const unsigned currentTrackMask = current->mTrackMask;
     dumpState->mTrackMask = currentTrackMask;
-    if (current->mFastTracksGen != fastTracksGen) {
+    if (current->mFastTracksGen != mFastTracksGen) {
         ALOG_ASSERT(mMixerBuffer != NULL);
         int name;
 
@@ -233,16 +233,16 @@
             removedTracks &= ~(1 << i);
             const FastTrack* fastTrack = &current->mFastTracks[i];
             ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
-            if (mixer != NULL) {
-                name = fastTrackNames[i];
+            if (mMixer != NULL) {
+                name = mFastTrackNames[i];
                 ALOG_ASSERT(name >= 0);
-                mixer->deleteTrackName(name);
+                mMixer->deleteTrackName(name);
             }
 #if !LOG_NDEBUG
-            fastTrackNames[i] = -1;
+            mFastTrackNames[i] = -1;
 #endif
             // don't reset track dump state, since other side is ignoring it
-            generations[i] = fastTrack->mGeneration;
+            mGenerations[i] = fastTrack->mGeneration;
         }
 
         // now process added tracks
@@ -252,29 +252,29 @@
             addedTracks &= ~(1 << i);
             const FastTrack* fastTrack = &current->mFastTracks[i];
             AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
-            ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
-            if (mixer != NULL) {
-                name = mixer->getTrackName(fastTrack->mChannelMask,
+            ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
+            if (mMixer != NULL) {
+                name = mMixer->getTrackName(fastTrack->mChannelMask,
                         fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
                 ALOG_ASSERT(name >= 0);
-                fastTrackNames[i] = name;
-                mixer->setBufferProvider(name, bufferProvider);
-                mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
+                mFastTrackNames[i] = name;
+                mMixer->setBufferProvider(name, bufferProvider);
+                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
                         (void *)mMixerBuffer);
                 // newly allocated track names default to full scale volume
-                mixer->setParameter(
+                mMixer->setParameter(
                         name,
                         AudioMixer::TRACK,
                         AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
-                mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
+                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
                         (void *)(uintptr_t)fastTrack->mFormat);
-                mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
+                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
                         (void *)(uintptr_t)fastTrack->mChannelMask);
-                mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
+                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
                         (void *)(uintptr_t)mSinkChannelMask);
-                mixer->enable(name);
+                mMixer->enable(name);
             }
-            generations[i] = fastTrack->mGeneration;
+            mGenerations[i] = fastTrack->mGeneration;
         }
 
         // finally process (potentially) modified tracks; these use the same slot
@@ -284,38 +284,38 @@
             int i = __builtin_ctz(modifiedTracks);
             modifiedTracks &= ~(1 << i);
             const FastTrack* fastTrack = &current->mFastTracks[i];
-            if (fastTrack->mGeneration != generations[i]) {
+            if (fastTrack->mGeneration != mGenerations[i]) {
                 // this track was actually modified
                 AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
                 ALOG_ASSERT(bufferProvider != NULL);
-                if (mixer != NULL) {
-                    name = fastTrackNames[i];
+                if (mMixer != NULL) {
+                    name = mFastTrackNames[i];
                     ALOG_ASSERT(name >= 0);
-                    mixer->setBufferProvider(name, bufferProvider);
+                    mMixer->setBufferProvider(name, bufferProvider);
                     if (fastTrack->mVolumeProvider == NULL) {
                         float f = AudioMixer::UNITY_GAIN_FLOAT;
-                        mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
-                        mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
+                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
+                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
                     }
-                    mixer->setParameter(name, AudioMixer::RESAMPLE,
+                    mMixer->setParameter(name, AudioMixer::RESAMPLE,
                             AudioMixer::REMOVE, NULL);
-                    mixer->setParameter(
+                    mMixer->setParameter(
                             name,
                             AudioMixer::TRACK,
                             AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
-                    mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
+                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
                             (void *)(uintptr_t)fastTrack->mFormat);
-                    mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
+                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
                             (void *)(uintptr_t)fastTrack->mChannelMask);
-                    mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
+                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
                             (void *)(uintptr_t)mSinkChannelMask);
                     // already enabled
                 }
-                generations[i] = fastTrack->mGeneration;
+                mGenerations[i] = fastTrack->mGeneration;
             }
         }
 
-        fastTracksGen = current->mFastTracksGen;
+        mFastTracksGen = current->mFastTracksGen;
 
         dumpState->mNumTracks = popcount(currentTrackMask);
     }
@@ -323,12 +323,12 @@
 
 void FastMixer::onWork()
 {
-    const FastMixerState * const current = (const FastMixerState *) this->current;
-    FastMixerDumpState * const dumpState = (FastMixerDumpState *) this->dumpState;
-    const FastMixerState::Command command = this->command;
+    const FastMixerState * const current = (const FastMixerState *) mCurrent;
+    FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
+    const FastMixerState::Command command = mCommand;
     const size_t frameCount = current->mFrameCount;
 
-    if ((command & FastMixerState::MIX) && (mixer != NULL) && isWarm) {
+    if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
         ALOG_ASSERT(mMixerBuffer != NULL);
         // for each track, update volume and check for underrun
         unsigned currentTrackMask = current->mTrackMask;
@@ -338,9 +338,9 @@
             const FastTrack* fastTrack = &current->mFastTracks[i];
 
             // Refresh the per-track timestamp
-            if (timestampStatus == NO_ERROR) {
+            if (mTimestampStatus == NO_ERROR) {
                 uint32_t trackFramesWrittenButNotPresented =
-                    nativeFramesWrittenButNotPresented;
+                    mNativeFramesWrittenButNotPresented;
                 uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
                 // Can't provide an AudioTimestamp before first frame presented,
                 // or during the brief 32-bit wraparound window
@@ -348,20 +348,20 @@
                     AudioTimestamp perTrackTimestamp;
                     perTrackTimestamp.mPosition =
                             trackFramesWritten - trackFramesWrittenButNotPresented;
-                    perTrackTimestamp.mTime = timestamp.mTime;
+                    perTrackTimestamp.mTime = mTimestamp.mTime;
                     fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
                 }
             }
 
-            int name = fastTrackNames[i];
+            int name = mFastTrackNames[i];
             ALOG_ASSERT(name >= 0);
             if (fastTrack->mVolumeProvider != NULL) {
                 gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
                 float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
 
-                mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
-                mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
+                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
+                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
             }
             // FIXME The current implementation of framesReady() for fast tracks
             // takes a tryLock, which can block
@@ -382,43 +382,43 @@
                 if (framesReady == 0) {
                     underruns.mBitFields.mEmpty++;
                     underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
-                    mixer->disable(name);
+                    mMixer->disable(name);
                 } else {
                     // allow mixing partial buffer
                     underruns.mBitFields.mPartial++;
                     underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
-                    mixer->enable(name);
+                    mMixer->enable(name);
                 }
             } else {
                 underruns.mBitFields.mFull++;
                 underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
-                mixer->enable(name);
+                mMixer->enable(name);
             }
             ftDump->mUnderruns = underruns;
             ftDump->mFramesReady = framesReady;
         }
 
         int64_t pts;
-        if (outputSink == NULL || (OK != outputSink->getNextWriteTimestamp(&pts))) {
+        if (mOutputSink == NULL || (OK != mOutputSink->getNextWriteTimestamp(&pts))) {
             pts = AudioBufferProvider::kInvalidPTS;
         }
 
         // process() is CPU-bound
-        mixer->process(pts);
+        mMixer->process(pts);
         mMixerBufferState = MIXED;
     } else if (mMixerBufferState == MIXED) {
         mMixerBufferState = UNDEFINED;
     }
     //bool didFullWrite = false;    // dumpsys could display a count of partial writes
-    if ((command & FastMixerState::WRITE) && (outputSink != NULL) && (mMixerBuffer != NULL)) {
+    if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
         if (mMixerBufferState == UNDEFINED) {
             memset(mMixerBuffer, 0, mMixerBufferSize);
             mMixerBufferState = ZEROED;
         }
         void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
-        if (format.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
-            memcpy_by_audio_format(buffer, format.mFormat, mMixerBuffer, mMixerBufferFormat,
-                    frameCount * Format_channelCount(format));
+        if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
+            memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
+                    frameCount * Format_channelCount(mFormat));
         }
         // if non-NULL, then duplicate write() to this non-blocking sink
         NBAIO_Sink* teeSink;
@@ -429,31 +429,31 @@
         //       but this code should be modified to handle both non-blocking and blocking sinks
         dumpState->mWriteSequence++;
         ATRACE_BEGIN("write");
-        ssize_t framesWritten = outputSink->write(buffer, frameCount);
+        ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
         ATRACE_END();
         dumpState->mWriteSequence++;
         if (framesWritten >= 0) {
             ALOG_ASSERT((size_t) framesWritten <= frameCount);
-            totalNativeFramesWritten += framesWritten;
-            dumpState->mFramesWritten = totalNativeFramesWritten;
+            mTotalNativeFramesWritten += framesWritten;
+            dumpState->mFramesWritten = mTotalNativeFramesWritten;
             //if ((size_t) framesWritten == frameCount) {
             //    didFullWrite = true;
             //}
         } else {
             dumpState->mWriteErrors++;
         }
-        attemptedWrite = true;
+        mAttemptedWrite = true;
         // FIXME count # of writes blocked excessively, CPU usage, etc. for dump
 
-        timestampStatus = outputSink->getTimestamp(timestamp);
-        if (timestampStatus == NO_ERROR) {
-            uint32_t totalNativeFramesPresented = timestamp.mPosition;
-            if (totalNativeFramesPresented <= totalNativeFramesWritten) {
-                nativeFramesWrittenButNotPresented =
-                    totalNativeFramesWritten - totalNativeFramesPresented;
+        mTimestampStatus = mOutputSink->getTimestamp(mTimestamp);
+        if (mTimestampStatus == NO_ERROR) {
+            uint32_t totalNativeFramesPresented = mTimestamp.mPosition;
+            if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
+                mNativeFramesWrittenButNotPresented =
+                    mTotalNativeFramesWritten - totalNativeFramesPresented;
             } else {
                 // HAL reported that more frames were presented than were written
-                timestampStatus = INVALID_OPERATION;
+                mTimestampStatus = INVALID_OPERATION;
             }
         }
     }
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 7649db2..06a68fb 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -48,36 +48,39 @@
     virtual void onStateChange();
     virtual void onWork();
 
-    // FIXME these former local variables need comments and to be renamed to have "m" prefix
-    static const FastMixerState initial;
-    FastMixerState preIdle; // copy of state before we went into idle
-    long slopNs;        // accumulated time we've woken up too early (> 0) or too late (< 0)
-    int fastTrackNames[FastMixerState::kMaxFastTracks]; // handles used by mixer to identify tracks
-    int generations[FastMixerState::kMaxFastTracks];    // last observed mFastTracks[i].mGeneration
-    NBAIO_Sink *outputSink;
-    int outputSinkGen;
-    AudioMixer* mixer;
+    // FIXME these former local variables need comments
+    static const FastMixerState sInitial;
+
+    FastMixerState  mPreIdle;   // copy of state before we went into idle
+    long            mSlopNs;    // accumulated time we've woken up too early (> 0) or too late (< 0)
+    int             mFastTrackNames[FastMixerState::kMaxFastTracks];
+                                // handles used by mixer to identify tracks
+    int             mGenerations[FastMixerState::kMaxFastTracks];
+                                // last observed mFastTracks[i].mGeneration
+    NBAIO_Sink*     mOutputSink;
+    int             mOutputSinkGen;
+    AudioMixer*     mMixer;
 
     // mSinkBuffer audio format is stored in format.mFormat.
-    void* mSinkBuffer;                  // used for mixer output format translation
+    void*           mSinkBuffer;        // used for mixer output format translation
                                         // if sink format is different than mixer output.
-    size_t mSinkBufferSize;
-    uint32_t mSinkChannelCount;
+    size_t          mSinkBufferSize;
+    uint32_t        mSinkChannelCount;
     audio_channel_mask_t mSinkChannelMask;
-    void* mMixerBuffer;                 // mixer output buffer.
-    size_t mMixerBufferSize;
-    audio_format_t mMixerBufferFormat;  // mixer output format: AUDIO_FORMAT_PCM_(16_BIT|FLOAT).
+    void*           mMixerBuffer;       // mixer output buffer.
+    size_t          mMixerBufferSize;
+    audio_format_t  mMixerBufferFormat; // mixer output format: AUDIO_FORMAT_PCM_(16_BIT|FLOAT).
 
     enum {UNDEFINED, MIXED, ZEROED} mMixerBufferState;
-    NBAIO_Format format;
-    unsigned sampleRate;
-    int fastTracksGen;
-    FastMixerDumpState dummyDumpState;
-    uint32_t totalNativeFramesWritten;  // copied to dumpState->mFramesWritten
+    NBAIO_Format    mFormat;
+    unsigned        mSampleRate;
+    int             mFastTracksGen;
+    FastMixerDumpState mDummyFastMixerDumpState;
+    uint32_t        mTotalNativeFramesWritten;  // copied to dumpState->mFramesWritten
 
     // next 2 fields are valid only when timestampStatus == NO_ERROR
-    AudioTimestamp timestamp;
-    uint32_t nativeFramesWrittenButNotPresented;
+    AudioTimestamp  mTimestamp;
+    uint32_t        mNativeFramesWrittenButNotPresented;
 
 };  // class FastMixer
 
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 0ddd908..386b29d 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -18,7 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include "Configuration.h"
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
 #include <cpustats/CentralTendencyStatistics.h>
 #ifdef CPU_FREQUENCY_STATISTICS
 #include <cpustats/ThreadCpuUsage.h>
@@ -30,39 +30,14 @@
 
 namespace android {
 
-FastMixerDumpState::FastMixerDumpState(
-#ifdef FAST_MIXER_STATISTICS
-        uint32_t samplingN
-#endif
-        ) : FastThreadDumpState(),
+FastMixerDumpState::FastMixerDumpState() : FastThreadDumpState(),
     mWriteSequence(0), mFramesWritten(0),
     mNumTracks(0), mWriteErrors(0),
     mSampleRate(0), mFrameCount(0),
     mTrackMask(0)
 {
-#ifdef FAST_MIXER_STATISTICS
-    increaseSamplingN(samplingN);
-#endif
 }
 
-#ifdef FAST_MIXER_STATISTICS
-void FastMixerDumpState::increaseSamplingN(uint32_t samplingN)
-{
-    if (samplingN <= mSamplingN || samplingN > kSamplingN || roundup(samplingN) != samplingN) {
-        return;
-    }
-    uint32_t additional = samplingN - mSamplingN;
-    // sample arrays aren't accessed atomically with respect to the bounds,
-    // so clearing reduces chance for dumpsys to read random uninitialized samples
-    memset(&mMonotonicNs[mSamplingN], 0, sizeof(mMonotonicNs[0]) * additional);
-    memset(&mLoadNs[mSamplingN], 0, sizeof(mLoadNs[0]) * additional);
-#ifdef CPU_FREQUENCY_STATISTICS
-    memset(&mCpukHz[mSamplingN], 0, sizeof(mCpukHz[0]) * additional);
-#endif
-    mSamplingN = samplingN;
-}
-#endif
-
 FastMixerDumpState::~FastMixerDumpState()
 {
 }
@@ -87,34 +62,6 @@
         dprintf(fd, "  FastMixer not initialized\n");
         return;
     }
-#define COMMAND_MAX 32
-    char string[COMMAND_MAX];
-    switch (mCommand) {
-    case FastMixerState::INITIAL:
-        strcpy(string, "INITIAL");
-        break;
-    case FastMixerState::HOT_IDLE:
-        strcpy(string, "HOT_IDLE");
-        break;
-    case FastMixerState::COLD_IDLE:
-        strcpy(string, "COLD_IDLE");
-        break;
-    case FastMixerState::EXIT:
-        strcpy(string, "EXIT");
-        break;
-    case FastMixerState::MIX:
-        strcpy(string, "MIX");
-        break;
-    case FastMixerState::WRITE:
-        strcpy(string, "WRITE");
-        break;
-    case FastMixerState::MIX_WRITE:
-        strcpy(string, "MIX_WRITE");
-        break;
-    default:
-        snprintf(string, COMMAND_MAX, "%d", mCommand);
-        break;
-    }
     double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
             (mMeasuredWarmupTs.tv_nsec / 1000000.0);
     double mixPeriodSec = (double) mFrameCount / (double) mSampleRate;
@@ -122,11 +69,11 @@
                 "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
                 "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
                 "            mixPeriod=%.2f ms\n",
-                 string, mWriteSequence, mFramesWritten,
+                 FastMixerState::commandToString(mCommand), mWriteSequence, mFramesWritten,
                  mNumTracks, mWriteErrors, mUnderruns, mOverruns,
                  mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
                  mixPeriodSec * 1e3);
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
     // find the interval of valid samples
     uint32_t bounds = mBounds;
     uint32_t newestOpen = bounds & 0xFFFF;
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/FastMixerDumpState.h
index f8354dd..ac15e7c 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/FastMixerDumpState.h
@@ -55,22 +55,12 @@
 struct FastTrackDump {
     FastTrackDump() : mFramesReady(0) { }
     /*virtual*/ ~FastTrackDump() { }
-    FastTrackUnderruns mUnderruns;
-    size_t mFramesReady;        // most recent value only; no long-term statistics kept
+    FastTrackUnderruns  mUnderruns;
+    size_t              mFramesReady;        // most recent value only; no long-term statistics kept
 };
 
-// The FastMixerDumpState keeps a cache of FastMixer statistics that can be logged by dumpsys.
-// Each individual native word-sized field is accessed atomically.  But the
-// overall structure is non-atomic, that is there may be an inconsistency between fields.
-// No barriers or locks are used for either writing or reading.
-// Only POD types are permitted, and the contents shouldn't be trusted (i.e. do range checks).
-// It has a different lifetime than the FastMixer, and so it can't be a member of FastMixer.
 struct FastMixerDumpState : FastThreadDumpState {
-    FastMixerDumpState(
-#ifdef FAST_MIXER_STATISTICS
-            uint32_t samplingN = kSamplingNforLowRamDevice
-#endif
-            );
+    FastMixerDumpState();
     /*virtual*/ ~FastMixerDumpState();
 
     void dump(int fd) const;    // should only be called on a stable copy, not the original
@@ -83,14 +73,6 @@
     size_t   mFrameCount;
     uint32_t mTrackMask;        // mask of active tracks
     FastTrackDump   mTracks[FastMixerState::kMaxFastTracks];
-
-#ifdef FAST_MIXER_STATISTICS
-    // Compile-time constant for a "low RAM device", must be a power of 2 <= kSamplingN.
-    // This value was chosen such that each array uses 1 small page (4 Kbytes).
-    static const uint32_t kSamplingNforLowRamDevice = 0x400;
-    // Increase sampling window after construction, must be a power of 2 <= kSamplingN
-    void    increaseSamplingN(uint32_t samplingN);
-#endif
 };
 
 }   // android
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 3aa8dad..a8c2634 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -39,4 +39,19 @@
 {
 }
 
+// static
+const char *FastMixerState::commandToString(Command command)
+{
+    const char *str = FastThreadState::commandToString(command);
+    if (str != NULL) {
+        return str;
+    }
+    switch (command) {
+    case FastMixerState::MIX:       return "MIX";
+    case FastMixerState::WRITE:     return "WRITE";
+    case FastMixerState::MIX_WRITE: return "MIX_WRITE";
+    }
+    LOG_ALWAYS_FATAL("%s", __func__);
+}
+
 }   // namespace android
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index 661c9ca..916514f 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -73,6 +73,9 @@
 
     // This might be a one-time configuration rather than per-state
     NBAIO_Sink* mTeeSink;       // if non-NULL, then duplicate write()s to this non-blocking sink
+
+    // never returns NULL; asserts if command is invalid
+    static const char *commandToString(Command command);
 };  // struct FastMixerState
 
 }   // namespace android
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index b69cc85..5ca579b 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -36,47 +36,47 @@
 namespace android {
 
 FastThread::FastThread() : Thread(false /*canCallJava*/),
-    // re-initialized to &initial by subclass constructor
-     previous(NULL), current(NULL),
-    /* oldTs({0, 0}), */
-    oldTsValid(false),
-    sleepNs(-1),
-    periodNs(0),
-    underrunNs(0),
-    overrunNs(0),
-    forceNs(0),
-    warmupNsMin(0),
-    warmupNsMax(LONG_MAX),
-    // re-initialized to &dummyDumpState by subclass constructor
+    // re-initialized to &sInitial by subclass constructor
+    mPrevious(NULL), mCurrent(NULL),
+    /* mOldTs({0, 0}), */
+    mOldTsValid(false),
+    mSleepNs(-1),
+    mPeriodNs(0),
+    mUnderrunNs(0),
+    mOverrunNs(0),
+    mForceNs(0),
+    mWarmupNsMin(0),
+    mWarmupNsMax(LONG_MAX),
+    // re-initialized to &mDummySubclassDumpState by subclass constructor
     mDummyDumpState(NULL),
-    dumpState(NULL),
-    ignoreNextOverrun(true),
-#ifdef FAST_MIXER_STATISTICS
-    // oldLoad
-    oldLoadValid(false),
-    bounds(0),
-    full(false),
-    // tcu
+    mDumpState(NULL),
+    mIgnoreNextOverrun(true),
+#ifdef FAST_THREAD_STATISTICS
+    // mOldLoad
+    mOldLoadValid(false),
+    mBounds(0),
+    mFull(false),
+    // mTcu
 #endif
-    coldGen(0),
-    isWarm(false),
-    /* measuredWarmupTs({0, 0}), */
-    warmupCycles(0),
-    warmupConsecutiveInRangeCycles(0),
-    // dummyLogWriter
-    logWriter(&dummyLogWriter),
-    timestampStatus(INVALID_OPERATION),
+    mColdGen(0),
+    mIsWarm(false),
+    /* mMeasuredWarmupTs({0, 0}), */
+    mWarmupCycles(0),
+    mWarmupConsecutiveInRangeCycles(0),
+    // mDummyLogWriter
+    mLogWriter(&mDummyLogWriter),
+    mTimestampStatus(INVALID_OPERATION),
 
-    command(FastThreadState::INITIAL),
+    mCommand(FastThreadState::INITIAL),
 #if 0
     frameCount(0),
 #endif
-    attemptedWrite(false)
+    mAttemptedWrite(false)
 {
-    oldTs.tv_sec = 0;
-    oldTs.tv_nsec = 0;
-    measuredWarmupTs.tv_sec = 0;
-    measuredWarmupTs.tv_nsec = 0;
+    mOldTs.tv_sec = 0;
+    mOldTs.tv_nsec = 0;
+    mMeasuredWarmupTs.tv_sec = 0;
+    mMeasuredWarmupTs.tv_nsec = 0;
 }
 
 FastThread::~FastThread()
@@ -88,34 +88,34 @@
     for (;;) {
 
         // either nanosleep, sched_yield, or busy wait
-        if (sleepNs >= 0) {
-            if (sleepNs > 0) {
-                ALOG_ASSERT(sleepNs < 1000000000);
-                const struct timespec req = {0, sleepNs};
+        if (mSleepNs >= 0) {
+            if (mSleepNs > 0) {
+                ALOG_ASSERT(mSleepNs < 1000000000);
+                const struct timespec req = {0, mSleepNs};
                 nanosleep(&req, NULL);
             } else {
                 sched_yield();
             }
         }
         // default to long sleep for next cycle
-        sleepNs = FAST_DEFAULT_NS;
+        mSleepNs = FAST_DEFAULT_NS;
 
         // poll for state change
         const FastThreadState *next = poll();
         if (next == NULL) {
             // continue to use the default initial state until a real state is available
-            // FIXME &initial not available, should save address earlier
-            //ALOG_ASSERT(current == &initial && previous == &initial);
-            next = current;
+            // FIXME &sInitial not available, should save address earlier
+            //ALOG_ASSERT(mCurrent == &sInitial && previous == &sInitial);
+            next = mCurrent;
         }
 
-        command = next->mCommand;
-        if (next != current) {
+        mCommand = next->mCommand;
+        if (next != mCurrent) {
 
             // As soon as possible of learning of a new dump area, start using it
-            dumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
-            logWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &dummyLogWriter;
-            setLog(logWriter);
+            mDumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
+            mLogWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &mDummyLogWriter;
+            setLog(mLogWriter);
 
             // We want to always have a valid reference to the previous (non-idle) state.
             // However, the state queue only guarantees access to current and previous states.
@@ -126,37 +126,38 @@
             //  non-idle -> idle        update previous from copy of current
             //  idle     -> idle        don't update previous
             //  idle     -> non-idle    don't update previous
-            if (!(current->mCommand & FastThreadState::IDLE)) {
-                if (command & FastThreadState::IDLE) {
+            if (!(mCurrent->mCommand & FastThreadState::IDLE)) {
+                if (mCommand & FastThreadState::IDLE) {
                     onIdle();
-                    oldTsValid = false;
-#ifdef FAST_MIXER_STATISTICS
-                    oldLoadValid = false;
+                    mOldTsValid = false;
+#ifdef FAST_THREAD_STATISTICS
+                    mOldLoadValid = false;
 #endif
-                    ignoreNextOverrun = true;
+                    mIgnoreNextOverrun = true;
                 }
-                previous = current;
+                mPrevious = mCurrent;
             }
-            current = next;
+            mCurrent = next;
         }
 #if !LOG_NDEBUG
         next = NULL;    // not referenced again
 #endif
 
-        dumpState->mCommand = command;
+        mDumpState->mCommand = mCommand;
 
+        // FIXME what does this comment mean?
         // << current, previous, command, dumpState >>
 
-        switch (command) {
+        switch (mCommand) {
         case FastThreadState::INITIAL:
         case FastThreadState::HOT_IDLE:
-            sleepNs = FAST_HOT_IDLE_NS;
+            mSleepNs = FAST_HOT_IDLE_NS;
             continue;
         case FastThreadState::COLD_IDLE:
             // only perform a cold idle command once
             // FIXME consider checking previous state and only perform if previous != COLD_IDLE
-            if (current->mColdGen != coldGen) {
-                int32_t *coldFutexAddr = current->mColdFutexAddr;
+            if (mCurrent->mColdGen != mColdGen) {
+                int32_t *coldFutexAddr = mCurrent->mColdFutexAddr;
                 ALOG_ASSERT(coldFutexAddr != NULL);
                 int32_t old = android_atomic_dec(coldFutexAddr);
                 if (old <= 0) {
@@ -168,42 +169,42 @@
                 }
                 // This may be overly conservative; there could be times that the normal mixer
                 // requests such a brief cold idle that it doesn't require resetting this flag.
-                isWarm = false;
-                measuredWarmupTs.tv_sec = 0;
-                measuredWarmupTs.tv_nsec = 0;
-                warmupCycles = 0;
-                warmupConsecutiveInRangeCycles = 0;
-                sleepNs = -1;
-                coldGen = current->mColdGen;
-#ifdef FAST_MIXER_STATISTICS
-                bounds = 0;
-                full = false;
+                mIsWarm = false;
+                mMeasuredWarmupTs.tv_sec = 0;
+                mMeasuredWarmupTs.tv_nsec = 0;
+                mWarmupCycles = 0;
+                mWarmupConsecutiveInRangeCycles = 0;
+                mSleepNs = -1;
+                mColdGen = mCurrent->mColdGen;
+#ifdef FAST_THREAD_STATISTICS
+                mBounds = 0;
+                mFull = false;
 #endif
-                oldTsValid = !clock_gettime(CLOCK_MONOTONIC, &oldTs);
-                timestampStatus = INVALID_OPERATION;
+                mOldTsValid = !clock_gettime(CLOCK_MONOTONIC, &mOldTs);
+                mTimestampStatus = INVALID_OPERATION;
             } else {
-                sleepNs = FAST_HOT_IDLE_NS;
+                mSleepNs = FAST_HOT_IDLE_NS;
             }
             continue;
         case FastThreadState::EXIT:
             onExit();
             return false;
         default:
-            LOG_ALWAYS_FATAL_IF(!isSubClassCommand(command));
+            LOG_ALWAYS_FATAL_IF(!isSubClassCommand(mCommand));
             break;
         }
 
         // there is a non-idle state available to us; did the state change?
-        if (current != previous) {
+        if (mCurrent != mPrevious) {
             onStateChange();
 #if 1   // FIXME shouldn't need this
             // only process state change once
-            previous = current;
+            mPrevious = mCurrent;
 #endif
         }
 
         // do work using current state here
-        attemptedWrite = false;
+        mAttemptedWrite = false;
         onWork();
 
         // To be exactly periodic, compute the next sleep time based on current time.
@@ -212,13 +213,13 @@
         struct timespec newTs;
         int rc = clock_gettime(CLOCK_MONOTONIC, &newTs);
         if (rc == 0) {
-            //logWriter->logTimestamp(newTs);
-            if (oldTsValid) {
-                time_t sec = newTs.tv_sec - oldTs.tv_sec;
-                long nsec = newTs.tv_nsec - oldTs.tv_nsec;
+            //mLogWriter->logTimestamp(newTs);
+            if (mOldTsValid) {
+                time_t sec = newTs.tv_sec - mOldTs.tv_sec;
+                long nsec = newTs.tv_nsec - mOldTs.tv_nsec;
                 ALOGE_IF(sec < 0 || (sec == 0 && nsec < 0),
                         "clock_gettime(CLOCK_MONOTONIC) failed: was %ld.%09ld but now %ld.%09ld",
-                        oldTs.tv_sec, oldTs.tv_nsec, newTs.tv_sec, newTs.tv_nsec);
+                        mOldTs.tv_sec, mOldTs.tv_nsec, newTs.tv_sec, newTs.tv_nsec);
                 if (nsec < 0) {
                     --sec;
                     nsec += 1000000000;
@@ -227,69 +228,69 @@
                 // do not start pulling data from tracks and mixing until warmup is complete.
                 // Warmup is considered complete after the earlier of:
                 //      MIN_WARMUP_CYCLES consecutive in-range write() attempts,
-                //          where "in-range" means warmupNsMin <= cycle time <= warmupNsMax
+                //          where "in-range" means mWarmupNsMin <= cycle time <= mWarmupNsMax
                 //      MAX_WARMUP_CYCLES write() attempts.
                 // This is overly conservative, but to get better accuracy requires a new HAL API.
-                if (!isWarm && attemptedWrite) {
-                    measuredWarmupTs.tv_sec += sec;
-                    measuredWarmupTs.tv_nsec += nsec;
-                    if (measuredWarmupTs.tv_nsec >= 1000000000) {
-                        measuredWarmupTs.tv_sec++;
-                        measuredWarmupTs.tv_nsec -= 1000000000;
+                if (!mIsWarm && mAttemptedWrite) {
+                    mMeasuredWarmupTs.tv_sec += sec;
+                    mMeasuredWarmupTs.tv_nsec += nsec;
+                    if (mMeasuredWarmupTs.tv_nsec >= 1000000000) {
+                        mMeasuredWarmupTs.tv_sec++;
+                        mMeasuredWarmupTs.tv_nsec -= 1000000000;
                     }
-                    ++warmupCycles;
-                    if (warmupNsMin <= nsec && nsec <= warmupNsMax) {
-                        ALOGV("warmup cycle %d in range: %.03f ms", warmupCycles, nsec * 1e-9);
-                        ++warmupConsecutiveInRangeCycles;
+                    ++mWarmupCycles;
+                    if (mWarmupNsMin <= nsec && nsec <= mWarmupNsMax) {
+                        ALOGV("warmup cycle %d in range: %.03f ms", mWarmupCycles, nsec * 1e-9);
+                        ++mWarmupConsecutiveInRangeCycles;
                     } else {
-                        ALOGV("warmup cycle %d out of range: %.03f ms", warmupCycles, nsec * 1e-9);
-                        warmupConsecutiveInRangeCycles = 0;
+                        ALOGV("warmup cycle %d out of range: %.03f ms", mWarmupCycles, nsec * 1e-9);
+                        mWarmupConsecutiveInRangeCycles = 0;
                     }
-                    if ((warmupConsecutiveInRangeCycles >= MIN_WARMUP_CYCLES) ||
-                            (warmupCycles >= MAX_WARMUP_CYCLES)) {
-                        isWarm = true;
-                        dumpState->mMeasuredWarmupTs = measuredWarmupTs;
-                        dumpState->mWarmupCycles = warmupCycles;
+                    if ((mWarmupConsecutiveInRangeCycles >= MIN_WARMUP_CYCLES) ||
+                            (mWarmupCycles >= MAX_WARMUP_CYCLES)) {
+                        mIsWarm = true;
+                        mDumpState->mMeasuredWarmupTs = mMeasuredWarmupTs;
+                        mDumpState->mWarmupCycles = mWarmupCycles;
                     }
                 }
-                sleepNs = -1;
-                if (isWarm) {
-                    if (sec > 0 || nsec > underrunNs) {
+                mSleepNs = -1;
+                if (mIsWarm) {
+                    if (sec > 0 || nsec > mUnderrunNs) {
                         ATRACE_NAME("underrun");
                         // FIXME only log occasionally
                         ALOGV("underrun: time since last cycle %d.%03ld sec",
                                 (int) sec, nsec / 1000000L);
-                        dumpState->mUnderruns++;
-                        ignoreNextOverrun = true;
-                    } else if (nsec < overrunNs) {
-                        if (ignoreNextOverrun) {
-                            ignoreNextOverrun = false;
+                        mDumpState->mUnderruns++;
+                        mIgnoreNextOverrun = true;
+                    } else if (nsec < mOverrunNs) {
+                        if (mIgnoreNextOverrun) {
+                            mIgnoreNextOverrun = false;
                         } else {
                             // FIXME only log occasionally
                             ALOGV("overrun: time since last cycle %d.%03ld sec",
                                     (int) sec, nsec / 1000000L);
-                            dumpState->mOverruns++;
+                            mDumpState->mOverruns++;
                         }
                         // This forces a minimum cycle time. It:
                         //  - compensates for an audio HAL with jitter due to sample rate conversion
                         //  - works with a variable buffer depth audio HAL that never pulls at a
-                        //    rate < than overrunNs per buffer.
+                        //    rate < than mOverrunNs per buffer.
                         //  - recovers from overrun immediately after underrun
                         // It doesn't work with a non-blocking audio HAL.
-                        sleepNs = forceNs - nsec;
+                        mSleepNs = mForceNs - nsec;
                     } else {
-                        ignoreNextOverrun = false;
+                        mIgnoreNextOverrun = false;
                     }
                 }
-#ifdef FAST_MIXER_STATISTICS
-                if (isWarm) {
+#ifdef FAST_THREAD_STATISTICS
+                if (mIsWarm) {
                     // advance the FIFO queue bounds
-                    size_t i = bounds & (dumpState->mSamplingN - 1);
-                    bounds = (bounds & 0xFFFF0000) | ((bounds + 1) & 0xFFFF);
-                    if (full) {
-                        bounds += 0x10000;
-                    } else if (!(bounds & (dumpState->mSamplingN - 1))) {
-                        full = true;
+                    size_t i = mBounds & (mDumpState->mSamplingN - 1);
+                    mBounds = (mBounds & 0xFFFF0000) | ((mBounds + 1) & 0xFFFF);
+                    if (mFull) {
+                        mBounds += 0x10000;
+                    } else if (!(mBounds & (mDumpState->mSamplingN - 1))) {
+                        mFull = true;
                     }
                     // compute the delta value of clock_gettime(CLOCK_MONOTONIC)
                     uint32_t monotonicNs = nsec;
@@ -301,9 +302,9 @@
                     struct timespec newLoad;
                     rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &newLoad);
                     if (rc == 0) {
-                        if (oldLoadValid) {
-                            sec = newLoad.tv_sec - oldLoad.tv_sec;
-                            nsec = newLoad.tv_nsec - oldLoad.tv_nsec;
+                        if (mOldLoadValid) {
+                            sec = newLoad.tv_sec - mOldLoad.tv_sec;
+                            nsec = newLoad.tv_nsec - mOldLoad.tv_nsec;
                             if (nsec < 0) {
                                 --sec;
                                 nsec += 1000000000;
@@ -314,42 +315,42 @@
                             }
                         } else {
                             // first time through the loop
-                            oldLoadValid = true;
+                            mOldLoadValid = true;
                         }
-                        oldLoad = newLoad;
+                        mOldLoad = newLoad;
                     }
 #ifdef CPU_FREQUENCY_STATISTICS
                     // get the absolute value of CPU clock frequency in kHz
                     int cpuNum = sched_getcpu();
-                    uint32_t kHz = tcu.getCpukHz(cpuNum);
+                    uint32_t kHz = mTcu.getCpukHz(cpuNum);
                     kHz = (kHz << 4) | (cpuNum & 0xF);
 #endif
                     // save values in FIFO queues for dumpsys
                     // these stores #1, #2, #3 are not atomic with respect to each other,
                     // or with respect to store #4 below
-                    dumpState->mMonotonicNs[i] = monotonicNs;
-                    dumpState->mLoadNs[i] = loadNs;
+                    mDumpState->mMonotonicNs[i] = monotonicNs;
+                    mDumpState->mLoadNs[i] = loadNs;
 #ifdef CPU_FREQUENCY_STATISTICS
-                    dumpState->mCpukHz[i] = kHz;
+                    mDumpState->mCpukHz[i] = kHz;
 #endif
                     // this store #4 is not atomic with respect to stores #1, #2, #3 above, but
                     // the newest open & oldest closed halves are atomic with respect to each other
-                    dumpState->mBounds = bounds;
+                    mDumpState->mBounds = mBounds;
                     ATRACE_INT("cycle_ms", monotonicNs / 1000000);
                     ATRACE_INT("load_us", loadNs / 1000);
                 }
 #endif
             } else {
                 // first time through the loop
-                oldTsValid = true;
-                sleepNs = periodNs;
-                ignoreNextOverrun = true;
+                mOldTsValid = true;
+                mSleepNs = mPeriodNs;
+                mIgnoreNextOverrun = true;
             }
-            oldTs = newTs;
+            mOldTs = newTs;
         } else {
             // monotonic clock is broken
-            oldTsValid = false;
-            sleepNs = periodNs;
+            mOldTsValid = false;
+            mSleepNs = mPeriodNs;
         }
 
     }   // for (;;)
diff --git a/services/audioflinger/FastThread.h b/services/audioflinger/FastThread.h
index cb32e9d..2efb6de 100644
--- a/services/audioflinger/FastThread.h
+++ b/services/audioflinger/FastThread.h
@@ -48,44 +48,45 @@
     virtual void onStateChange() = 0;
     virtual void onWork() = 0;
 
-    // FIXME these former local variables need comments and to be renamed to have an "m" prefix
-    const FastThreadState *previous;
-    const FastThreadState *current;
-    struct timespec oldTs;
-    bool oldTsValid;
-    long sleepNs;   // -1: busy wait, 0: sched_yield, > 0: nanosleep
-    long periodNs;      // expected period; the time required to render one mix buffer
-    long underrunNs;    // underrun likely when write cycle is greater than this value
-    long overrunNs;     // overrun likely when write cycle is less than this value
-    long forceNs;       // if overrun detected, force the write cycle to take this much time
-    long warmupNsMin;   // warmup complete when write cycle is greater than or equal to this value
-    long warmupNsMax;   //                                 and less than or equal to this value
-    FastThreadDumpState *mDummyDumpState;
-    FastThreadDumpState *dumpState;
-    bool ignoreNextOverrun;  // used to ignore initial overrun and first after an underrun
-#ifdef FAST_MIXER_STATISTICS
-    struct timespec oldLoad;    // previous value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
-    bool oldLoadValid;  // whether oldLoad is valid
-    uint32_t bounds;
-    bool full;          // whether we have collected at least mSamplingN samples
+    // FIXME these former local variables need comments
+    const FastThreadState*  mPrevious;
+    const FastThreadState*  mCurrent;
+    struct timespec mOldTs;
+    bool            mOldTsValid;
+    long            mSleepNs;       // -1: busy wait, 0: sched_yield, > 0: nanosleep
+    long            mPeriodNs;      // expected period; the time required to render one mix buffer
+    long            mUnderrunNs;    // underrun likely when write cycle is greater than this value
+    long            mOverrunNs;     // overrun likely when write cycle is less than this value
+    long            mForceNs;       // if overrun detected,
+                                    // force the write cycle to take this much time
+    long            mWarmupNsMin;   // warmup complete when write cycle is greater than or equal to
+                                    // this value
+    long            mWarmupNsMax;   // and less than or equal to this value
+    FastThreadDumpState* mDummyDumpState;
+    FastThreadDumpState* mDumpState;
+    bool            mIgnoreNextOverrun;     // used to ignore initial overrun and first after an
+                                            // underrun
+#ifdef FAST_THREAD_STATISTICS
+    struct timespec mOldLoad;       // previous value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
+    bool            mOldLoadValid;  // whether oldLoad is valid
+    uint32_t        mBounds;
+    bool            mFull;          // whether we have collected at least mSamplingN samples
 #ifdef CPU_FREQUENCY_STATISTICS
-    ThreadCpuUsage tcu;     // for reading the current CPU clock frequency in kHz
+    ThreadCpuUsage  mTcu;           // for reading the current CPU clock frequency in kHz
 #endif
 #endif
-    unsigned coldGen;   // last observed mColdGen
-    bool isWarm;        // true means ready to mix, false means wait for warmup before mixing
-    struct timespec measuredWarmupTs;  // how long did it take for warmup to complete
-    uint32_t warmupCycles;  // counter of number of loop cycles during warmup phase
-    uint32_t warmupConsecutiveInRangeCycles;    // number of consecutive cycles in range
-    NBLog::Writer dummyLogWriter;
-    NBLog::Writer *logWriter;
-    status_t timestampStatus;
+    unsigned        mColdGen;       // last observed mColdGen
+    bool            mIsWarm;        // true means ready to mix,
+                                    // false means wait for warmup before mixing
+    struct timespec mMeasuredWarmupTs;  // how long did it take for warmup to complete
+    uint32_t        mWarmupCycles;  // counter of number of loop cycles during warmup phase
+    uint32_t        mWarmupConsecutiveInRangeCycles;    // number of consecutive cycles in range
+    NBLog::Writer   mDummyLogWriter;
+    NBLog::Writer*  mLogWriter;
+    status_t        mTimestampStatus;
 
-    FastThreadState::Command command;
-#if 0
-    size_t frameCount;
-#endif
-    bool attemptedWrite;
+    FastThreadState::Command mCommand;
+    bool            mAttemptedWrite;
 
 };  // class FastThread
 
diff --git a/services/audioflinger/FastThreadDumpState.cpp b/services/audioflinger/FastThreadDumpState.cpp
index d7b825d..9df5c4c 100644
--- a/services/audioflinger/FastThreadDumpState.cpp
+++ b/services/audioflinger/FastThreadDumpState.cpp
@@ -22,16 +22,37 @@
     mCommand(FastThreadState::INITIAL), mUnderruns(0), mOverruns(0),
     /* mMeasuredWarmupTs({0, 0}), */
     mWarmupCycles(0)
-#ifdef FAST_MIXER_STATISTICS
-    , mSamplingN(1), mBounds(0)
+#ifdef FAST_THREAD_STATISTICS
+    , mSamplingN(0), mBounds(0)
 #endif
 {
     mMeasuredWarmupTs.tv_sec = 0;
     mMeasuredWarmupTs.tv_nsec = 0;
+#ifdef FAST_THREAD_STATISTICS
+    increaseSamplingN(1);
+#endif
 }
 
 FastThreadDumpState::~FastThreadDumpState()
 {
 }
 
+#ifdef FAST_THREAD_STATISTICS
+void FastThreadDumpState::increaseSamplingN(uint32_t samplingN)
+{
+    if (samplingN <= mSamplingN || samplingN > kSamplingN || roundup(samplingN) != samplingN) {
+        return;
+    }
+    uint32_t additional = samplingN - mSamplingN;
+    // sample arrays aren't accessed atomically with respect to the bounds,
+    // so clearing reduces chance for dumpsys to read random uninitialized samples
+    memset(&mMonotonicNs[mSamplingN], 0, sizeof(mMonotonicNs[0]) * additional);
+    memset(&mLoadNs[mSamplingN], 0, sizeof(mLoadNs[0]) * additional);
+#ifdef CPU_FREQUENCY_STATISTICS
+    memset(&mCpukHz[mSamplingN], 0, sizeof(mCpukHz[0]) * additional);
+#endif
+    mSamplingN = samplingN;
+}
+#endif
+
 }   // android
diff --git a/services/audioflinger/FastThreadDumpState.h b/services/audioflinger/FastThreadDumpState.h
index 17afbe5..1ce0914 100644
--- a/services/audioflinger/FastThreadDumpState.h
+++ b/services/audioflinger/FastThreadDumpState.h
@@ -22,7 +22,12 @@
 
 namespace android {
 
-// FIXME extract common part of comment at FastMixerDumpState
+// The FastThreadDumpState keeps a cache of FastThread statistics that can be logged by dumpsys.
+// Each individual native word-sized field is accessed atomically.  But the
+// overall structure is non-atomic, that is there may be an inconsistency between fields.
+// No barriers or locks are used for either writing or reading.
+// Only POD types are permitted, and the contents shouldn't be trusted (i.e. do range checks).
+// It has a different lifetime than the FastThread, and so it can't be a member of FastThread.
 struct FastThreadDumpState {
     FastThreadDumpState();
     /*virtual*/ ~FastThreadDumpState();
@@ -33,12 +38,15 @@
     struct timespec mMeasuredWarmupTs;  // measured warmup time
     uint32_t mWarmupCycles;     // number of loop cycles required to warmup
 
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
     // Recently collected samples of per-cycle monotonic time, thread CPU time, and CPU frequency.
     // kSamplingN is max size of sampling frame (statistics), and must be a power of 2 <= 0x8000.
     // The sample arrays are virtually allocated based on this compile-time constant,
     // but are only initialized and used based on the runtime parameter mSamplingN.
     static const uint32_t kSamplingN = 0x8000;
+    // Compile-time constant for a "low RAM device", must be a power of 2 <= kSamplingN.
+    // This value was chosen such that each array uses 1 small page (4 Kbytes).
+    static const uint32_t kSamplingNforLowRamDevice = 0x400;
     // Corresponding runtime maximum size of sample arrays, must be a power of 2 <= kSamplingN.
     uint32_t mSamplingN;
     // The bounds define the interval of valid samples, and are represented as follows:
@@ -52,6 +60,9 @@
 #ifdef CPU_FREQUENCY_STATISTICS
     uint32_t mCpukHz[kSamplingN];       // absolute CPU clock frequency in kHz, bits 0-3 are CPU#
 #endif
+
+    // Increase sampling window after construction, must be a power of 2 <= kSamplingN
+    void    increaseSamplingN(uint32_t samplingN);
 #endif
 
 };  // struct FastThreadDumpState
diff --git a/services/audioflinger/FastThreadState.cpp b/services/audioflinger/FastThreadState.cpp
index e6cf85c..ad5f31f 100644
--- a/services/audioflinger/FastThreadState.cpp
+++ b/services/audioflinger/FastThreadState.cpp
@@ -29,4 +29,16 @@
 {
 }
 
+// static
+const char *FastThreadState::commandToString(FastThreadState::Command command)
+{
+    switch (command) {
+    case FastThreadState::INITIAL:      return "INITIAL";
+    case FastThreadState::HOT_IDLE:     return "HOT_IDLE";
+    case FastThreadState::COLD_IDLE:    return "COLD_IDLE";
+    case FastThreadState::EXIT:         return "EXIT";
+    }
+    return NULL;
+}
+
 }   // namespace android
diff --git a/services/audioflinger/FastThreadState.h b/services/audioflinger/FastThreadState.h
index 011921d..f18f846 100644
--- a/services/audioflinger/FastThreadState.h
+++ b/services/audioflinger/FastThreadState.h
@@ -46,6 +46,8 @@
     FastThreadDumpState* mDumpState; // if non-NULL, then update dump state periodically
     NBLog::Writer* mNBLogWriter; // non-blocking logger
 
+    // returns NULL if command belongs to a subclass
+    static const char *commandToString(Command command);
 };  // struct FastThreadState
 
 }   // android
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 4f0c6b1..efbdcff 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -694,4 +694,4 @@
 }
 
 
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 40ab0af..7451245 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3116,8 +3116,10 @@
 #endif
             }
             state->mCommand = FastMixerState::MIX_WRITE;
+#ifdef FAST_THREAD_STATISTICS
             mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
-                    FastMixerDumpState::kSamplingNforLowRamDevice : FastMixerDumpState::kSamplingN);
+                FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN);
+#endif
             sq->end();
             sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
             if (kUseFastMixer == FastMixer_Dynamic) {
@@ -5386,8 +5388,8 @@
                 state->mCommand = FastCaptureState::READ_WRITE;
 #if 0   // FIXME
                 mFastCaptureDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
-                        FastCaptureDumpState::kSamplingNforLowRamDevice :
-                        FastMixerDumpState::kSamplingN);
+                        FastThreadDumpState::kSamplingNforLowRamDevice :
+                        FastThreadDumpState::kSamplingN);
 #endif
                 didModify = true;
             }
@@ -6520,4 +6522,4 @@
     config->ext.mix.usecase.source = mAudioSource;
 }
 
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index fa0beaa..8329be4 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2182,4 +2182,4 @@
     mProxy->releaseBuffer(buffer);
 }
 
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b48dc80..53ec0f6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4467,7 +4467,7 @@
             if (device) break;
             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
             if (device) break;
-            if (mPhoneState != AUDIO_MODE_IN_CALL) {
+            if (!isInCall()) {
                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
                 if (device) break;
                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 00a70eb..8e894cd 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "CameraFlashlight"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
-#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -32,16 +32,21 @@
 
 namespace android {
 
+/////////////////////////////////////////////////////////////////////
+// CameraFlashlight implementation begins
+// used by camera service to control flashflight.
+/////////////////////////////////////////////////////////////////////
 CameraFlashlight::CameraFlashlight(CameraModule& cameraModule,
         const camera_module_callbacks_t& callbacks) :
         mCameraModule(&cameraModule),
-        mCallbacks(&callbacks) {
+        mCallbacks(&callbacks),
+        mFlashlightMapInitialized(false) {
 }
 
 CameraFlashlight::~CameraFlashlight() {
 }
 
-status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) {
+status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
     ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
             cameraId.string());
     if (mFlashControl != NULL) {
@@ -52,7 +57,7 @@
 
     if (mCameraModule->getRawModule()->module_api_version >=
             CAMERA_MODULE_API_VERSION_2_4) {
-        mFlashControl = new FlashControl(*mCameraModule, *mCallbacks);
+        mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks);
         if (mFlashControl == NULL) {
             ALOGV("%s: cannot create flash control for module api v2.4+",
                      __FUNCTION__);
@@ -67,7 +72,7 @@
             res = mCameraModule->getCameraInfo(
                     atoi(String8(cameraId).string()), &info);
             if (res) {
-                ALOGV("%s: failed to get camera info for camera %s",
+                ALOGE("%s: failed to get camera info for camera %s",
                         __FUNCTION__, cameraId.string());
                 return res;
             }
@@ -83,18 +88,19 @@
             }
 
             mFlashControl = flashControl;
-        }
-        else {
-            // todo: implement for device api 1
-            return INVALID_OPERATION;
+        } else {
+            mFlashControl =
+                    new CameraHardwareInterfaceFlashControl(*mCameraModule,
+                                                            *mCallbacks);
         }
     }
 
     return OK;
 }
 
-status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled) {
-    if (!mCameraModule) {
+status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
+    if (!mFlashlightMapInitialized) {
+        ALOGE("%s: findFlashUnits() must be called before this method.");
         return NO_INIT;
     }
 
@@ -105,6 +111,10 @@
     Mutex::Autolock l(mLock);
 
     if (mFlashControl == NULL) {
+        if (enabled == false) {
+            return OK;
+        }
+
         res = createFlashlightControl(cameraId);
         if (res) {
             return res;
@@ -130,88 +140,169 @@
     return res;
 }
 
-bool CameraFlashlight::hasFlashUnit(const String16& cameraId) {
+status_t CameraFlashlight::findFlashUnits() {
+    Mutex::Autolock l(mLock);
+    status_t res;
+    int32_t numCameras = mCameraModule->getNumberOfCameras();
+
+    mHasFlashlightMap.clear();
+    mFlashlightMapInitialized = false;
+
+    for (int32_t i = 0; i < numCameras; i++) {
+        bool hasFlash = false;
+        String8 id = String8::format("%d", i);
+
+        res = createFlashlightControl(id);
+        if (res) {
+            ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
+                    id.string());
+        } else {
+            res = mFlashControl->hasFlashUnit(id, &hasFlash);
+            if (res == -EUSERS || res == -EBUSY) {
+                ALOGE("%s: failed to check if camera %s has a flash unit. Some "
+                        "camera devices may be opened", __FUNCTION__,
+                        id.string());
+                return res;
+            } else if (res) {
+                ALOGE("%s: failed to check if camera %s has a flash unit. %s"
+                        " (%d)", __FUNCTION__, id.string(), strerror(-res),
+                        res);
+            }
+
+            mFlashControl.clear();
+        }
+        mHasFlashlightMap.add(id, hasFlash);
+    }
+
+    mFlashlightMapInitialized = true;
+    return OK;
+}
+
+bool CameraFlashlight::hasFlashUnit(const String8& cameraId) {
     status_t res;
 
     Mutex::Autolock l(mLock);
-
-    if (mFlashControl == NULL) {
-        res = createFlashlightControl(cameraId);
-        if (res) {
-            ALOGE("%s: failed to create flash control for %s ",
-                    __FUNCTION__, cameraId.string());
-            return false;
-        }
-    }
-
-    bool flashUnit = false;
-
-    // if flash control already exists, querying if a camera device has a flash
-    // unit may fail if it's module v1
-    res = mFlashControl->hasFlashUnit(cameraId, &flashUnit);
-    if (res == BAD_INDEX) {
-        // need to close the flash control before query.
-        mFlashControl.clear();
-        res = createFlashlightControl(cameraId);
-        if (res) {
-            ALOGE("%s: failed to create flash control for %s ", __FUNCTION__,
-                    cameraId.string());
-            return false;
-        }
-        res = mFlashControl->hasFlashUnit(cameraId, &flashUnit);
-        if (res) {
-            flashUnit = false;
-        }
-    }
-
-    return flashUnit;
+    return hasFlashUnitLocked(cameraId);
 }
 
-status_t CameraFlashlight::prepareDeviceOpen() {
+bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
+    if (!mFlashlightMapInitialized) {
+        ALOGE("%s: findFlashUnits() must be called before this method.");
+        return false;
+    }
+
+    ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
+    if (index == NAME_NOT_FOUND) {
+        ALOGE("%s: camera %s not present when findFlashUnits() was called",
+                __FUNCTION__, cameraId.string());
+        return false;
+    }
+
+    return mHasFlashlightMap.valueAt(index);
+}
+
+status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
     ALOGV("%s: prepare for device open", __FUNCTION__);
 
     Mutex::Autolock l(mLock);
+    if (!mFlashlightMapInitialized) {
+        ALOGE("%s: findFlashUnits() must be called before this method.");
+        return NO_INIT;
+    }
 
-    if (mCameraModule && mCameraModule->getRawModule()->module_api_version <
+    if (mCameraModule->getRawModule()->module_api_version <
             CAMERA_MODULE_API_VERSION_2_4) {
         // framework is going to open a camera device, all flash light control
         // should be closed for backward compatible support.
-        if (mFlashControl != NULL) {
-            mFlashControl.clear();
+        mFlashControl.clear();
+
+        if (mOpenedCameraIds.size() == 0) {
+            // notify torch unavailable for all cameras with a flash
+            int numCameras = mCameraModule->getNumberOfCameras();
+            for (int i = 0; i < numCameras; i++) {
+                if (hasFlashUnitLocked(String8::format("%d", i))) {
+                    mCallbacks->torch_mode_status_change(mCallbacks,
+                            String8::format("%d", i).string(),
+                            TORCH_MODE_STATUS_NOT_AVAILABLE);
+                }
+            }
         }
+
+        // close flash control that may be opened by calling hasFlashUnitLocked.
+        mFlashControl.clear();
+    }
+
+    if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) {
+        mOpenedCameraIds.add(cameraId);
     }
 
     return OK;
 }
 
+status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
+    ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string());
+
+    Mutex::Autolock l(mLock);
+    if (!mFlashlightMapInitialized) {
+        ALOGE("%s: findFlashUnits() must be called before this method.");
+        return NO_INIT;
+    }
+
+    ssize_t index = mOpenedCameraIds.indexOf(cameraId);
+    if (index == NAME_NOT_FOUND) {
+        ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
+                cameraId.string());
+    } else {
+        mOpenedCameraIds.removeAt(index);
+    }
+
+    // Cannot do anything until all cameras are closed.
+    if (mOpenedCameraIds.size() != 0)
+        return OK;
+
+    if (mCameraModule->getRawModule()->module_api_version <
+            CAMERA_MODULE_API_VERSION_2_4) {
+        // notify torch available for all cameras with a flash
+        int numCameras = mCameraModule->getNumberOfCameras();
+        for (int i = 0; i < numCameras; i++) {
+            if (hasFlashUnitLocked(String8::format("%d", i))) {
+                mCallbacks->torch_mode_status_change(mCallbacks,
+                        String8::format("%d", i).string(),
+                        TORCH_MODE_STATUS_AVAILABLE_OFF);
+            }
+        }
+    }
+
+    return OK;
+}
+// CameraFlashlight implementation ends
+
 
 FlashControlBase::~FlashControlBase() {
 }
 
-
-FlashControl::FlashControl(CameraModule& cameraModule,
+/////////////////////////////////////////////////////////////////////
+// ModuleFlashControl implementation begins
+// Flash control for camera module v2.4 and above.
+/////////////////////////////////////////////////////////////////////
+ModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule,
         const camera_module_callbacks_t& callbacks) :
     mCameraModule(&cameraModule) {
 }
 
-FlashControl::~FlashControl() {
+ModuleFlashControl::~ModuleFlashControl() {
 }
 
-status_t FlashControl::hasFlashUnit(const String16& cameraId, bool *hasFlash) {
+status_t ModuleFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) {
     if (!hasFlash) {
         return BAD_VALUE;
     }
 
     *hasFlash = false;
-
     Mutex::Autolock l(mLock);
 
-    if (!mCameraModule) {
-        return NO_INIT;
-    }
-
     camera_info info;
-    status_t res = mCameraModule->getCameraInfo(atoi(String8(cameraId).string()),
+    status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()),
             &info);
     if (res != 0) {
         return res;
@@ -228,33 +319,31 @@
     return OK;
 }
 
-status_t FlashControl::setTorchMode(const String16& cameraId, bool enabled) {
+status_t ModuleFlashControl::setTorchMode(const String8& cameraId, bool enabled) {
     ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
             cameraId.string(), enabled);
 
     Mutex::Autolock l(mLock);
-    if (!mCameraModule) {
-        return NO_INIT;
-    }
-
-    return mCameraModule->setTorchMode(String8(cameraId).string(), enabled);
+    return mCameraModule->setTorchMode(cameraId.string(), enabled);
 }
+// ModuleFlashControl implementation ends
 
+/////////////////////////////////////////////////////////////////////
+// CameraDeviceClientFlashControl implementation begins
+// Flash control for camera module <= v2.3 and camera HAL v2-v3
+/////////////////////////////////////////////////////////////////////
 CameraDeviceClientFlashControl::CameraDeviceClientFlashControl(
         CameraModule& cameraModule,
         const camera_module_callbacks_t& callbacks) :
         mCameraModule(&cameraModule),
         mCallbacks(&callbacks),
         mTorchEnabled(false),
-        mMetadata(NULL) {
+        mMetadata(NULL),
+        mStreaming(false) {
 }
 
 CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() {
-    if (mDevice != NULL) {
-        mDevice->flush();
-        mDevice->deleteStream(mStreamId);
-        mDevice.clear();
-    }
+    disconnectCameraDevice();
     if (mMetadata) {
         delete mMetadata;
     }
@@ -269,13 +358,13 @@
             ALOGV("%s: notify the framework that torch was turned off",
                     __FUNCTION__);
             mCallbacks->torch_mode_status_change(mCallbacks,
-                    String8(mCameraId).string(), TORCH_MODE_STATUS_OFF);
+                    mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
         }
     }
 }
 
-status_t CameraDeviceClientFlashControl::initializeSurface(int32_t width,
-        int32_t height) {
+status_t CameraDeviceClientFlashControl::initializeSurface(
+        sp<CameraDeviceBase> &device, int32_t width, int32_t height) {
     status_t res;
     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
 
@@ -295,27 +384,16 @@
         return res;
     }
 
-    bool useAsync = false;
-    int32_t consumerUsage;
-    res = mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage);
-    if (res) {
-        return res;
-    }
-
-    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
-        useAsync = true;
-    }
-
-    mAnw = new Surface(mProducer, useAsync);
+    mAnw = new Surface(mProducer, /*useAsync*/ true);
     if (mAnw == NULL) {
         return NO_MEMORY;
     }
-    res = mDevice->createStream(mAnw, width, height, format, &mStreamId);
+    res = device->createStream(mAnw, width, height, format, &mStreamId);
     if (res) {
         return res;
     }
 
-    res = mDevice->configureStreams();
+    res = device->configureStreams();
     if (res) {
         return res;
     }
@@ -342,7 +420,21 @@
             int32_t ww = streamConfigs.data.i32[i + 1];
             int32_t hh = streamConfigs.data.i32[i + 2];
 
-            if (w* h > ww * hh) {
+            if (w * h > ww * hh) {
+                w = ww;
+                h = hh;
+            }
+        }
+    }
+
+    // if stream configuration is not found, try available processed sizes.
+    if (streamConfigs.count == 0) {
+        camera_metadata_entry availableProcessedSizes =
+            metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+        for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
+            int32_t ww = availableProcessedSizes.data.i32[i];
+            int32_t hh = availableProcessedSizes.data.i32[i + 1];
+            if (w * h > ww * hh) {
                 w = ww;
                 h = hh;
             }
@@ -360,24 +452,24 @@
 }
 
 status_t CameraDeviceClientFlashControl::connectCameraDevice(
-        const String16& cameraId) {
-    String8 id = String8(cameraId);
+        const String8& cameraId) {
     camera_info info;
-    status_t res = mCameraModule->getCameraInfo(atoi(id.string()), &info);
+    status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info);
     if (res != 0) {
         ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__,
-                mCameraId.string());
+                cameraId.string());
         return res;
     }
 
-    mDevice = CameraDeviceFactory::createDevice(atoi(id.string()));
-    if (mDevice == NULL) {
+    sp<CameraDeviceBase> device =
+            CameraDeviceFactory::createDevice(atoi(cameraId.string()));
+    if (device == NULL) {
         return NO_MEMORY;
     }
 
-    res = mDevice->initialize(mCameraModule);
+    res = device->initialize(mCameraModule);
     if (res) {
-        goto fail;
+        return res;
     }
 
     int32_t width, height;
@@ -385,22 +477,30 @@
     if (res) {
         return res;
     }
-    res = initializeSurface(width, height);
+    res = initializeSurface(device, width, height);
     if (res) {
-        goto fail;
+        return res;
     }
 
     mCameraId = cameraId;
+    mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1);
+    mDevice = device;
 
     return OK;
+}
 
-fail:
-    mDevice.clear();
-    return res;
+status_t CameraDeviceClientFlashControl::disconnectCameraDevice() {
+    if (mDevice != NULL) {
+        mDevice->disconnect();
+        mDevice.clear();
+    }
+
+    return OK;
 }
 
 
-status_t CameraDeviceClientFlashControl::hasFlashUnit(const String16& cameraId,
+
+status_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId,
         bool *hasFlash) {
     ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__,
             cameraId.string());
@@ -411,19 +511,14 @@
 }
 
 status_t CameraDeviceClientFlashControl::hasFlashUnitLocked(
-        const String16& cameraId, bool *hasFlash) {
-    if (!mCameraModule) {
-        ALOGE("%s: camera module is NULL", __FUNCTION__);
-        return NO_INIT;
-    }
-
+        const String8& cameraId, bool *hasFlash) {
     if (!hasFlash) {
         return BAD_VALUE;
     }
 
     camera_info info;
     status_t res = mCameraModule->getCameraInfo(
-            atoi(String8(cameraId).string()), &info);
+            atoi(cameraId.string()), &info);
     if (res != 0) {
         ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__,
                 cameraId.string());
@@ -441,7 +536,7 @@
     return OK;
 }
 
-status_t CameraDeviceClientFlashControl::submitTorchRequest(bool enabled) {
+status_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() {
     status_t res;
 
     if (mMetadata == NULL) {
@@ -456,27 +551,29 @@
         }
     }
 
-    uint8_t torchOn = enabled ? ANDROID_FLASH_MODE_TORCH :
-                                ANDROID_FLASH_MODE_OFF;
-
+    uint8_t torchOn = ANDROID_FLASH_MODE_TORCH;
     mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1);
     mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1);
 
+    uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
+    mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
+
     int32_t requestId = 0;
     mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1);
 
-    List<const CameraMetadata> metadataRequestList;
-    metadataRequestList.push_back(*mMetadata);
-
-    int64_t lastFrameNumber = 0;
-    res = mDevice->captureList(metadataRequestList, &lastFrameNumber);
-
+    if (mStreaming) {
+        res = mDevice->setStreamingRequest(*mMetadata);
+    } else {
+        res = mDevice->capture(*mMetadata);
+    }
     return res;
 }
 
 
+
+
 status_t CameraDeviceClientFlashControl::setTorchMode(
-        const String16& cameraId, bool enabled) {
+        const String8& cameraId, bool enabled) {
     bool hasFlash = false;
 
     Mutex::Autolock l(mLock);
@@ -499,6 +596,13 @@
     } else if (mDevice == NULL || cameraId != mCameraId) {
         // disabling the torch mode of an un-opened or different device.
         return OK;
+    } else {
+        // disabling the torch mode of currently opened device
+        disconnectCameraDevice();
+        mTorchEnabled = false;
+        mCallbacks->torch_mode_status_change(mCallbacks,
+            cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+        return OK;
     }
 
     if (mDevice == NULL) {
@@ -508,13 +612,263 @@
         }
     }
 
-    res = submitTorchRequest(enabled);
+    res = submitTorchEnabledRequest();
     if (res) {
         return res;
     }
 
-    mTorchEnabled = enabled;
+    mTorchEnabled = true;
+    mCallbacks->torch_mode_status_change(mCallbacks,
+            cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
     return OK;
 }
+// CameraDeviceClientFlashControl implementation ends
+
+
+/////////////////////////////////////////////////////////////////////
+// CameraHardwareInterfaceFlashControl implementation begins
+// Flash control for camera module <= v2.3 and camera HAL v1
+/////////////////////////////////////////////////////////////////////
+CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
+        CameraModule& cameraModule,
+        const camera_module_callbacks_t& callbacks) :
+        mCameraModule(&cameraModule),
+        mCallbacks(&callbacks),
+        mTorchEnabled(false) {
+
+}
+
+CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
+    disconnectCameraDevice();
+
+    mAnw.clear();
+    mSurfaceTexture.clear();
+    mProducer.clear();
+    mConsumer.clear();
+
+    if (mTorchEnabled) {
+        if (mCallbacks) {
+            ALOGV("%s: notify the framework that torch was turned off",
+                    __FUNCTION__);
+            mCallbacks->torch_mode_status_change(mCallbacks,
+                    mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+        }
+    }
+}
+
+status_t CameraHardwareInterfaceFlashControl::setTorchMode(
+        const String8& cameraId, bool enabled) {
+    Mutex::Autolock l(mLock);
+
+    // pre-check
+    status_t res;
+    if (enabled) {
+        bool hasFlash = false;
+        res = hasFlashUnitLocked(cameraId, &hasFlash);
+        // invalid camera?
+        if (res) {
+            // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
+            // another camera device.
+            return res == BAD_INDEX ? BAD_INDEX : -EINVAL;
+        }
+        // no flash unit?
+        if (!hasFlash) {
+            return -ENOSYS;
+        }
+    } else if (mDevice == NULL || cameraId != mCameraId) {
+        // disabling the torch mode of an un-opened or different device.
+        return OK;
+    } else {
+        // disabling the torch mode of currently opened device
+        disconnectCameraDevice();
+        mTorchEnabled = false;
+        mCallbacks->torch_mode_status_change(mCallbacks,
+            cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+        return OK;
+    }
+
+    res = startPreviewAndTorch();
+    if (res) {
+        return res;
+    }
+
+    mTorchEnabled = true;
+    mCallbacks->torch_mode_status_change(mCallbacks,
+            cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
+    return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
+        const String8& cameraId, bool *hasFlash) {
+    Mutex::Autolock l(mLock);
+    return hasFlashUnitLocked(cameraId, hasFlash);
+}
+
+status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
+        const String8& cameraId, bool *hasFlash) {
+    if (!hasFlash) {
+        return BAD_VALUE;
+    }
+
+    status_t res;
+    if (mDevice == NULL) {
+        res = connectCameraDevice(cameraId);
+        if (res) {
+            return res;
+        }
+    }
+
+    if (cameraId != mCameraId) {
+        return BAD_INDEX;
+    }
+
+    const char *flashMode =
+            mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
+    if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
+        *hasFlash = true;
+    } else {
+        *hasFlash = false;
+    }
+
+    return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() {
+    status_t res = OK;
+    res = mDevice->startPreview();
+    if (res) {
+        ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+        return res;
+    }
+
+    mParameters.set(CameraParameters::KEY_FLASH_MODE,
+            CameraParameters::FLASH_MODE_TORCH);
+
+    return mDevice->setParameters(mParameters);
+}
+
+status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize(
+        int32_t *width, int32_t *height) {
+    if (!width || !height) {
+        return BAD_VALUE;
+    }
+
+    int32_t w = INT32_MAX;
+    int32_t h = 1;
+    Vector<Size> sizes;
+
+    mParameters.getSupportedPreviewSizes(sizes);
+    for (size_t i = 0; i < sizes.size(); i++) {
+        Size s = sizes[i];
+        if (w * h > s.width * s.height) {
+            w = s.width;
+            h = s.height;
+        }
+    }
+
+    if (w == INT32_MAX) {
+        return NAME_NOT_FOUND;
+    }
+
+    *width = w;
+    *height = h;
+
+    return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow(
+        sp<CameraHardwareInterface> device, int32_t width, int32_t height) {
+    status_t res;
+    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
+
+    mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL,
+            true, true);
+    if (mSurfaceTexture == NULL) {
+        return NO_MEMORY;
+    }
+
+    int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    res = mSurfaceTexture->setDefaultBufferSize(width, height);
+    if (res) {
+        return res;
+    }
+    res = mSurfaceTexture->setDefaultBufferFormat(format);
+    if (res) {
+        return res;
+    }
+
+    mAnw = new Surface(mProducer, /*useAsync*/ true);
+    if (mAnw == NULL) {
+        return NO_MEMORY;
+    }
+
+    res = native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
+    if (res) {
+        ALOGE("%s: Unable to connect to native window", __FUNCTION__);
+        return res;
+    }
+
+    return device->setPreviewWindow(mAnw);
+}
+
+status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
+        const String8& cameraId) {
+    sp<CameraHardwareInterface> device =
+            new CameraHardwareInterface(cameraId.string());
+
+    status_t res = device->initialize(mCameraModule);
+    if (res) {
+        ALOGE("%s: initializing camera %s failed", __FUNCTION__,
+                cameraId.string());
+        return res;
+    }
+
+    // need to set __get_memory in set_callbacks().
+    device->setCallbacks(NULL, NULL, NULL, NULL);
+
+    mParameters = device->getParameters();
+
+    int32_t width, height;
+    res = getSmallestSurfaceSize(&width, &height);
+    if (res) {
+        ALOGE("%s: failed to get smallest surface size for camera %s",
+                __FUNCTION__, cameraId.string());
+        return res;
+    }
+
+    res = initializePreviewWindow(device, width, height);
+    if (res) {
+        ALOGE("%s: failed to initialize preview window for camera %s",
+                __FUNCTION__, cameraId.string());
+        return res;
+    }
+
+    mCameraId = cameraId;
+    mDevice = device;
+    return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() {
+    if (mDevice == NULL) {
+        return OK;
+    }
+
+    mParameters.set(CameraParameters::KEY_FLASH_MODE,
+            CameraParameters::FLASH_MODE_OFF);
+    mDevice->setParameters(mParameters);
+    mDevice->stopPreview();
+    status_t res = native_window_api_disconnect(mAnw.get(),
+            NATIVE_WINDOW_API_CAMERA);
+    if (res) {
+        ALOGW("%s: native_window_api_disconnect failed: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+    }
+    mDevice->setPreviewWindow(NULL);
+    mDevice->release();
+
+    return OK;
+}
+// CameraHardwareInterfaceFlashControl implementation ends
 
 }
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index a0de0b0..30f01f0 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -19,9 +19,11 @@
 
 #include "hardware/camera_common.h"
 #include "utils/KeyedVector.h"
+#include "utils/SortedVector.h"
 #include "gui/GLConsumer.h"
 #include "gui/Surface.h"
 #include "common/CameraDeviceBase.h"
+#include "device1/CameraHardwareInterface.h"
 
 namespace android {
 
@@ -37,11 +39,11 @@
         // cause the torch mode to be turned off in HAL v1 devices. If
         // previously-on torch mode is turned off,
         // callbacks.torch_mode_status_change() should be invoked.
-        virtual status_t hasFlashUnit(const String16& cameraId,
+        virtual status_t hasFlashUnit(const String8& cameraId,
                     bool *hasFlash) = 0;
 
         // set the torch mode to on or off.
-        virtual status_t setTorchMode(const String16& cameraId,
+        virtual status_t setTorchMode(const String8& cameraId,
                     bool enabled) = 0;
 };
 
@@ -54,43 +56,61 @@
                 const camera_module_callbacks_t& callbacks);
         virtual ~CameraFlashlight();
 
-        // set the torch mode to on or off.
-        status_t setTorchMode(const String16& cameraId, bool enabled);
+        // Find all flash units. This must be called before other methods. All
+        // camera devices must be closed when it's called because HAL v1 devices
+        // need to be opened to query available flash modes.
+        status_t findFlashUnits();
 
-        // Whether a camera device has a flash unit. Calling this function may
-        // cause the torch mode to be turned off in HAL v1 devices.
-        bool hasFlashUnit(const String16& cameraId);
+        // Whether a camera device has a flash unit. Before findFlashUnits() is
+        // called, this function always returns false.
+        bool hasFlashUnit(const String8& cameraId);
+
+        // set the torch mode to on or off.
+        status_t setTorchMode(const String8& cameraId, bool enabled);
 
         // Notify CameraFlashlight that camera service is going to open a camera
         // device. CameraFlashlight will free the resources that may cause the
         // camera open to fail. Camera service must call this function before
         // opening a camera device.
-        status_t prepareDeviceOpen();
+        status_t prepareDeviceOpen(const String8& cameraId);
+
+        // Notify CameraFlashlight that camera service has closed a camera
+        // device. CameraFlashlight may invoke callbacks for torch mode
+        // available depending on the implementation.
+        status_t deviceClosed(const String8& cameraId);
 
     private:
         // create flashlight control based on camera module API and camera
         // device API versions.
-        status_t createFlashlightControl(const String16& cameraId);
+        status_t createFlashlightControl(const String8& cameraId);
+
+        // mLock should be locked.
+        bool hasFlashUnitLocked(const String8& cameraId);
 
         sp<FlashControlBase> mFlashControl;
         CameraModule *mCameraModule;
         const camera_module_callbacks_t *mCallbacks;
+        SortedVector<String8> mOpenedCameraIds;
 
-        Mutex mLock;
+        // camera id -> if it has a flash unit
+        KeyedVector<String8, bool> mHasFlashlightMap;
+        bool mFlashlightMapInitialized;
+
+        Mutex mLock; // protect CameraFlashlight API
 };
 
 /**
  * Flash control for camera module v2.4 and above.
  */
-class FlashControl : public FlashControlBase {
+class ModuleFlashControl : public FlashControlBase {
     public:
-        FlashControl(CameraModule& cameraModule,
+        ModuleFlashControl(CameraModule& cameraModule,
                 const camera_module_callbacks_t& callbacks);
-        virtual ~FlashControl();
+        virtual ~ModuleFlashControl();
 
         // FlashControlBase
-        status_t hasFlashUnit(const String16& cameraId, bool *hasFlash);
-        status_t setTorchMode(const String16& cameraId, bool enabled);
+        status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
+        status_t setTorchMode(const String8& cameraId, bool enabled);
 
     private:
         CameraModule *mCameraModule;
@@ -108,30 +128,38 @@
         virtual ~CameraDeviceClientFlashControl();
 
         // FlashControlBase
-        status_t setTorchMode(const String16& cameraId, bool enabled);
-        status_t hasFlashUnit(const String16& cameraId, bool *hasFlash);
+        status_t setTorchMode(const String8& cameraId, bool enabled);
+        status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
 
     private:
         // connect to a camera device
-        status_t connectCameraDevice(const String16& cameraId);
+        status_t connectCameraDevice(const String8& cameraId);
+        // disconnect and free mDevice
+        status_t disconnectCameraDevice();
 
         // initialize a surface
-        status_t initializeSurface(int32_t width, int32_t height);
+        status_t initializeSurface(sp<CameraDeviceBase>& device, int32_t width,
+                int32_t height);
 
-        // submit a request with the given torch mode
-        status_t submitTorchRequest(bool enabled);
+        // submit a request to enable the torch mode
+        status_t submitTorchEnabledRequest();
 
         // get the smallest surface size of IMPLEMENTATION_DEFINED
         status_t getSmallestSurfaceSize(const camera_info& info, int32_t *width,
                     int32_t *height);
 
-        status_t hasFlashUnitLocked(const String16& cameraId, bool *hasFlash);
+        // protected by mLock
+        status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
 
         CameraModule *mCameraModule;
         const camera_module_callbacks_t *mCallbacks;
-        String16 mCameraId;
+        String8 mCameraId;
         bool mTorchEnabled;
         CameraMetadata *mMetadata;
+        // WORKAROUND: will be set to true for HAL v2 devices where
+        // setStreamingRequest() needs to be call for torch mode settings to
+        // take effect.
+        bool mStreaming;
 
         sp<CameraDeviceBase> mDevice;
 
@@ -144,6 +172,54 @@
         Mutex mLock;
 };
 
+/**
+ * Flash control for camera module <= v2.3 and camera HAL v1
+ */
+class CameraHardwareInterfaceFlashControl : public FlashControlBase {
+    public:
+        CameraHardwareInterfaceFlashControl(CameraModule& cameraModule,
+                const camera_module_callbacks_t& callbacks);
+        virtual ~CameraHardwareInterfaceFlashControl();
+
+        // FlashControlBase
+        status_t setTorchMode(const String8& cameraId, bool enabled);
+        status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
+
+    private:
+        // connect to a camera device
+        status_t connectCameraDevice(const String8& cameraId);
+
+        // disconnect and free mDevice
+        status_t disconnectCameraDevice();
+
+        // initialize the preview window
+        status_t initializePreviewWindow(sp<CameraHardwareInterface> device,
+                int32_t width, int32_t height);
+
+        // start preview and enable torch
+        status_t startPreviewAndTorch();
+
+        // get the smallest surface
+        status_t getSmallestSurfaceSize(int32_t *width, int32_t *height);
+
+        // protected by mLock
+        status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
+
+        CameraModule *mCameraModule;
+        const camera_module_callbacks_t *mCallbacks;
+        sp<CameraHardwareInterface> mDevice;
+        String8 mCameraId;
+        CameraParameters mParameters;
+        bool mTorchEnabled;
+
+        sp<IGraphicBufferProducer> mProducer;
+        sp<IGraphicBufferConsumer>  mConsumer;
+        sp<GLConsumer> mSurfaceTexture;
+        sp<ANativeWindow> mAnw;
+
+        Mutex mLock;
+};
+
 } // namespace android
 
 #endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index d65ac21..6f37f16 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -101,14 +101,14 @@
 
     ICameraServiceListener::TorchStatus status;
     switch (new_status) {
-        case TORCH_MODE_STATUS_AVAILABLE:
-            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE;
-            break;
-        case TORCH_MODE_STATUS_RESOURCE_BUSY:
+        case TORCH_MODE_STATUS_NOT_AVAILABLE:
             status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
             break;
-        case TORCH_MODE_STATUS_OFF:
-            status = ICameraServiceListener::TORCH_STATUS_OFF;
+        case TORCH_MODE_STATUS_AVAILABLE_OFF:
+            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
+            break;
+        case TORCH_MODE_STATUS_AVAILABLE_ON:
+            status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
             break;
         default:
             ALOGE("Unknown torch status %d", new_status);
@@ -116,7 +116,7 @@
     }
 
     cs->onTorchStatusChanged(
-        String16(camera_id),
+        String8(camera_id),
         status);
 }
 } // extern "C"
@@ -156,23 +156,29 @@
     }
     else {
         mModule = new CameraModule(rawModule);
-        mFlashlight = new CameraFlashlight(*mModule, *this);
-
         const hw_module_t *common = mModule->getRawModule();
-        ALOGI("Loaded \"%s\" camera module", common->name);
+        ALOGI("Loaded \"%s\" cameraCa module", common->name);
         mNumberOfCameras = mModule->getNumberOfCameras();
         if (mNumberOfCameras > MAX_CAMERAS) {
             ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
                     mNumberOfCameras, MAX_CAMERAS);
             mNumberOfCameras = MAX_CAMERAS;
         }
+
+        mFlashlight = new CameraFlashlight(*mModule, *this);
+        status_t res = mFlashlight->findFlashUnits();
+        if (res) {
+            // impossible because we haven't open any camera devices.
+            ALOGE("failed to find flash units.");
+        }
+
         for (int i = 0; i < mNumberOfCameras; i++) {
             setCameraFree(i);
 
-            String16 cameraName = String16(String8::format("%d", i));
+            String8 cameraName = String8::format("%d", i);
             if (mFlashlight->hasFlashUnit(cameraName)) {
                 mTorchStatusMap.add(cameraName,
-                        ICameraServiceListener::TORCH_STATUS_AVAILABLE);
+                        ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
             }
         }
 
@@ -207,7 +213,7 @@
 void CameraService::onDeviceStatusChanged(int cameraId,
                                           int newStatus)
 {
-    ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
+    ALOGV("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
           cameraId, newStatus);
 
     if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
@@ -268,24 +274,30 @@
 
 }
 
-void CameraService::onTorchStatusChanged(const String16& cameraId,
+void CameraService::onTorchStatusChanged(const String8& cameraId,
         ICameraServiceListener::TorchStatus newStatus) {
     Mutex::Autolock al(mTorchStatusMutex);
     onTorchStatusChangedLocked(cameraId, newStatus);
 }
 
-void CameraService::onTorchStatusChangedLocked(const String16& cameraId,
+void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
         ICameraServiceListener::TorchStatus newStatus) {
     ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
             __FUNCTION__, cameraId.string(), newStatus);
 
-    if (getTorchStatusLocked(cameraId) == newStatus) {
+    ICameraServiceListener::TorchStatus status;
+    status_t res = getTorchStatusLocked(cameraId, &status);
+    if (res) {
+        ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
+        return;
+    }
+    if (status == newStatus) {
         ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
               __FUNCTION__, (uint32_t)newStatus);
         return;
     }
 
-    status_t res = setTorchStatusLocked(cameraId, newStatus);
+    res = setTorchStatusLocked(cameraId, newStatus);
     if (res) {
         ALOGE("%s: Failed to set the torch status", __FUNCTION__,
                 (uint32_t)newStatus);
@@ -294,7 +306,7 @@
 
     Vector<sp<ICameraServiceListener> >::const_iterator it;
     for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
-        (*it)->onTorchStatusChanged(newStatus, cameraId);
+        (*it)->onTorchStatusChanged(newStatus, String16(cameraId.string()));
     }
 }
 
@@ -484,19 +496,6 @@
     return deviceVersion;
 }
 
-status_t CameraService::filterOpenErrorCode(status_t err) {
-    switch(err) {
-        case NO_ERROR:
-        case -EBUSY:
-        case -EINVAL:
-        case -EUSERS:
-            return err;
-        default:
-            break;
-    }
-    return -ENODEV;
-}
-
 status_t CameraService::filterGetInfoErrorCode(status_t err) {
     switch(err) {
         case NO_ERROR:
@@ -754,7 +753,7 @@
         bool legacyMode) {
 
     // give flashlight a chance to close devices if necessary.
-    mFlashlight->prepareDeviceOpen();
+    mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
 
     int facing = -1;
     int deviceVersion = getDeviceVersion(cameraId, &facing);
@@ -932,44 +931,94 @@
     return OK;
 }
 
+bool CameraService::validCameraIdForSetTorchMode(const String8& cameraId) {
+    // invalid string for int
+    if (cameraId.string() == NULL) {
+        return false;
+    }
+    errno = 0;
+    char *endptr;
+    long id = strtol(cameraId.string(), &endptr, 10); // base 10
+    if (errno || id > INT_MAX || id < INT_MIN || *endptr != 0) {
+        return false;
+    }
+
+    // id matches one of the plugged-in devices?
+    ICameraServiceListener::Status deviceStatus = getStatus(id);
+    if (deviceStatus != ICameraServiceListener::STATUS_PRESENT &&
+            deviceStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+        return false;
+    }
+
+    return true;
+}
+
 status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
         const sp<IBinder>& clientBinder) {
     if (enabled && clientBinder == NULL) {
         ALOGE("%s: torch client binder is NULL", __FUNCTION__);
-        return -ENOSYS;
+        return -EINVAL;
     }
 
-    Mutex::Autolock al(mTorchStatusMutex);
-    status_t res = mFlashlight->setTorchMode(cameraId, enabled);
+    String8 id = String8(cameraId.string());
+
+    // verify id is valid.
+    if (validCameraIdForSetTorchMode(id) == false) {
+        ALOGE("%s: camera id is invalid %s", id.string());
+        return -EINVAL;
+    }
+
+    {
+        Mutex::Autolock al(mTorchStatusMutex);
+        ICameraServiceListener::TorchStatus status;
+        status_t res = getTorchStatusLocked(id, &status);
+        if (res) {
+            ALOGE("%s: getting current torch status failed for camera %s",
+                    __FUNCTION__, id.string());
+            return -EINVAL;
+        }
+
+        if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
+            if (getStatus(atoi(id.string())) ==
+                        ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+                ALOGE("%s: torch mode of camera %s is not available because "
+                        "camera is in use", __FUNCTION__, id.string());
+                return -EBUSY;
+            } else {
+                ALOGE("%s: torch mode of camera %s is not available due to "
+                        "insufficient resources", __FUNCTION__, id.string());
+                return -EUSERS;
+            }
+        }
+    }
+
+    status_t res = mFlashlight->setTorchMode(id, enabled);
     if (res) {
-        ALOGE("%s: setting torch mode of camera %s to %d failed", __FUNCTION__,
-                cameraId.string(), enabled);
+        ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
+                __FUNCTION__, id.string(), enabled, strerror(-res), res);
         return res;
     }
 
-    // update the link to client's death
-    ssize_t index = mTorchClientMap.indexOfKey(cameraId);
-    if (enabled) {
-        if (index == NAME_NOT_FOUND) {
-            mTorchClientMap.add(cameraId, clientBinder);
-        } else {
-            const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
+    {
+        // update the link to client's death
+        Mutex::Autolock al(mTorchClientMapMutex);
+        ssize_t index = mTorchClientMap.indexOfKey(id);
+        if (enabled) {
+            if (index == NAME_NOT_FOUND) {
+                mTorchClientMap.add(id, clientBinder);
+            } else {
+                const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
+                oldBinder->unlinkToDeath(this);
+
+                mTorchClientMap.replaceValueAt(index, clientBinder);
+            }
+            clientBinder->linkToDeath(this);
+        } else if (index != NAME_NOT_FOUND) {
+            sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
             oldBinder->unlinkToDeath(this);
-
-            mTorchClientMap.replaceValueAt(index, clientBinder);
         }
-        clientBinder->linkToDeath(this);
-    } else if (index != NAME_NOT_FOUND) {
-        sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
-        oldBinder->unlinkToDeath(this);
     }
 
-    // notify the listeners the change.
-    ICameraServiceListener::TorchStatus status = enabled ?
-            ICameraServiceListener::TORCH_STATUS_ON :
-            ICameraServiceListener::TORCH_STATUS_OFF;
-    onTorchStatusChangedLocked(cameraId, status);
-
     return OK;
 }
 
@@ -1099,7 +1148,7 @@
         int deviceVersion = getDeviceVersion(cameraId, &facing);
 
         // give flashlight a chance to close devices if necessary.
-        mFlashlight->prepareDeviceOpen();
+        mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
 
         switch(deviceVersion) {
           case CAMERA_DEVICE_API_VERSION_1_0:
@@ -1176,8 +1225,8 @@
     {
         Mutex::Autolock al(mTorchStatusMutex);
         for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
-            listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i),
-                    mTorchStatusMap.keyAt(i));
+            String16 id = String16(mTorchStatusMap.keyAt(i).string());
+            listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
         }
 
     }
@@ -1616,6 +1665,9 @@
                 mCameraId,
                 &rejectSourceStates);
 
+        // Notify flashlight that a camera device is closed.
+        mCameraService->mFlashlight->deviceClosed(
+                String8::format("%d", mCameraId));
     }
     // Always stop watching, even if no camera op is active
     if (mOpsCallback != NULL) {
@@ -1862,17 +1914,18 @@
 }
 
 void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
-    Mutex::Autolock al(mTorchStatusMutex);
+    Mutex::Autolock al(mTorchClientMapMutex);
     for (size_t i = 0; i < mTorchClientMap.size(); i++) {
         if (mTorchClientMap[i] == who) {
             // turn off the torch mode that was turned on by dead client
-            String16 cameraId = mTorchClientMap.keyAt(i);
-            mFlashlight->setTorchMode(cameraId, false);
+            String8 cameraId = mTorchClientMap.keyAt(i);
+            status_t res = mFlashlight->setTorchMode(cameraId, false);
+            if (res) {
+                ALOGE("%s: torch client died but couldn't turn off torch: "
+                    "%s (%d)", __FUNCTION__, strerror(-res), res);
+                return;
+            }
             mTorchClientMap.removeItemsAt(i);
-
-            // notify torch mode was turned off
-            onTorchStatusChangedLocked(cameraId,
-                    ICameraServiceListener::TORCH_STATUS_OFF);
             break;
         }
     }
@@ -1968,6 +2021,19 @@
             }
         }
 
+        if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
+            status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+            // update torch status to not available when the camera device
+            // becomes not present or not available.
+            onTorchStatusChanged(String8::format("%d", cameraId),
+                    ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
+        } else if (status == ICameraServiceListener::STATUS_PRESENT) {
+            // update torch status to available when the camera device becomes
+            // present or available
+            onTorchStatusChanged(String8::format("%d", cameraId),
+                    ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
+        }
+
         Vector<sp<ICameraServiceListener> >::const_iterator it;
         for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
             (*it)->onStatusChanged(status, cameraId);
@@ -1985,17 +2051,23 @@
     return mStatusList[cameraId];
 }
 
-ICameraServiceListener::TorchStatus CameraService::getTorchStatusLocked(
-        const String16& cameraId) const {
+status_t CameraService::getTorchStatusLocked(
+        const String8& cameraId,
+        ICameraServiceListener::TorchStatus *status) const {
+    if (!status) {
+        return BAD_VALUE;
+    }
     ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
     if (index == NAME_NOT_FOUND) {
-        return ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
+        // invalid camera ID or the camera doesn't have a flash unit
+        return NAME_NOT_FOUND;
     }
 
-    return mTorchStatusMap.valueAt(index);
+    *status = mTorchStatusMap.valueAt(index);
+    return OK;
 }
 
-status_t CameraService::setTorchStatusLocked(const String16& cameraId,
+status_t CameraService::setTorchStatusLocked(const String8& cameraId,
         ICameraServiceListener::TorchStatus status) {
     ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
     if (index == NAME_NOT_FOUND) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 84bcdb8..22afc8c 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -72,7 +72,7 @@
     // HAL Callbacks
     virtual void        onDeviceStatusChanged(int cameraId,
                                               int newStatus);
-    virtual void        onTorchStatusChanged(const String16& cameraId,
+    virtual void        onTorchStatusChanged(const String8& cameraId,
                                              ICameraServiceListener::TorchStatus
                                                    newStatus);
 
@@ -150,7 +150,6 @@
 
     /////////////////////////////////////////////////////////////////////
     // Shared utilities
-    static status_t     filterOpenErrorCode(status_t err);
     static status_t     filterGetInfoErrorCode(status_t err);
 
     /////////////////////////////////////////////////////////////////////
@@ -418,28 +417,33 @@
 
     // flashlight control
     sp<CameraFlashlight> mFlashlight;
-    // guard mTorchStatusMap and mTorchClientMap
+    // guard mTorchStatusMap
     Mutex                mTorchStatusMutex;
+    // guard mTorchClientMap
+    Mutex                mTorchClientMapMutex;
     // camera id -> torch status
-    KeyedVector<String16, ICameraServiceListener::TorchStatus> mTorchStatusMap;
+    KeyedVector<String8, ICameraServiceListener::TorchStatus> mTorchStatusMap;
     // camera id -> torch client binder
     // only store the last client that turns on each camera's torch mode
-    KeyedVector<String16, sp<IBinder> > mTorchClientMap;
+    KeyedVector<String8, sp<IBinder> > mTorchClientMap;
 
     // check and handle if torch client's process has died
     void handleTorchClientBinderDied(const wp<IBinder> &who);
 
     // handle torch mode status change and invoke callbacks. mTorchStatusMutex
     // should be locked.
-    void onTorchStatusChangedLocked(const String16& cameraId,
+    void onTorchStatusChangedLocked(const String8& cameraId,
             ICameraServiceListener::TorchStatus newStatus);
 
+    // validate the camera id for use of setting a torch mode.
+    bool validCameraIdForSetTorchMode(const String8& cameraId);
+
     // get a camera's torch status. mTorchStatusMutex should be locked.
-    ICameraServiceListener::TorchStatus getTorchStatusLocked(
-            const String16 &cameraId) const;
+    status_t getTorchStatusLocked(const String8 &cameraId,
+            ICameraServiceListener::TorchStatus *status) const;
 
     // set a camera's torch status. mTorchStatusMutex should be locked.
-    status_t setTorchStatusLocked(const String16 &cameraId,
+    status_t setTorchStatusLocked(const String8 &cameraId,
             ICameraServiceListener::TorchStatus status);
 
     // IBinder::DeathRecipient implementation
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index 85a4df9..5f767ad 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -91,7 +91,7 @@
 }
 
 int CameraModule::open(const char* id, struct hw_device_t** device) {
-    return mModule->common.methods->open(&mModule->common, id, device);
+    return filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
 }
 
 int CameraModule::openLegacy(
@@ -125,5 +125,20 @@
     return mModule->set_torch_mode(camera_id, enable);
 }
 
+
+status_t CameraModule::filterOpenErrorCode(status_t err) {
+    switch(err) {
+        case NO_ERROR:
+        case -EBUSY:
+        case -EINVAL:
+        case -EUSERS:
+            return err;
+        default:
+            break;
+    }
+    return -ENODEV;
+}
+
+
 }; // namespace android
 
diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h
index 31b9ae2..16207aa 100644
--- a/services/camera/libcameraservice/common/CameraModule.h
+++ b/services/camera/libcameraservice/common/CameraModule.h
@@ -50,6 +50,8 @@
 private:
     // Derive camera characteristics keys defined after HAL device version
     static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
+    status_t filterOpenErrorCode(status_t err);
+
     camera_module_t *mModule;
     CameraMetadata mCameraCharacteristics[MAX_CAMERAS_PER_MODULE];
     camera_info mCameraInfo[MAX_CAMERAS_PER_MODULE];
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 9e1cdc9..f5ebbf8 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -104,8 +104,7 @@
                                      CAMERA_DEVICE_API_VERSION_1_0,
                                      (hw_device_t **)&mDevice);
         } else {
-            rc = CameraService::filterOpenErrorCode(module->open(
-                    mName.string(), (hw_device_t **)&mDevice));
+            rc = module->open(mName.string(), (hw_device_t **)&mDevice);
         }
         if (rc != OK) {
             ALOGE("Could not open camera %s: %d", mName.string(), rc);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index be66c4d..43c8307 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -68,8 +68,7 @@
 
     camera2_device_t *device;
 
-    res = CameraService::filterOpenErrorCode(module->open(
-            name, reinterpret_cast<hw_device_t**>(&device)));
+    res = module->open(name, reinterpret_cast<hw_device_t**>(&device));
 
     if (res != OK) {
         ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 9a4e5ac..bca9bfd 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -106,8 +106,8 @@
     camera3_device_t *device;
 
     ATRACE_BEGIN("camera3->open");
-    res = CameraService::filterOpenErrorCode(module->open(
-            deviceName.string(), reinterpret_cast<hw_device_t**>(&device)));
+    res = module->open(deviceName.string(),
+            reinterpret_cast<hw_device_t**>(&device));
     ATRACE_END();
 
     if (res != OK) {
diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp
index 4d0981b..fe4d212 100644
--- a/tools/resampler_tools/fir.cpp
+++ b/tools/resampler_tools/fir.cpp
@@ -99,7 +99,7 @@
     double Fc = 20478;
     double atten = 1;
     int format = 0;     // 0=fixed, 1=float
-    bool declarations = 0;
+    bool declarations = false;
 
     // in order to keep the errors associated with the linear
     // interpolation of the coefficients below the quantization error
@@ -230,9 +230,9 @@
     for (int i = M-1 ; i; i>>=1, nz++);
     // generate the right half of the filter
     if (!debug) {
-        printf("// cmd-line: ");
+        printf("// cmd-line:");
         for (int i=0 ; i<argc ; i++) {
-            printf("%s ", argv[i]);
+            printf(" %s", argv[i]);
         }
         printf("\n");
         if (declarations) {